菜鸟Liu 发表于 2012-3-13 21:36:49

判断点是否在多边形内(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的微博

zz0147 发表于 2012-3-25 20:48:18

,你直接用系统api吧。

gyl 发表于 2012-6-7 00:08:30

zz0147 发表于 2012-3-25 20:48 static/image/common/back.gif
,你直接用系统api吧。

能具体说一下吗?

jiangfei200809 发表于 2012-7-25 10:31:31

用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;

      }

sdaulj 发表于 2014-5-26 10:20:46

东西不错,顶了,感谢分享
页: [1]
查看完整版本: 判断点是否在多边形内(C#版本)