Esempio n. 1
0
        static public bool IsInsideCurve(Curve cur, Point3d testPt)
        {
            if (!cur.Closed)
            {
                // Cannot be inside
                return(false);
            }

            var poly2d = cur as Polyline2d;

            if (poly2d != null && poly2d.PolyType != Poly2dType.SimplePoly)
            {
                // Not supported
                return(false);
            }
            var ptOnCurve = cur.GetClosestPointTo(testPt, false);

            if (Tolerance.Equals(testPt, ptOnCurve))
            {
                return(true);
            }

            // Check it's planar
            var plane = cur.GetPlane();

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

            // Make the test ray from the plane
            var normal     = plane.Normal;
            var testVector = normal.GetPerpendicularVector();

            var ray = new Ray {
                BasePoint = testPt, UnitDir = testVector
            };
            var intersectionPoints = new Point3dCollection();

            // Fire the ray at the curve
            cur.IntersectWith(ray, Intersect.OnBothOperands, intersectionPoints, 0, 0);
            ray.Dispose();

            int numberOfInters = intersectionPoints.Count;

            if (numberOfInters == 0)
            {
                // Must be outside
                return(false);
            }

            int          nGlancingHits = 0;
            const double epsilon       = 2e-6; // (trust me on this)

            for (int i = 0; i < numberOfInters; i++)
            {
                // Get the first point, and get its parameter
                Point3d hitPt    = intersectionPoints[i];
                double  hitParam = cur.GetParameterAtPoint(hitPt);

                double        inParam      = hitParam - epsilon;
                double        outParam     = hitParam + epsilon;
                IncidenceType inIncidence  = CurveIncidence(cur, inParam, testVector, normal);
                IncidenceType outIncidence = CurveIncidence(cur, outParam, testVector, normal);

                if ((inIncidence == IncidenceType.ToRight && outIncidence == IncidenceType.ToLeft) ||
                    (inIncidence == IncidenceType.ToLeft &&
                     outIncidence == IncidenceType.ToRight))
                {
                    nGlancingHits++;
                }
            }

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