C# 求圆和线的交点
我试图找到一条线是否与圆相交 我写的代码,但似乎与该代码的一些问题C# 求圆和线的交点,c#,C#,我试图找到一条线是否与圆相交 我写的代码,但似乎与该代码的一些问题 private Point2d[] IntersectionPoint(Point2d p1, Point2d p2, Point2d sc, double r) { Point2d[] sect = null; double a, b, c; double bb4ac; double mu1, mu2; Point2d dp;
private Point2d[] IntersectionPoint(Point2d p1, Point2d p2, Point2d sc, double r)
{
Point2d[] sect = null;
double a, b, c;
double bb4ac;
double mu1, mu2;
Point2d dp;
dp = p2 - p1;
a = dp.X * dp.X + dp.Y * dp.Y;
b = 2 * (dp.X * (p1.X - sc.X) + dp.Y * (p1.Y - sc.Y));
c = sc.X * sc.X + sc.Y * sc.Y;
c += p1.X * p1.X + p1.Y * p1.Y;
c -= 2 * (sc.X * p1.X + sc.Y * p1.Y);
c -= r * r;
bb4ac = b * b - 4 * a * c;
if (Math.Abs(a) < Double.Epsilon || bb4ac < 0)
{
return new Point2d[0];
}
mu1 = (-b + Math.Sqrt(bb4ac)) / (2 * a);
mu2 = (-b - Math.Sqrt(bb4ac)) / (2 * a);
// no intersection
if ((mu1 < 0 || mu1 > 1) && (mu2 < 0 || mu2 > 1))
{
sect = new Point2d[0];
}
// one point on mu1
else if (mu1 > 0 && mu1 < 1 && (mu2 < 0 || mu2 > 1))
{
sect = new Point2d[1];
sect[0] = p1 + ((p2 - p1) * mu1);
}
// one point on mu2
else if (mu2 > 0 && mu2 < 1 && (mu1 < 0 || mu1 > 1))
{
sect = new Point2d[1];
sect[0] = p1 + ((p2 - p1) * mu2);
}
// one or two points
else if (mu1 > 0 && mu1 < 1 && mu2 > 0 && mu2 < 1)
{
// tangential
if (mu1 == mu2)
{
sect = new Point2d[1];
sect[0] = p1 + ((p2 - p1) * mu1);
}
// two points
else
{
sect = new Point2d[2];
sect[0] = p1 + ((p2 - p1) * mu1);
sect[1] = p1 + ((p2 - p1) * mu2);
}
}
else
{
// should NEVER get here
sect = new Point2d[0];
}
return sect;
}
当我尝试使用这些坐标时,它失败了
30,-30
80,-40
十,
编辑:向量现在是C# 下面是我的相交代码:
public static Vector3? IntersectRayCircle(Vector3 rayStart, Vector3 rayPoint, Vector3 circlePosition, float circleRadiusSquared)
{
if (rayStart == rayPoint || circleRadiusSquared <= 0)
{
return null;
}
Vector3 nearest = GetNearestPoint(circlePosition, rayStart, rayPoint, false, false);
float distanceSquared = Vector3.DistanceSquared(nearest, circlePosition);
if (distanceSquared > circleRadiusSquared)
{
return null;
}
Vector3 offset = Vector3.Normalize(rayPoint - rayStart) * (float)Math.Sqrt(circleRadiusSquared - distanceSquared);
if (Vector3.DistanceSquared(circlePosition, rayStart) < circleRadiusSquared)
{
return nearest + offset;
}
else
{
return nearest - offset;
}
}
公共静态向量3?相交光线圆(矢量3光线起点、矢量3光线点、矢量3圆圈位置、浮动圆圈半径平方)
{
if(光线起点==光线点| |圆度平方圆度平方圆度平方)
{
返回null;
}
Vector3偏移=Vector3.规格化(光线点-光线开始)*(浮点)数学.Sqrt(circleRadiusSquared-距离平方);
if(矢量3.距离平方(圆位置,光线开始)
public static Vector3 GetNearestPoint(Vector3位置、Vector3段开始、Vector3段结束、bool trimStart、bool trimsend)
{
如果(分段开始==分段结束)
{
抛出新ArgumentException(“segmentStart不能等于segmentEnd”);
}
Vector3 AP=位置-分段开始;
Vector3 AB=分段结束-分段开始;
浮点数AB=AB.长度平方();
float ABAPproduct=Vector3.Dot(AP,AB);
浮动距离=ABAPproduct/magnificatab;
返回(距离<0&&trimStart)?分段开始:(距离>1&&trimEnd)?分段结束:分段开始+AB*距离;
}
你可以做一些线性代数:
P1
和标准化方向向量N
PC=P1+dot(C-P1,N)*N
C
和PC
之间的距离平方dSquared
PC
位于圆上,是单个交点offset=sqrt(radiusquared-dSquared)
PC+/-偏移*N
//在查看代码之后,看起来您的代码实际上就是从这里开始的我的一些代码也是基于那里编写的,我遇到了一个问题,
bb4ac
有时非常接近于零(但仍然不应该是;与球体的切线),以至于无法通过相交测试。//我认为您需要将bb4ac
与epsilonI进行比较,因为我无法构建此代码@另一位用户我也不相信那些编写包含数学公式的代码的人,除了“似乎有些问题”和“它失败了”之外,不能提供任何关于出错原因的信息。要么代码与您的设计不匹配(您可以进行调试),要么您的设计有缺陷,我们现在还不应该查看代码。您实际上是在检查半径是否小于直线中间的距离。是的,我正在按照图表进行检查@TAWVACTOR在C#中不可用@AgentFire@PrinceChopra-拜托,你不能自己做向量类?这就像是最基本的任务:)如果你看不到
public static Vector3? IntersectRayCircle(Vector3 rayStart, Vector3 rayPoint, Vector3 circlePosition, float circleRadiusSquared)
{
if (rayStart == rayPoint || circleRadiusSquared <= 0)
{
return null;
}
Vector3 nearest = GetNearestPoint(circlePosition, rayStart, rayPoint, false, false);
float distanceSquared = Vector3.DistanceSquared(nearest, circlePosition);
if (distanceSquared > circleRadiusSquared)
{
return null;
}
Vector3 offset = Vector3.Normalize(rayPoint - rayStart) * (float)Math.Sqrt(circleRadiusSquared - distanceSquared);
if (Vector3.DistanceSquared(circlePosition, rayStart) < circleRadiusSquared)
{
return nearest + offset;
}
else
{
return nearest - offset;
}
}
public static Vector3 GetNearestPoint(Vector3 location, Vector3 segmentStart, Vector3 segmentEnd, bool trimStart, bool trimEnd)
{
if (segmentStart == segmentEnd)
{
throw new ArgumentException("segmentStart cannot be equal to segmentEnd.");
}
Vector3 AP = location - segmentStart;
Vector3 AB = segmentEnd - segmentStart;
float magnitudeAB = AB.LengthSquared();
float ABAPproduct = Vector3.Dot(AP, AB);
float distance = ABAPproduct / magnitudeAB;
return (distance < 0 && trimStart) ? segmentStart : (distance > 1 && trimEnd) ? segmentEnd : segmentStart + AB * distance;
}