找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1477|回复: 3

[分享] 点在多边形内部

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-7-10 11:00:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
http://www.cnblogs.com/dwdxdy/p/3230647.html


  1.         //  The function will return YES if the point x,y is inside the polygon, or
  2.         //  NO if it is not.  If the point is exactly on the edge of the polygon,
  3.         //  then the function may return YES or NO.
  4.         bool IsPointInPolygon(Point3dCollection pts, Point3d pt)
  5.         {
  6.             int i, j;
  7.             bool c = false;
  8.             for (i = 0, j = pts.Count - 1; i < pts.Count; j = i++)
  9.             {
  10.                 if ((((pts[i].Y <= pt.Y) && (pt.Y < pts[j].Y)) ||
  11.                     ((pts[j].Y <= pt.Y) && (pt.Y < pts[i].Y)))
  12.                     && (pt.X < (pts[j].X - pts[i].X) * (pt.Y - pts[i].Y) / (pts[j].Y - pts[i].Y) + pts[i].X))
  13.                 {
  14.                     c = !c;
  15.                 }
  16.             }
  17.             return c;
  18.         }
复制代码
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-7-10 20:39:11 来自手机 | 显示全部楼层
bool IsInsideCurve(Curve curve, Point3d testPt)
        {
            if (!curve.Closed)
            {
                // cannot be inside
                return false;
            }

            Point3d ptOnCurve = curve.GetClosestPointTo(testPt, false);

            if (testPt == ptOnCurve)
            {
                return true;
            }

            if (!curve.IsPlanar)
            {
                return false;
            }

            // check its planar
            Plane plane = curve.GetPlane();

            // make the test ray from the plane
            double epsilon = 2e-6; // ( trust me on this )

            Point3dCollection IntersectionPoints = new Point3dCollection();
            Vector3d normal = plane.Normal;
            Vector3d testVector = normal.GetPerpendicularVector();

            using (Ray ray = new Ray())
            {
                ray.BasePoint = testPt;

                int nGlancingHits = 0, numberOfInters = 0;
                bool bRetryWithOtherRayDirection;

                do
                {
                    bRetryWithOtherRayDirection = false;

                    IntersectionPoints.Clear();

                    ray.UnitDir = testVector;

                    // fire the ray at the curve
                    curve.IntersectWith(ray,
                        Intersect.OnBothOperands,
                        IntersectionPoints,
                        IntPtr.Zero,
                        IntPtr.Zero);

                    numberOfInters = IntersectionPoints.Count;

                    if (numberOfInters == 0)
                    {
                        return false;
                    }

                    nGlancingHits = 0;

                    for (int i = 0; i < IntersectionPoints.Count; ++i)
                    {
                        double hitParam;

                        try
                        {
                            //This try/catch block circumvents an issue with GetParameterAtPoint API
                            hitParam = curve.GetParameterAtPoint(IntersectionPoints[i]);
                        }
                        catch
                        {
                            bRetryWithOtherRayDirection = true;
                            testVector = testVector.RotateBy(5.0 * Math.PI / 180.0, normal);
                            break;
                        }

                        double inParam = hitParam - epsilon;
                        double outParam = hitParam + epsilon;

                        //Loop back inside the curve if param is falling outside of range
                        if (inParam < curve.StartParam)
                            inParam = curve.EndParam - epsilon + (curve.StartParam - inParam);

                        if (outParam > curve.EndParam)
                            outParam = curve.StartParam + epsilon + (curve.EndParam - outParam);

                        IncidenceType inIncidence = CurveIncidence(curve, inParam, testVector, normal);
                        IncidenceType outIncidence = CurveIncidence(curve, outParam, testVector, normal);

                        if (inIncidence == IncidenceType.kIncidenceToFront || outIncidence == IncidenceType.kIncidenceToFront)
                        {
                            bRetryWithOtherRayDirection = true;
                            testVector = testVector.RotateBy(5.0 * Math.PI / 180.0, normal);
                            break;
                        }

                        if ((inIncidence == IncidenceType.kIncidenceToRight && outIncidence == IncidenceType.kIncidenceToLeft) ||
                            (inIncidence == IncidenceType.kIncidenceToLeft && outIncidence == IncidenceType.kIncidenceToRight))
                        {
                            nGlancingHits++;
                        }
                    }
                }
                while (bRetryWithOtherRayDirection);

                return ((numberOfInters + nGlancingHits) % 2
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-7-10 20:41:13 来自手机 | 显示全部楼层
bool IsInsideCurve(Curve curve, Point3d testPt)
        {
            if (!curve.Closed)
            {
                // cannot be inside
                return false;
            }

            Point3d ptOnCurve = curve.GetClosestPointTo(testPt, false);

            if (testPt == ptOnCurve)
            {
                return true;
            }

            if (!curve.IsPlanar)
            {
                return false;
            }

            // check its planar
            Plane plane = curve.GetPlane();

            // make the test ray from the plane
            double epsilon = 2e-6; // ( trust me on this )

            Point3dCollection IntersectionPoints = new Point3dCollection();
            Vector3d normal = plane.Normal;
            Vector3d testVector = normal.GetPerpendicularVector();

            using (Ray ray = new Ray())
            {
                ray.BasePoint = testPt;

                int nGlancingHits = 0, numberOfInters = 0;
                bool bRetryWithOtherRayDirection;

                do
                {
                    bRetryWithOtherRayDirection = false;

                    IntersectionPoints.Clear();

                    ray.UnitDir = testVector;

                    // fire the ray at the curve
                    curve.IntersectWith(ray,
                        Intersect.OnBothOperands,
                        IntersectionPoints,
                        IntPtr.Zero,
                        IntPtr.Zero);

                    numberOfInters = IntersectionPoints.Count;

                    if (numberOfInters == 0)
                    {
                        return false;
                    }

                    nGlancingHits = 0;

                    for (int i = 0; i < IntersectionPoints.Count; ++i)
                    {
                        double hitParam;

                        try
                        {
                            //This try/catch block circumvents an issue with GetParameterAtPoint API
                            hitParam = curve.GetParameterAtPoint(IntersectionPoints[i]);
                        }
                        catch
                        {
                            bRetryWithOtherRayDirection = true;
                            testVector = testVector.RotateBy(5.0 * Math.PI / 180.0, normal);
                            break;
                        }

                        double inParam = hitParam - epsilon;
                        double outParam = hitParam + epsilon;

                        //Loop back inside the curve if param is falling outside of range
                        if (inParam < curve.StartParam)
                            inParam = curve.EndParam - epsilon + (curve.StartParam - inParam);

                        if (outParam > curve.EndParam)
                            outParam = curve.StartParam + epsilon + (curve.EndParam - outParam);

                        IncidenceType inIncidence = CurveIncidence(curve, inParam, testVector, normal);
                        IncidenceType outIncidence = CurveIncidence(curve, outParam, testVector, normal);

                        if (inIncidence == IncidenceType.kIncidenceToFront || outIncidence == IncidenceType.kIncidenceToFront)
                        {
                            bRetryWithOtherRayDirection = true;
                            testVector = testVector.RotateBy(5.0 * Math.PI / 180.0, normal);
                            break;
                        }

                        if ((inIncidence == IncidenceType.kIncidenceToRight && outIncidence == IncidenceType.kIncidenceToLeft) ||
                            (inIncidence == IncidenceType.kIncidenceToLeft && outIncidence == IncidenceType.kIncidenceToRight))
                        {
                            nGlancingHits++;
                        }
                    }
                }
                while (bRetryWithOtherRayDirection);

                return ((numberOfInters + nGlancingHits) % 2.  
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-7-10 20:43:08 | 显示全部楼层
bool IsInsideCurve(Curve curve, Point3d testPt)
        {
            if (!curve.Closed)
            {
                // cannot be inside
                return false;
            }

            Point3d ptOnCurve = curve.GetClosestPointTo(testPt, false);

            if (testPt == ptOnCurve)
            {
                return true;
            }

            if (!curve.IsPlanar)
            {
                return false;
            }

            // check its planar
            Plane plane = curve.GetPlane();

            // make the test ray from the plane
            double epsilon = 2e-6; // ( trust me on this )

            Point3dCollection IntersectionPoints = new Point3dCollection();
            Vector3d normal = plane.Normal;
            Vector3d testVector = normal.GetPerpendicularVector();

            using (Ray ray = new Ray())
            {
                ray.BasePoint = testPt;

                int nGlancingHits = 0, numberOfInters = 0;
                bool bRetryWithOtherRayDirection;

                do
                {
                    bRetryWithOtherRayDirection = false;

                    IntersectionPoints.Clear();

                    ray.UnitDir = testVector;

                    // fire the ray at the curve
                    curve.IntersectWith(ray,
                        Intersect.OnBothOperands,
                        IntersectionPoints,
                        IntPtr.Zero,
                        IntPtr.Zero);

                    numberOfInters = IntersectionPoints.Count;

                    if (numberOfInters == 0)
                    {
                        return false;
                    }

                    nGlancingHits = 0;

                    for (int i = 0; i < IntersectionPoints.Count; ++i)
                    {
                        double hitParam;

                        try
                        {
                            //This try/catch block circumvents an issue with GetParameterAtPoint API
                            hitParam = curve.GetParameterAtPoint(IntersectionPoints[i]);
                        }
                        catch
                        {
                            bRetryWithOtherRayDirection = true;
                            testVector = testVector.RotateBy(5.0 * Math.PI / 180.0, normal);
                            break;
                        }

                        double inParam = hitParam - epsilon;
                        double outParam = hitParam + epsilon;

                        //Loop back inside the curve if param is falling outside of range
                        if (inParam < curve.StartParam)
                            inParam = curve.EndParam - epsilon + (curve.StartParam - inParam);

                        if (outParam > curve.EndParam)
                            outParam = curve.StartParam + epsilon + (curve.EndParam - outParam);

                        IncidenceType inIncidence = CurveIncidence(curve, inParam, testVector, normal);
                        IncidenceType outIncidence = CurveIncidence(curve, outParam, testVector, normal);

                        if (inIncidence == IncidenceType.kIncidenceToFront || outIncidence == IncidenceType.kIncidenceToFront)
                        {
                            bRetryWithOtherRayDirection = true;
                            testVector = testVector.RotateBy(5.0 * Math.PI / 180.0, normal);
                            break;
                        }

                        if ((inIncidence == IncidenceType.kIncidenceToRight && outIncidence == IncidenceType.kIncidenceToLeft) ||
                            (inIncidence == IncidenceType.kIncidenceToLeft && outIncidence == IncidenceType.kIncidenceToRight))
                        {
                            nGlancingHits++;
                        }
                    }
                }
                while (bRetryWithOtherRayDirection);

                return ((numberOfInters + nGlancingHits) % 2  == 1
}
}

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-12-19 01:50 , Processed in 0.390230 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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