static void AdjustParameters(ParallelogramLeaf l0, LineSegment ls0, ParallelogramLeaf l1, LineSegment ls1, Point x, ref double asol, ref double bsol) { if (ls0 != l0.Seg && l0.Seg is Polyline == false) //l0.Seg is not a LineSegment and not a polyline asol = l0.Seg.ClosestParameter(x); //we need to find the correct parameter else asol = l0.Low + asol*(l0.High - l0.Low); if (ls1 != l1.Seg && l1.Seg is Polyline == false) //l1.Seg is not a LineSegment and not a polyline bsol = l1.Seg.ClosestParameter(x); //we need to find the correct parameter else bsol = l1.Low + bsol*(l1.High - l1.Low); }
static void GoDeeper(ref List<IntersectionInfo> intersections, ParallelogramLeaf l0, ParallelogramLeaf l1) { double eps = ApproximateComparer.DistanceEpsilon; // Console.WriteLine("did not find an intersection"); if (l0.LeafBoxesOffset > eps && l1.LeafBoxesOffset > eps) { // Console.WriteLine("going deeper on both with offset {0} {1}", l0.LeafBoxesOffset / 2, l1.LeafBoxesOffset / 2); ParallelogramNodeOverICurve nn0 = ParallelogramNodeOverICurve.CreateParallelogramNodeForCurveSeg( l0.Low, l0.High, l0.Seg, l0.LeafBoxesOffset/2); ParallelogramNodeOverICurve nn1 = ParallelogramNodeOverICurve.CreateParallelogramNodeForCurveSeg( l1.Low, l1.High, l1.Seg, l1.LeafBoxesOffset/2); CurveCurveXWithParallelogramNodes(nn0, nn1, ref intersections); } else if (l0.LeafBoxesOffset > eps) { // Console.WriteLine("go deeper on the left"); ParallelogramNodeOverICurve nn0 = ParallelogramNodeOverICurve.CreateParallelogramNodeForCurveSeg( l0.Low, l0.High, l0.Seg, l0.LeafBoxesOffset/2); CurveCurveXWithParallelogramNodes(nn0, l1, ref intersections); } else if (l1.LeafBoxesOffset > eps) { // Console.WriteLine("go deeper on the right"); ParallelogramNodeOverICurve nn1 = ParallelogramNodeOverICurve.CreateParallelogramNodeForCurveSeg( l1.Low, l1.High, l1.Seg, l1.LeafBoxesOffset/2); CurveCurveXWithParallelogramNodes(l0, nn1, ref intersections); } else { //just cross LineSegs since the polylogramms are so thin Point l0Low = l0.Seg[l0.Low]; Point l0High = l0.Seg[l0.High]; if (!ApproximateComparer.Close(l0Low, l0High)) { Point l1Low = l1.Seg[l1.Low]; Point l1High = l1.Seg[l1.High]; if (!ApproximateComparer.Close(l1Low, l1High)) { LineSegment ls0 = l0.Seg is LineSegment ? l0.Seg as LineSegment : new LineSegment(l0Low, l0High); LineSegment ls1 = l1.Seg is LineSegment ? l1.Seg as LineSegment : new LineSegment(l1Low, l1High); double asol, bsol; Point x; bool r = CrossWithinIntervalsWithGuess(ls0, ls1, 0, 1, 0, 1, 0.5, 0.5, out asol, out bsol, out x); if (r) { AdjustParameters(l0, ls0, l1, ls1, x, ref asol, ref bsol); AddIntersection(l0, l1, intersections, asol, bsol, x); } } } } }
static IntersectionInfo CreateIntersectionOne(ParallelogramLeaf n0, ParallelogramLeaf n1, double aSol, double bSol, Point x) { //adjust the intersection if it is close to the ends of the segs if (ApproximateComparer.CloseIntersections(x, n0.Seg[n0.Low])) { x = n0.Seg[n0.Low]; aSol = n0.Low; } else if (ApproximateComparer.CloseIntersections(x, n0.Seg[n0.High])) { x = n0.Seg[n0.High]; aSol = n0.High; } if (ApproximateComparer.CloseIntersections(x, n1.Seg[n1.Low])) { x = n1.Seg[n1.Low]; bSol = n1.Low; } else if (ApproximateComparer.CloseIntersections(x, n1.Seg[n1.High])) { x = n1.Seg[n1.High]; bSol = n1.High; } return new IntersectionInfo(aSol, bSol, x, n0.Seg, n1.Seg); }
static IntersectionInfo GoDeeperOne(ParallelogramLeaf l0, ParallelogramLeaf l1) { double eps = ApproximateComparer.DistanceEpsilon; // Console.WriteLine("did not find an intersection"); if (l0.LeafBoxesOffset > eps && l1.LeafBoxesOffset > eps) { // Console.WriteLine("going deeper on both with offset {0} {1}", l0.LeafBoxesOffset / 2, l1.LeafBoxesOffset / 2); ParallelogramNodeOverICurve nn0 = ParallelogramNodeOverICurve.CreateParallelogramNodeForCurveSeg( l0.Low, l0.High, l0.Seg, l0.LeafBoxesOffset/2); ParallelogramNodeOverICurve nn1 = ParallelogramNodeOverICurve.CreateParallelogramNodeForCurveSeg( l1.Low, l1.High, l1.Seg, l1.LeafBoxesOffset/2); return CurveCurveXWithParallelogramNodesOne(nn0, nn1); } if (l0.LeafBoxesOffset > eps) { // Console.WriteLine("go deeper on the left"); ParallelogramNodeOverICurve nn0 = ParallelogramNodeOverICurve.CreateParallelogramNodeForCurveSeg( l0.Low, l0.High, l0.Seg, l0.LeafBoxesOffset/2); return CurveCurveXWithParallelogramNodesOne(nn0, l1); } if (l1.LeafBoxesOffset > eps) { // Console.WriteLine("go deeper on the right"); ParallelogramNodeOverICurve nn1 = ParallelogramNodeOverICurve.CreateParallelogramNodeForCurveSeg( l1.Low, l1.High, l1.Seg, l1.LeafBoxesOffset/2); return CurveCurveXWithParallelogramNodesOne(l0, nn1); } //just cross LineSegs and adjust the solutions if the segments are not straight lines Point l0Low = l0.Seg[l0.Low]; Point l0High = l0.Seg[l0.High]; if (!ApproximateComparer.Close(l0Low, l0High)) { Point l1Low = l1.Seg[l1.Low]; Point l1High = l1.Seg[l1.High]; if (!ApproximateComparer.Close(l1Low, l1High)) { LineSegment ls0 = l0.Seg is LineSegment ? l0.Seg as LineSegment : new LineSegment(l0Low, l0High); LineSegment ls1 = l1.Seg is LineSegment ? l1.Seg as LineSegment : new LineSegment(l1Low, l1High); double asol, bsol; Point x; bool r = CrossWithinIntervalsWithGuess(ls0, ls1, 0, 1, 0, 1, 0.5, 0.5, out asol, out bsol, out x); if (r) { AdjustParameters(l0, ls0, l1, ls1, x, ref asol, ref bsol); return CreateIntersectionOne(l0, l1, asol, bsol, x); } } } return null; }
static void AddIntersection(ParallelogramLeaf n0, ParallelogramLeaf n1, List<IntersectionInfo> intersections, double aSol, double bSol, Point x) { //adjust the intersection if it is close to the ends of the segs if (ApproximateComparer.CloseIntersections(x, n0.Seg[n0.Low])) { x = n0.Seg[n0.Low]; aSol = n0.Low; } else if (ApproximateComparer.CloseIntersections(x, n0.Seg[n0.High])) { x = n0.Seg[n0.High]; aSol = n0.High; } if (ApproximateComparer.CloseIntersections(x, n1.Seg[n1.Low])) { x = n1.Seg[n1.Low]; bSol = n1.Low; } else if (ApproximateComparer.CloseIntersections(x, n1.Seg[n1.High])) { x = n1.Seg[n1.High]; bSol = n1.High; } bool oldIntersection = OldIntersection(intersections, ref x); if (!oldIntersection) { var xx = new IntersectionInfo(aSol, bSol, x, n0.Seg, n1.Seg); intersections.Add(xx); } return; }