明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 8741|回复: 4

判断点是否在多边形内(C#版本)

[复制链接]
发表于 2012-3-13 21:36 | 显示全部楼层 |阅读模式
   /// <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[0].X;
                minx = ptPolygon[0].X;
                maxy = ptPolygon[0].Y;
                miny = ptPolygon[0].Y;
                for (int j = 1; j < nCount;j++)
                {
                    if (ptPolygon[j].X >= maxx)
                        maxx = ptPolygon[j].X;
                    else if (ptPolygon[j].X <= minx)
                        minx = ptPolygon[j].X;
                    if (ptPolygon[j].Y >= maxy)
                        maxy = ptPolygon[j].Y;
                    else if (ptPolygon[j].Y <= miny)
                        miny = ptPolygon[j].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;     // 多边形外
        }


该贴已经同步到 菜鸟Liu的微博

点评

牛人  发表于 2012-3-14 20:13
发表于 2012-3-25 20:48 | 显示全部楼层
,你直接用系统api吧。
发表于 2012-6-7 00:08 | 显示全部楼层
zz0147 发表于 2012-3-25 20:48
,你直接用系统api吧。

能具体说一下吗?
发表于 2012-7-25 10:31 | 显示全部楼层
用lz的方法 在有些时候判别出现了问题
你看下这样代码应该好点
  1. public int ptInPolygon1(Point3d pt, Polyline pPolyline)
  2.         {
  3.             int count = pPolyline.NumberOfVertices;
  4.             //构建多边形外接矩形
  5.             double maxx = double.MinValue, maxy = double.MinValue, minx = double.MaxValue, miny = double.MaxValue;
  6.             for (int i = 0; i < count; i++)
  7.             {
  8.                 if (pPolyline.GetPoint3dAt(i).X > maxx)
  9.                 {
  10.                     maxx = pPolyline.GetPoint3dAt(i).X;
  11.                 }
  12.                 if (pPolyline.GetPoint3dAt(i).Y > maxy)
  13.                 {
  14.                     maxy = pPolyline.GetPoint3dAt(i).Y;
  15.                 }
  16.                 if (pPolyline.GetPoint3dAt(i).X < minx)
  17.                 {
  18.                     minx = pPolyline.GetPoint3dAt(i).X;
  19.                 }
  20.                 if (pPolyline.GetPoint3dAt(i).Y < miny)
  21.                 {
  22.                     miny = pPolyline.GetPoint3dAt(i).Y;
  23.                 }
  24.             }
  25.             if (pt.X > maxx || pt.Y > maxy || pt.X < minx || pt.Y < miny)
  26.             {
  27.                 return -1;
  28.             }

  29.             Line line1 = new Line(new Point3d(maxx, pt.Y, 0), new Point3d(minx, pt.Y, 0));

  30.             int crossCount = 0;

  31.             using (Transaction tran = pDatabase.TransactionManager.StartTransaction())
  32.             {
  33.                 BlockTableRecord pBlockTableRecord = tran.GetObject(pDatabase.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

  34.                 Point3dCollection crossPoint = new Point3dCollection();

  35.                 line1.IntersectWith(pPolyline, Intersect.OnBothOperands, crossPoint, 0, 0);
  36.                 if (crossPoint.Count >= 1)
  37.                 {
  38.                     for (int n = 0; n < crossPoint.Count; n++)
  39.                     {
  40.                         Point3d crossPt = crossPoint[n];
  41.                         if (crossPt.X > pt.X)
  42.                         {
  43.                             crossCount++;

  44.                             Circle pCircle = new Circle(crossPt, Vector3d.ZAxis, 2);

  45.                             pBlockTableRecord.AppendEntity(pCircle);
  46.                             tran.AddNewlyCreatedDBObject(pCircle, true);
  47.                         }
  48.                     }

  49.                 }
  50.                 Circle circle = new Circle(pt, Vector3d.ZAxis, 2);
  51.                 pBlockTableRecord.AppendEntity(circle);
  52.                 tran.AddNewlyCreatedDBObject(circle, true);

  53.                 pBlockTableRecord.AppendEntity(line1);
  54.                 tran.AddNewlyCreatedDBObject(line1, true);
  55.                 tran.Commit();
  56.             }
  57.             return crossCount % 2;

  58.         }
发表于 2014-5-26 10:20 | 显示全部楼层
东西不错,顶了,感谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-25 09:07 , Processed in 1.687875 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表