如何知道一条线是不是与C#中的平面相交?
Posted
技术标签:
【中文标题】如何知道一条线是不是与C#中的平面相交?【英文标题】:How to know if a line intersects a plane in C#?如何知道一条线是否与C#中的平面相交? 【发布时间】:2010-09-07 00:03:36 【问题描述】:我有两个点(一条线段)和一个矩形。我想知道如何计算线段是否与矩形相交。
【问题讨论】:
【参考方案1】:来自我的“几何”课程:
public struct Line
public static Line Empty;
private PointF p1;
private PointF p2;
public Line(PointF p1, PointF p2)
this.p1 = p1;
this.p2 = p2;
public PointF P1
get return p1;
set p1 = value;
public PointF P2
get return p2;
set p2 = value;
public float X1
get return p1.X;
set p1.X = value;
public float X2
get return p2.X;
set p2.X = value;
public float Y1
get return p1.Y;
set p1.Y = value;
public float Y2
get return p2.Y;
set p2.Y = value;
public struct Polygon: IEnumerable<PointF>
private PointF[] points;
public Polygon(PointF[] points)
this.points = points;
public PointF[] Points
get return points;
set points = value;
public int Length
get return points.Length;
public PointF this[int index]
get return points[index];
set points[index] = value;
public static implicit operator PointF[](Polygon polygon)
return polygon.points;
public static implicit operator Polygon(PointF[] points)
return new Polygon(points);
IEnumerator<PointF> IEnumerable<PointF>.GetEnumerator()
return (IEnumerator<PointF>)points.GetEnumerator();
public IEnumerator GetEnumerator()
return points.GetEnumerator();
public enum Intersection
None,
Tangent,
Intersection,
Containment
public static class Geometry
public static Intersection IntersectionOf(Line line, Polygon polygon)
if (polygon.Length == 0)
return Intersection.None;
if (polygon.Length == 1)
return IntersectionOf(polygon[0], line);
bool tangent = false;
for (int index = 0; index < polygon.Length; index++)
int index2 = (index + 1)%polygon.Length;
Intersection intersection = IntersectionOf(line, new Line(polygon[index], polygon[index2]));
if (intersection == Intersection.Intersection)
return intersection;
if (intersection == Intersection.Tangent)
tangent = true;
return tangent ? Intersection.Tangent : IntersectionOf(line.P1, polygon);
public static Intersection IntersectionOf(PointF point, Polygon polygon)
switch (polygon.Length)
case 0:
return Intersection.None;
case 1:
if (polygon[0].X == point.X && polygon[0].Y == point.Y)
return Intersection.Tangent;
else
return Intersection.None;
case 2:
return IntersectionOf(point, new Line(polygon[0], polygon[1]));
int counter = 0;
int i;
PointF p1;
int n = polygon.Length;
p1 = polygon[0];
if (point == p1)
return Intersection.Tangent;
for (i = 1; i <= n; i++)
PointF p2 = polygon[i % n];
if (point == p2)
return Intersection.Tangent;
if (point.Y > Math.Min(p1.Y, p2.Y))
if (point.Y <= Math.Max(p1.Y, p2.Y))
if (point.X <= Math.Max(p1.X, p2.X))
if (p1.Y != p2.Y)
double xinters = (point.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X;
if (p1.X == p2.X || point.X <= xinters)
counter++;
p1 = p2;
return (counter % 2 == 1) ? Intersection.Containment : Intersection.None;
public static Intersection IntersectionOf(PointF point, Line line)
float bottomY = Math.Min(line.Y1, line.Y2);
float topY = Math.Max(line.Y1, line.Y2);
bool heightIsRight = point.Y >= bottomY &&
point.Y <= topY;
//Vertical line, slope is divideByZero error!
if (line.X1 == line.X2)
if (point.X == line.X1 && heightIsRight)
return Intersection.Tangent;
else
return Intersection.None;
float slope = (line.X2 - line.X1)/(line.Y2 - line.Y1);
bool onLine = (line.Y1 - point.Y) == (slope*(line.X1 - point.X));
if (onLine && heightIsRight)
return Intersection.Tangent;
else
return Intersection.None;
【讨论】:
是否所有四个交点方法,即 (Point, Line) 、 (Point, Polygon) 、(Line ,Line) 和 (Line, Polygon) 都必须检查一条线是否与任何给定的 n-polygon 相交?我想知道是否只有 (Line, Polygon) 就足够了? (Line, Polygon) 使用 (Line, Line)。你不需要指出方法。不过,它们对于其他目的很方便!【参考方案2】:对直线和矩形的每一边执行http://mathworld.wolfram.com/Line-LineIntersection.html。 或:http://mathworld.wolfram.com/Line-PlaneIntersection.html
【讨论】:
【参考方案3】:因为它丢失了,我只是为了完整性添加它
public static Intersection IntersectionOf(Line line1, Line line2)
// Fail if either line segment is zero-length.
if (line1.X1 == line1.X2 && line1.Y1 == line1.Y2 || line2.X1 == line2.X2 && line2.Y1 == line2.Y2)
return Intersection.None;
if (line1.X1 == line2.X1 && line1.Y1 == line2.Y1 || line1.X2 == line2.X1 && line1.Y2 == line2.Y1)
return Intersection.Intersection;
if (line1.X1 == line2.X2 && line1.Y1 == line2.Y2 || line1.X2 == line2.X2 && line1.Y2 == line2.Y2)
return Intersection.Intersection;
// (1) Translate the system so that point A is on the origin.
line1.X2 -= line1.X1; line1.Y2 -= line1.Y1;
line2.X1 -= line1.X1; line2.Y1 -= line1.Y1;
line2.X2 -= line1.X1; line2.Y2 -= line1.Y1;
// Discover the length of segment A-B.
double distAB = Math.Sqrt(line1.X2 * line1.X2 + line1.Y2 * line1.Y2);
// (2) Rotate the system so that point B is on the positive X axis.
double theCos = line1.X2 / distAB;
double theSin = line1.Y2 / distAB;
double newX = line2.X1 * theCos + line2.Y1 * theSin;
line2.Y1 = line2.Y1 * theCos - line2.X1 * theSin; line2.X1 = newX;
newX = line2.X2 * theCos + line2.Y2 * theSin;
line2.Y2 = line2.Y2 * theCos - line2.X2 * theSin; line2.X2 = newX;
// Fail if segment C-D doesn't cross line A-B.
if (line2.Y1 < 0 && line2.Y2 < 0 || line2.Y1 >= 0 && line2.Y2 >= 0)
return Intersection.None;
// (3) Discover the position of the intersection point along line A-B.
double posAB = line2.X2 + (line2.X1 - line2.X2) * line2.Y2 / (line2.Y2 - line2.Y1);
// Fail if segment C-D crosses line A-B outside of segment A-B.
if (posAB < 0 || posAB > distAB)
return Intersection.None;
// (4) Apply the discovered position to line A-B in the original coordinate system.
return Intersection.Intersection;
注意该方法会旋转线段以避免与方向相关的问题
【讨论】:
【参考方案4】:使用类:
System.Drawing.Rectangle
方法:
IntersectsWith();
【讨论】:
【参考方案5】:如果是二维的,那么所有的线都在唯一的平面上。
所以,这是基本的 3-D 几何。你应该可以用一个简单的公式来做到这一点。
查看此页面:
http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/。
第二种解决方案应该很容易实现,只要将矩形的坐标转换为平面方程即可。
此外,检查您的分母是否不为零(线不相交或包含在平面中)。
【讨论】:
【参考方案6】:我讨厌浏览 MSDN 文档(它们非常慢而且很奇怪 :-s),但我认为它们应该有类似于 this Java method... 的内容,如果没有,对他们不利! XD(顺便说一句,它适用于段,而不是线条)。
无论如何,你可以看看开源 Java SDK 是如何实现的,也许你会学到一些新的技巧(当我看别人的代码时,我总是很惊讶)
【讨论】:
投了反对票,因为它只是一个链接的答案,并且该链接不再有效【参考方案7】:是否可以使用简单的线段公式检查矩形每一边的线。
【讨论】:
以上是关于如何知道一条线是不是与C#中的平面相交?的主要内容,如果未能解决你的问题,请参考以下文章
cad三维制图中如何找到一条线与一个面的交点,如空间斜线与水平标高24M面的交点,如何找到该交点