コード例 #1
0
        public static Polyline RegionIntersect(Polyline polyline1, Polyline polyline2)
        {
            Polyline resultPolyine = new Polyline();

            List <double> tempParamA = new List <double>(); //Polyline1 위의 교차점
            List <double> tempParamB = new List <double>(); //Polyline1 위의 교차점
            Curve         polyCurve1 = polyline1.ToNurbsCurve();
            Curve         polyCurve2 = polyline2.ToNurbsCurve();

            List <Curve> tempLocalResult = new List <Curve>();

            //mutual intersection
            var tempIntersection = Rhino.Geometry.Intersect.Intersection.CurveCurve(polyCurve1, polyCurve2, 0, 0);

            if (tempIntersection.Count == 0) //없으면 null..
            {
                return(resultPolyine);
            }

            foreach (var i in tempIntersection)
            {
                tempParamA.Add(i.ParameterA);
                tempParamB.Add(i.ParameterB);
            }


            List <Curve> tempSplittedA = polyCurve1.Split(tempParamA).ToList();
            List <Curve> tempSplittedB = polyCurve2.Split(tempParamB).ToList();

            //case of Polyline1
            foreach (Curve i in tempSplittedA)
            {
                List <Curve> testCrvSet = i.DuplicateSegments().ToList();

                if (testCrvSet.Count == 0)
                {
                    testCrvSet.Add(i);
                }

                foreach (Curve j in testCrvSet)
                {
                    Point3d testPt  = (j.PointAtStart + j.PointAtEnd) / 2;
                    int     decider = (int)polyCurve2.Contains(testPt);

                    if (decider != 2)
                    {
                        tempLocalResult.Add(j);
                    }
                }
            }

            //case of Polyline2
            foreach (Curve i in tempSplittedB)
            {
                List <Curve> testCrvSet = i.DuplicateSegments().ToList();

                if (testCrvSet.Count == 0)
                {
                    testCrvSet.Add(i);
                }

                foreach (Curve j in testCrvSet)
                {
                    Point3d testPt  = (j.PointAtStart + j.PointAtEnd) / 2;
                    int     decider = (int)polyCurve1.Contains(testPt);

                    if (decider != 2)
                    {
                        tempLocalResult.Add(j);
                    }
                }
            }
            List <Curve> resultList = Curve.JoinCurves(tempLocalResult, 0, true).ToList();

            resultList.Sort((a, b) => a.GetArea().CompareTo(b.GetArea()));

            if (resultList.Count != 0)
            {
                resultPolyine = CurveTools.ToPolyline(resultList[0]);
            }

            return(resultPolyine);
        }
コード例 #2
0
        public static List <Polyline> RemoveLoop(Polyline looped, bool isCCW)
        {
            Curve loopedCrv = looped.ToNurbsCurve();

            //Search selfX params.
            List <double> selfXParams = new List <double>();

            var selfIntersect = Intersection.CurveSelf(loopedCrv, 0);

            foreach (IntersectionEvent e in selfIntersect)
            {
                selfXParams.Add(e.ParameterA);
                selfXParams.Add(e.ParameterB);
            }

            //Set trimming intervals.
            List <double> trimmingParams = new List <double>();

            for (int i = 0; i < looped.Count; i++)
            {
                trimmingParams.Add(i);
            }
            trimmingParams.AddRange(selfXParams);
            trimmingParams.Sort();

            List <Interval> trimmingInterval = new List <Interval>();
            int             paramCount       = trimmingParams.Count;

            for (int i = 0; i < paramCount - 1; i++)
            {
                trimmingInterval.Add(
                    new Interval(trimmingParams[i], trimmingParams[(paramCount + i + 1) % paramCount]));
            }

            //Get segments.
            List <LineCurve> trimmedSegs = new List <LineCurve>();

            foreach (Interval i in trimmingInterval)
            {
                trimmedSegs.Add(
                    new LineCurve(looped.PointAt(i.T0), looped.PointAt(i.T1)));
            }

            //Divide segments into in/out group.
            List <LineCurve> innerSegs = new List <LineCurve>();
            List <LineCurve> outerSegs = new List <LineCurve>();

            foreach (LineCurve i in trimmedSegs)
            {
                Vector3d toInnerCCW = i.TangentAtStart;
                toInnerCCW.Rotate(Math.PI / 2, Vector3d.ZAxis);
                Point3d inOutTestPoint = (i.PointAtStart + i.PointAtEnd) / 2 + toInnerCCW;

                PointContainment inOutResult = loopedCrv.Contains(inOutTestPoint);
                if (inOutResult == PointContainment.Inside)
                {
                    innerSegs.Add(i);
                }
                else
                {
                    outerSegs.Add(i);
                }
            }

            //Decided output by curve orientation.
            List <LineCurve> outputSegs;

            if (isCCW)
            {
                outputSegs = innerSegs;
            }
            else
            {
                outputSegs = outerSegs;
            }

            if (outputSegs.Count > 0)
            {
                Curve[] outputCrv = Curve.JoinCurves(outputSegs);
                return(outputCrv.Select(n => CurveTools.ToPolyline(n)).ToList());
            }

            return(new List <Polyline>());
        }