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