如何判断直线是否与C#中的多边形相交?
我有一个非常类似的问题: 我正在寻找一种方法(用C#)来判断直线是否与任意多边形相交 我认为该方法非常有用,但缺少了最重要的方法,即线与线的相交 是否有人知道一种线交点方法来完成Chris Marasti Georg的代码,或者有类似的方法 C#中是否有用于此的内置代码如何判断直线是否与C#中的多边形相交?,c#,geometry,2d,bing-maps,computational-geometry,C#,Geometry,2d,Bing Maps,Computational Geometry,我有一个非常类似的问题: 我正在寻找一种方法(用C#)来判断直线是否与任意多边形相交 我认为该方法非常有用,但缺少了最重要的方法,即线与线的相交 是否有人知道一种线交点方法来完成Chris Marasti Georg的代码,或者有类似的方法 C#中是否有用于此的内置代码 此方法与Bing Maps算法配合使用,该算法通过禁区功能增强。生成的路径不能通过禁止区域(任意多边形)。本文看起来会有所帮助 这段代码是一个二维多边形裁剪算法,它精确地确定直线与多边形边界相交的位置。此代码适用于完全任意形
此方法与Bing Maps算法配合使用,该算法通过禁区功能增强。生成的路径不能通过禁止区域(任意多边形)。本文看起来会有所帮助
这段代码是一个二维多边形裁剪算法,它精确地确定直线与多边形边界相交的位置。此代码适用于完全任意形状的凹多边形和凸多边形,并且能够处理任何直线方向。在.NET framework中没有内置的边缘检测代码 以下代码(移植到C#)满足您的需要(实际算法可在Google Group上的comp.graphics.algorithms中找到):
公共静态点F FindLineIntersection(点F start1、点F end1、点F start2、点F end2)
{
float-denom=((end1.X-start1.X)*(end2.Y-start2.Y))-((end1.Y-start1.Y)*(end2.X-start2.X));
//AB和CD是平行的
如果(denom==0)
返回点f.Empty;
浮点数=((start1.Y-start2.Y)*(end2.X-start2.X))-((start1.X-start2.X)*(end2.Y-start2.Y));
浮点数r=数值/小数;
浮点数2=((start1.Y-start2.Y)*(end1.X-start1.X))-((start1.X-start2.X)*(end1.Y-start1.Y));
浮点数s=numer2/denom;
if((r<0 | | r>1)| |(s<0 | | s>1))
返回点f.Empty;
//求交点
PointF结果=新的PointF();
result.X=start1.X+(r*(end1.X-start1.X));
result.Y=start1.Y+(r*(end1.Y-start1.Y));
返回结果;
}
要在silverlight地图项目中检测多边形之间的碰撞,我们使用clipper库:
免费商用,体积小,性能好,使用方便
有点离题,但如果行是无限的,我认为有一个更简单的解决方案: 如果所有点位于直线的同一侧,则直线不会穿过多边形 在这两方面的帮助下:
public class PointsAndLines
{
public static bool IsOutside(Point lineP1, Point lineP2, IEnumerable<Point> region)
{
if (region == null || !region.Any()) return true;
var side = GetSide(lineP1, lineP2, region.First());
return
side == 0
? false
: region.All(x => GetSide(lineP1, lineP2, x) == side);
}
public static int GetSide(Point lineP1, Point lineP2, Point queryP)
{
return Math.Sign((lineP2.X - lineP1.X) * (queryP.Y - lineP1.Y) - (lineP2.Y - lineP1.Y) * (queryP.X - lineP1.X));
}
}
公共类点和线
{
公共静态边界等外(点线P1、点线P2、IEnumerable region)
{
if(region==null | |!region.Any())返回true;
var-side=GetSide(lineP1,lineP2,region.First());
返回
边==0
?错误
:region.All(x=>GetSide(lineP1,lineP2,x==side);
}
公共静态int GetSide(点线P1、点线P2、点查询)
{
返回数学符号((lineP2.X-lineP1.X)*(queryP.Y-lineP1.Y)-(lineP2.Y-lineP1.Y)*(queryP.X-lineP1.X));
}
}
public class PointsAndLines
{
public static bool IsOutside(Point lineP1, Point lineP2, IEnumerable<Point> region)
{
if (region == null || !region.Any()) return true;
var side = GetSide(lineP1, lineP2, region.First());
return
side == 0
? false
: region.All(x => GetSide(lineP1, lineP2, x) == side);
}
public static int GetSide(Point lineP1, Point lineP2, Point queryP)
{
return Math.Sign((lineP2.X - lineP1.X) * (queryP.Y - lineP1.Y) - (lineP2.Y - lineP1.Y) * (queryP.X - lineP1.X));
}
}