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); }
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>()); }