判断点是否在多边形内(C#版本)
/// <summary>/// 判断点是否在闭合多线段内
/// </summary>
/// <param name="pt">待判断点</param>
/// <param name="poly">目标多边形</param>
/// <returns>在多边形内则返回1</returns>
private double min(double x,double y)
{
if (x > y)
return y;
else
return x;
}
private double max(double x, double y)
{
if (x > y)
return x;
else
return y;
}
public int PtinPolygon(Point3d pt,Point3d[] ptPolygon)
{
int nCount = ptPolygon.Length;
// 记录是否在多边形的边上
bool isBeside = false;
// 多边形外接矩形
double maxx,maxy,minx,miny;
if (nCount > 0)
{
maxx = ptPolygon.X;
minx = ptPolygon.X;
maxy = ptPolygon.Y;
miny = ptPolygon.Y;
for (int j = 1; j < nCount;j++)
{
if (ptPolygon.X >= maxx)
maxx = ptPolygon.X;
else if (ptPolygon.X <= minx)
minx = ptPolygon.X;
if (ptPolygon.Y >= maxy)
maxy = ptPolygon.Y;
else if (ptPolygon.Y <= miny)
miny = ptPolygon.Y;
}
if ((pt.X > maxx) || (pt.X < minx) || (pt.Y > maxy) || (pt.Y < miny))
return -1;
}
// 射线法判断
int nCross = 0;
for (int i = 0; i < nCount;i++)
{
Point3d p1 = ptPolygon;
Point3d p2 = ptPolygon[(i + 1) % nCount];
if (p1.Y==p2.Y)
{
if (pt.Y == p1.Y && pt.X >= min(p1.X,p2.X) && pt.X <= max(p1.X,p2.X))
{
isBeside = true;
continue;
}
}
// 交点在p1p2延长线上
if (pt.Y < min(p1.Y, p2.Y) || pt.Y > max(p1.Y, p2.Y))
continue;
// 求交点的X坐标
double x = (double)(pt.Y - p1.Y) * (double)(p2.X - p1.X) / (double)(p2.Y - p1.Y) + p1.X;
if (x > pt.X)
nCross++;// 只统计单边交点
else if (x == pt.X)
isBeside = true;
}
if (isBeside)
return 0;//多边形上
else if (nCross % 2 == 1)
return 1;// 多边形内
return -1; // 多边形外
}
http://bbs.mjtd.com/xwb/images/bgimg/icon_logo.png 该贴已经同步到 菜鸟Liu的微博 ,你直接用系统api吧。 zz0147 发表于 2012-3-25 20:48 static/image/common/back.gif
,你直接用系统api吧。
能具体说一下吗? 用lz的方法 在有些时候判别出现了问题
你看下这样代码应该好点public int ptInPolygon1(Point3d pt, Polyline pPolyline)
{
int count = pPolyline.NumberOfVertices;
//构建多边形外接矩形
double maxx = double.MinValue, maxy = double.MinValue, minx = double.MaxValue, miny = double.MaxValue;
for (int i = 0; i < count; i++)
{
if (pPolyline.GetPoint3dAt(i).X > maxx)
{
maxx = pPolyline.GetPoint3dAt(i).X;
}
if (pPolyline.GetPoint3dAt(i).Y > maxy)
{
maxy = pPolyline.GetPoint3dAt(i).Y;
}
if (pPolyline.GetPoint3dAt(i).X < minx)
{
minx = pPolyline.GetPoint3dAt(i).X;
}
if (pPolyline.GetPoint3dAt(i).Y < miny)
{
miny = pPolyline.GetPoint3dAt(i).Y;
}
}
if (pt.X > maxx || pt.Y > maxy || pt.X < minx || pt.Y < miny)
{
return -1;
}
Line line1 = new Line(new Point3d(maxx, pt.Y, 0), new Point3d(minx, pt.Y, 0));
int crossCount = 0;
using (Transaction tran = pDatabase.TransactionManager.StartTransaction())
{
BlockTableRecord pBlockTableRecord = tran.GetObject(pDatabase.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
Point3dCollection crossPoint = new Point3dCollection();
line1.IntersectWith(pPolyline, Intersect.OnBothOperands, crossPoint, 0, 0);
if (crossPoint.Count >= 1)
{
for (int n = 0; n < crossPoint.Count; n++)
{
Point3d crossPt = crossPoint;
if (crossPt.X > pt.X)
{
crossCount++;
Circle pCircle = new Circle(crossPt, Vector3d.ZAxis, 2);
pBlockTableRecord.AppendEntity(pCircle);
tran.AddNewlyCreatedDBObject(pCircle, true);
}
}
}
Circle circle = new Circle(pt, Vector3d.ZAxis, 2);
pBlockTableRecord.AppendEntity(circle);
tran.AddNewlyCreatedDBObject(circle, true);
pBlockTableRecord.AppendEntity(line1);
tran.AddNewlyCreatedDBObject(line1, true);
tran.Commit();
}
return crossCount % 2;
} 东西不错,顶了,感谢分享
页:
[1]