예제 #1
0
        static bool ParallelSegsIntersect(ref Parallelogram p0, ref Parallelogram p1)
        {
            Point v0 = p0.Corner;
            Point v1 = p0.OtherCorner;

            Point v2 = p1.Corner;
            Point v3 = p1.OtherCorner;


            Point d = v1 - v0;

            //let us imagine that v0 is at zero

            double r0 = 0; // position of v0

            //offset of v1
            double r1 = d * d;

            //offset of v2
            double r2 = (v2 - v0) * d;

            //offset of v3
            double r3 = (v3 - v0) * d;

            // we need to check if [r0,r1] intersects [r2,r3]

            if (r2 > r3)
            {
                double t = r2;
                r2 = r3;
                r3 = t;
            }

            return(!(r3 < r0 - ApproximateComparer.DistanceEpsilon || r2 > r1 + ApproximateComparer.DistanceEpsilon));
        }
예제 #2
0
/// <summary>
/// returns true if parallelograms intersect
/// </summary>
        /// <param name="parallelogram0"></param>
        /// <param name="parallelogram1"></param>
/// <returns></returns>
        static public bool Intersect(Parallelogram parallelogram0, Parallelogram parallelogram1)
        {
            //my hunch is that p0 and p1 do not intersect if and only if
            //they can be separated with one of the parallelogram sides in case when at least one of them


            bool ret = !(separByA(ref parallelogram0, ref parallelogram1) || separByA(ref parallelogram1, ref parallelogram0) ||
                         separByB(ref parallelogram0, ref parallelogram1) || separByB(ref parallelogram1, ref parallelogram0));

            if (ret == false)
            {
                return(false);
            }

            if (!(parallelogram0.isSeg && parallelogram1.isSeg))
            {
                return(true);
            }


            if (!Point.ParallelWithinEpsilon(parallelogram0.OtherCorner - parallelogram0.Corner,
                                             parallelogram1.OtherCorner - parallelogram1.Corner, 1.0E-5))
            {
                return(true);
            }

            //here we know that the segs are parallel
            return(ParallelSegsIntersect(ref parallelogram1, ref parallelogram0));
        }
 internal ParallelogramLeaf(double low, double high, Parallelogram box, ICurve seg, double leafBoxesOffset)
     : base(seg, leafBoxesOffset)
 {
     this.low           = low;
     this.high          = high;
     this.Parallelogram = box;
 }
예제 #4
0
        void CalculatePbNode()
        {
            pBNode = new ParallelogramInternalTreeNode(this, ParallelogramNodeOverICurve.DefaultLeafBoxesOffset);
            var           parallelograms = new List <Parallelogram>();
            PolylinePoint pp             = StartPoint;
            int           offset         = 0;

            while (pp.Next != null)
            {
                Parallelogram parallelogram = ParallelogramOfLineSeg(pp.Point, pp.Next.Point);
                parallelograms.Add(parallelogram);
                pBNode.AddChild(new ParallelogramLeaf(offset, offset + 1, parallelogram, this, 0));
                pp = pp.Next;
                offset++;
            }

            if (Closed)
            {
                Parallelogram parallelogram = ParallelogramOfLineSeg(EndPoint.Point, StartPoint.Point);
                parallelograms.Add(parallelogram);
                pBNode.AddChild(new ParallelogramLeaf(offset, offset + 1, parallelogram, this, 0));
            }

            pBNode.Parallelogram = Parallelogram.GetParallelogramOfAGroup(parallelograms);
        }
예제 #5
0
        internal Parallelogram(Parallelogram box0, Parallelogram box1)
        {
            Point  v = box0.Corner;
            double minX, maxX, minY, maxY;

            minX = maxX = v.X;
            minY = maxY = v.Y;


            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box0.aPlusCorner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box0.otherCorner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box0.bPlusCorner);

            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box1.corner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box1.aPlusCorner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box1.otherCorner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box1.bPlusCorner);

            this.corner = new Point(minX, minY);
            this.a      = new Point(0, maxY - minY);
            this.b      = new Point(maxX - minX, 0);

            aPlusCorner = a + corner;
            otherCorner = b + aPlusCorner;
            bPlusCorner = b + corner;

            this.aRot = new Point(-this.a.Y, this.a.X);
            if (aRot.Length > 0.5)
            {
                aRot = aRot.Normalize();
            }

            this.bRot = new Point(-this.b.Y, this.b.X);
            if (bRot.Length > 0.5)
            {
                bRot = bRot.Normalize();
            }

            abRot = this.a * bRot;
            baRot = this.b * aRot;


            if (abRot < 0)
            {
                abRot = -abRot;
                bRot  = -bRot;
            }

            if (baRot < 0)
            {
                baRot = -baRot;
                aRot  = -aRot;
            }

            isSeg = (this.a - this.b).Length < ApproximateComparer.DistanceEpsilon;
        }
예제 #6
0
        /// <summary>
        /// Creates a bounding parallelogram on a curve segment
        /// We suppose here that the segment is convex or concave from start to end,
        /// that is the region bounded by the straight segment seg[start], seg[end] and the curve seg is convex
        /// </summary>
        internal static bool CreateParallelogramOnSubSeg(double start, double end, ICurve seg, ref Parallelogram box,
                                                         Point startPoint, Point endPoint)
        {
            if (seg is CubicBezierSegment)
            {
                return(CreateParallelogramOnSubSegOnBezierSeg(start, end, seg, ref box));
            }

            Point tan1 = seg.Derivative(start);

            Point tan2     = seg.Derivative(end);
            Point tan2Perp = Point.P(-tan2.Y, tan2.X);



            Point p = endPoint - startPoint;

            double numerator   = p * tan2Perp;
            double denumerator = (tan1 * tan2Perp);
            double x;// = (p * tan2Perp) / (tan1 * tan2Perp);

            if (Math.Abs(numerator) < ApproximateComparer.DistanceEpsilon)
            {
                x = 0;
            }
            else if (Math.Abs(denumerator) < ApproximateComparer.DistanceEpsilon)
            {
                //it is degenerated; adjacent sides are parallel, but
                //since p * tan2Perp is big it does not contain e
                return(false);
            }
            else
            {
                x = numerator / denumerator;
            }

            tan1 *= x;

            box = new Parallelogram(startPoint, tan1, endPoint - startPoint - tan1);
#if DEBUGCURVES
            if (!box.Contains(seg[end]))
            {
                throw new InvalidOperationException();//"the box does not contain the end of the segment");
            }
#endif

            double delta = (end - start) / 64;
            for (int i = 1; i < 64; i++)
            {
                if (!box.Contains(seg[start + delta * i]))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #7
0
        static bool separByB(ref Parallelogram p0, ref Parallelogram p1)
        {
            double eps = ApproximateComparer.DistanceEpsilon;
            double p1a = (p1.Vertex(0) - p0.corner) * p0.bRot;

            if (p1a > p0.abRot + eps)
            {
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=371
                //SharpKit/Colin - can't cast ints to enum
                foreach (var i in p1.OtherVertices)
                {
                    if ((i - p0.corner) * p0.bRot <= p0.abRot + eps)
                    {
                        return(false);
                    }
                }
#else
                for (int i = 1; i < 4; i++)
                {
                    if ((p1.Vertex((VertexId)i) - p0.corner) * p0.bRot <= p0.abRot + eps)
                    {
                        return(false);
                    }
                }
#endif

                return(true);
            }
            else if (p1a < -eps)
            {
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=371
                //SharpKit/Colin - can't cast ints to enum
                foreach (var i in p1.OtherVertices)
                {
                    if ((i - p0.corner) * p0.bRot >= -eps)
                    {
                        return(false);
                    }
                }
#else
                for (int i = 1; i < 4; i++)
                {
                    if ((p1.Vertex((VertexId)i) - p0.corner) * p0.bRot >= -eps)
                    {
                        return(false);
                    }
                }
#endif
                return(true);
            }
            return(false);
        }
예제 #8
0
        static ParallelogramNodeOverICurve CreateNodeWithSegmentSplit(double start, double end, Ellipse seg, double eps)
        {
            var pBNode = new ParallelogramInternalTreeNode(seg, eps);

            pBNode.AddChild(CreateParallelogramNodeForCurveSeg(start, 0.5 * (start + end), seg, eps));
            pBNode.AddChild(CreateParallelogramNodeForCurveSeg(0.5 * (start + end), end, seg, eps));
            var boxes = new List <Parallelogram>();

            boxes.Add(pBNode.Children[0].Parallelogram);
            boxes.Add(pBNode.Children[1].Parallelogram);
            pBNode.Parallelogram = Parallelogram.GetParallelogramOfAGroup(boxes);
            return(pBNode);
        }
예제 #9
0
        internal static ParallelogramNodeOverICurve CreateParallelogramNodeForCurveSeg(double start, double end,
                                                                                       Ellipse seg, double eps)
        {
            bool closedSeg = (start == seg.ParStart && end == seg.ParEnd && ApproximateComparer.Close(seg.Start, seg.End));

            if (closedSeg)
            {
                return(CreateNodeWithSegmentSplit(start, end, seg, eps));
            }

            Point s      = seg[start];
            Point e      = seg[end];
            Point w      = e - s;
            Point middle = seg[(start + end) / 2];

            if (ParallelogramNodeOverICurve.DistToSegm(middle, s, e) <= ApproximateComparer.IntersectionEpsilon &&
                w * w < Curve.LineSegmentThreshold * Curve.LineSegmentThreshold && end - start < Curve.LineSegmentThreshold)
            {
                var ls   = new LineSegment(s, e);
                var leaf = ls.ParallelogramNodeOverICurve as ParallelogramLeaf;
                leaf.Low   = start;
                leaf.High  = end;
                leaf.Seg   = seg;
                leaf.Chord = ls;
                return(leaf);
            }

            bool we  = WithinEpsilon(seg, start, end, eps);
            var  box = new Parallelogram();

            if (we && CreateParallelogramOnSubSeg(start, end, seg, ref box))
            {
                return(new ParallelogramLeaf(start, end, box, seg, eps));
            }
            else
            {
                return(CreateNodeWithSegmentSplit(start, end, seg, eps));
            }
        }
예제 #10
0
        internal static bool CreateParallelogramOnSubSegOnBezierSeg(double start, double end, ICurve seg, ref Parallelogram box)
        {
            CubicBezierSegment trimSeg = seg.Trim(start, end) as CubicBezierSegment;


            B     b = trimSeg.B;
            Point a = b(1) - b(0);

            box = new Parallelogram(b(0), a, b(3) - b(0));

            if (box.Contains(b(2)))
            {
                return(true);
            }

            box = new Parallelogram(b(3), b(2) - b(3), b(0) - b(3));

            if (box.Contains(b(1)))
            {
                return(true);
            }

            return(false);
        }
        internal static bool CreateParallelogramOnSubSeg(double start, double end, Ellipse seg, ref Parallelogram box){
            Point tan1 = seg.Derivative(start);

            Point tan2 = seg.Derivative(end);
            Point tan2Perp = Point.P(-tan2.Y, tan2.X);

            Point corner = seg[start];

            Point e = seg[end];

            Point p = e - corner;

            double numerator = p*tan2Perp;
            double denumerator = (tan1*tan2Perp);
            double x; // = (p * tan2Perp) / (tan1 * tan2Perp);
            if(Math.Abs(numerator) < ApproximateComparer.DistanceEpsilon)
                x = 0;
            else if(Math.Abs(denumerator) < ApproximateComparer.DistanceEpsilon){
                //it is degenerated; adjacent sides are parallel, but 
                //since p * tan2Perp is big it does not contain e
                return false;
            } else x = numerator/denumerator;

            tan1 *= x;

            box = new Parallelogram(corner, tan1, e - corner - tan1);
#if DEBUGCURVES
      if (!box.Contains(seg[end]))
      {
      
        throw new InvalidOperationException();//"the box does not contain the end of the segment");
      }
#endif

            return true;
        }
        /// <summary>
        /// Creates a bounding parallelogram on a curve segment
        /// We suppose here that the segment is convex or concave from start to end,
        /// that is the region bounded by the straight segment seg[start], seg[end] and the curve seg is convex
        /// </summary>
        internal static bool CreateParallelogramOnSubSeg(double start, double end, ICurve seg, ref Parallelogram box,  
            Point startPoint, Point endPoint) {

            if (seg is CubicBezierSegment)
                return CreateParallelogramOnSubSegOnBezierSeg(start, end, seg, ref box);

            Point tan1 = seg.Derivative(start);

            Point tan2 = seg.Derivative(end);
            Point tan2Perp = Point.P(-tan2.Y, tan2.X);

           

            Point p = endPoint - startPoint;

            double numerator = p * tan2Perp;
            double denumerator = (tan1 * tan2Perp);
            double x;// = (p * tan2Perp) / (tan1 * tan2Perp);
            if (Math.Abs(numerator) < ApproximateComparer.DistanceEpsilon)
                x = 0;
            else if (Math.Abs(denumerator) < ApproximateComparer.DistanceEpsilon) {
                //it is degenerated; adjacent sides are parallel, but 
                //since p * tan2Perp is big it does not contain e
                return false;
            } else x = numerator / denumerator;

            tan1 *= x;

            box = new Parallelogram(startPoint, tan1, endPoint - startPoint - tan1);
#if DEBUGCURVES
      if (!box.Contains(seg[end]))
      {
      
        throw new InvalidOperationException();//"the box does not contain the end of the segment");
      }
#endif

            double delta = (end - start) / 64;
            for (int i = 1; i < 64; i++) {
                if (!box.Contains(seg[start + delta * i])) 
                    return false;
               }
            return true;


        }
예제 #13
0
        internal static bool CreateParallelogramOnSubSeg(double start, double end, Ellipse seg, ref Parallelogram box)
        {
            Point tan1 = seg.Derivative(start);

            Point tan2     = seg.Derivative(end);
            Point tan2Perp = Point.P(-tan2.Y, tan2.X);

            Point corner = seg[start];

            Point e = seg[end];

            Point p = e - corner;

            double numerator   = p * tan2Perp;
            double denumerator = (tan1 * tan2Perp);
            double x; // = (p * tan2Perp) / (tan1 * tan2Perp);

            if (Math.Abs(numerator) < ApproximateComparer.DistanceEpsilon)
            {
                x = 0;
            }
            else if (Math.Abs(denumerator) < ApproximateComparer.DistanceEpsilon)
            {
                //it is degenerated; adjacent sides are parallel, but
                //since p * tan2Perp is big it does not contain e
                return(false);
            }
            else
            {
                x = numerator / denumerator;
            }

            tan1 *= x;

            box = new Parallelogram(corner, tan1, e - corner - tan1);
#if DEBUGCURVES
            if (!box.Contains(seg[end]))
            {
                throw new InvalidOperationException();//"the box does not contain the end of the segment");
            }
#endif

            return(true);
        }
        internal static ParallelogramNodeOverICurve CreateParallelogramNodeForCurveSeg(double start, double end,
                                                                                       Ellipse seg, double eps){
            bool closedSeg = (start == seg.ParStart && end == seg.ParEnd && ApproximateComparer.Close(seg.Start, seg.End));
            if(closedSeg)
                return CreateNodeWithSegmentSplit(start, end, seg, eps);

            Point s = seg[start];
            Point e = seg[end];
            Point w = e - s;
            Point middle = seg[(start + end) / 2];
           
            if (ParallelogramNodeOverICurve.DistToSegm(middle, s, e) <= ApproximateComparer.IntersectionEpsilon &&
                w * w < Curve.LineSegmentThreshold * Curve.LineSegmentThreshold && end - start < Curve.LineSegmentThreshold) {
                var ls = new LineSegment(s, e);
                var leaf = ls.ParallelogramNodeOverICurve as ParallelogramLeaf;
                leaf.Low = start;
                leaf.High = end;
                leaf.Seg = seg;
                leaf.Chord = ls;
                return leaf;
            }

            bool we = WithinEpsilon(seg, start, end, eps);
            var box = new Parallelogram();

            if(we && CreateParallelogramOnSubSeg(start, end, seg, ref box)){
                return new ParallelogramLeaf(start, end, box, seg, eps);
            } else{
                return CreateNodeWithSegmentSplit(start, end, seg, eps);
            }
        }
        ParallelogramNode Calc(List<ParallelogramNode> nodes) {

            if (nodes.Count == 0)
                return null;

            if (nodes.Count == 1)
                return nodes[0];

            //Finding the seeds
            Parallelogram b0 = nodes[0].Parallelogram;

            //the first seed
            int seed0 = 1;

            double area = new Parallelogram(b0, nodes[seed0].Parallelogram).Area;
            for (int i = 2; i < nodes.Count; i++) {
                double area0 = new Parallelogram(b0, nodes[i].Parallelogram).Area;
                if (area0 > area) {
                    seed0 = i;
                    area = area0;
                }
            }

            //Got the first seed seed0
            //Now looking for a seed for the second group
            int seed1 = 0; //the compiler forces me to init it

            //init seed1
            for (int i = 0; i < nodes.Count; i++) {
                if (i != seed0) {
                    seed1 = i;
                    break;
                }
            }

            area = new Parallelogram(nodes[seed0].Parallelogram, nodes[seed1].Parallelogram).Area;
            //Now try to improve the second seed

            for (int i = 0; i < nodes.Count; i++) {
                if (i == seed0)
                    continue;
                double area1 = new Parallelogram(nodes[seed0].Parallelogram, nodes[i].Parallelogram).Area;
                if (area1 > area) {
                    seed1 = i;
                    area = area1;
                }
            }

            //We have two seeds at hand. Build two groups.
            List<ParallelogramNode> gr0 = new List<ParallelogramNode>();
            List<ParallelogramNode> gr1 = new List<ParallelogramNode>();

            gr0.Add(nodes[seed0]);
            gr1.Add(nodes[seed1]);

            Parallelogram box0 = nodes[seed0].Parallelogram;
            Parallelogram box1 = nodes[seed1].Parallelogram;
            //divide nodes on two groups
            for (int i = 0; i < nodes.Count; i++) {

                if (i == seed0 || i == seed1)
                    continue;

                Parallelogram box0_ = new Parallelogram(box0, nodes[i].Parallelogram);
                double delta0 = box0_.Area - box0.Area;

                Parallelogram box1_ = new Parallelogram(box1, nodes[i].Parallelogram);
                double delta1 = box1_.Area - box1.Area;

                //keep the tree roughly balanced

                if (gr0.Count * groupSplitThreshold < gr1.Count) {
                    gr0.Add(nodes[i]);
                    box0 = box0_;
                } else if (gr1.Count * groupSplitThreshold < gr0.Count) {
                    gr1.Add(nodes[i]);
                    box1 = box1_;
                } else if (delta0 < delta1) {
                    gr0.Add(nodes[i]);
                    box0 = box0_;
                } else {
                    gr1.Add(nodes[i]);
                    box1 = box1_;
                }

            }

            ParallelogramBinaryTreeNode ret = new ParallelogramBinaryTreeNode();
            ret.Parallelogram = new Parallelogram(box0, box1);
        
            ret.LeftSon = Calc(gr0);
            ret.RightSon = Calc(gr1);
         
            return ret;

        }
 internal ParallelogramLeaf(double low, double high, Parallelogram box, ICurve seg, double leafBoxesOffset)
     : base(seg, leafBoxesOffset) {
     this.low = low;
     this.high = high;
     this.Parallelogram = box;
 }
        static bool ParallelSegsIntersect(ref Parallelogram p0, ref Parallelogram p1) {

            Point v0 = p0.Corner;
            Point v1 = p0.OtherCorner;

            Point v2 = p1.Corner;
            Point v3 = p1.OtherCorner;


            Point d = v1 - v0;

            //let us imagine that v0 is at zero

            double r0 = 0; // position of v0

            //offset of v1
            double r1 = d * d;

            //offset of v2
            double r2 = (v2 - v0) * d;

            //offset of v3
            double r3 = (v3 - v0) * d;

            // we need to check if [r0,r1] intersects [r2,r3]

            if (r2 > r3) {
                double t = r2;
                r2 = r3;
                r3 = t;
            }

            return !(r3 < r0 - ApproximateComparer.DistanceEpsilon || r2 > r1 + ApproximateComparer.DistanceEpsilon);

        }
/// <summary>
/// returns true if parallelograms intersect
/// </summary>
        /// <param name="parallelogram0"></param>
        /// <param name="parallelogram1"></param>
/// <returns></returns>
        static public bool Intersect(Parallelogram parallelogram0, Parallelogram parallelogram1) {
            //my hunch is that p0 and p1 do not intersect if and only if
            //they can be separated with one of the parallelogram sides in case when at least one of them


            bool ret = !(separByA(ref parallelogram0, ref parallelogram1) || separByA(ref parallelogram1, ref parallelogram0) ||
                       separByB(ref parallelogram0, ref parallelogram1) || separByB(ref parallelogram1, ref parallelogram0));

            if (ret == false)
                return false;

            if (!(parallelogram0.isSeg && parallelogram1.isSeg))
                return true;


            if (!Point.ParallelWithinEpsilon(parallelogram0.OtherCorner - parallelogram0.Corner,
                                             parallelogram1.OtherCorner - parallelogram1.Corner, 1.0E-5))
                return true;

            //here we know that the segs are parallel
            return ParallelSegsIntersect(ref parallelogram1, ref parallelogram0);

        }
예제 #19
0
        static bool separByA(ref Parallelogram p0, ref Parallelogram p1)
        {
            double eps = ApproximateComparer.DistanceEpsilon;
            Point  t   = new Point(p1.corner.X - p0.corner.X, p1.corner.Y - p0.corner.Y);
            double p1a = mult(ref t, ref p0.aRot);

            if (p1a > p0.baRot + eps)
            {
                t.X = p1.aPlusCorner.X - p0.corner.X;
                t.Y = p1.aPlusCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) <= p0.baRot + eps)
                {
                    return(false);
                }

                t.X = p1.bPlusCorner.X - p0.corner.X;
                t.Y = p1.bPlusCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) <= p0.baRot + eps)
                {
                    return(false);
                }

                t.X = p1.otherCorner.X - p0.corner.X;
                t.Y = p1.otherCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) <= p0.baRot + eps)
                {
                    return(false);
                }

                return(true);
            }
            else if (p1a < -eps)
            {
                t.X = p1.aPlusCorner.X - p0.corner.X;
                t.Y = p1.aPlusCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) >= -eps)
                {
                    return(false);
                }

                t.X = p1.bPlusCorner.X - p0.corner.X;
                t.Y = p1.bPlusCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) >= -eps)
                {
                    return(false);
                }

                t.X = p1.otherCorner.X - p0.corner.X;
                t.Y = p1.otherCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) >= -eps)
                {
                    return(false);
                }

                return(true);
            }

            return(false);/*
                           * double eps = Curve.DistEps;
                           *
                           * double p1a = (p1.Corner - p0.Corner) * p0.aRot;
                           *
                           * if (p1a > p0.baRot + eps) {
                           * for (int i = 1; i < 4; i++) {
                           * if ((p1.Vertex((Parallelogram.VertexId)i) - p0.corner) * p0.aRot <= p0.baRot + eps)
                           * return false;
                           * }
                           * return true;
                           * } else if (p1a < -eps) {
                           * for (int i = 1; i < 4; i++) {
                           *
                           * double delta = (p1.Vertex((Parallelogram.VertexId)i) - p0.corner) * p0.aRot;
                           *
                           * if (delta >= -eps) {
                           * return false;
                           * }
                           * }
                           * return true;
                           * }
                           *
                           * return false;*/
        }
         static bool separByA(ref Parallelogram p0, ref Parallelogram p1) {

            double eps = ApproximateComparer.DistanceEpsilon;
            Point t = new Point(p1.corner.X - p0.corner.X, p1.corner.Y - p0.corner.Y);
            double p1a = mult(ref t , ref p0.aRot);

            if (p1a > p0.baRot + eps) {
                t.X = p1.aPlusCorner.X - p0.corner.X;
                t.Y = p1.aPlusCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) <= p0.baRot + eps)
                    return false;

                t.X = p1.bPlusCorner.X - p0.corner.X;
                t.Y = p1.bPlusCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) <= p0.baRot + eps)
                    return false;

                t.X = p1.otherCorner.X - p0.corner.X;
                t.Y = p1.otherCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) <= p0.baRot + eps)
                    return false;

                return true;
            } else if (p1a < -eps) {
                t.X = p1.aPlusCorner.X - p0.corner.X;
                t.Y = p1.aPlusCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) >= - eps)
                    return false;

                t.X = p1.bPlusCorner.X - p0.corner.X;
                t.Y = p1.bPlusCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) >= -eps)
                    return false;

                t.X = p1.otherCorner.X - p0.corner.X;
                t.Y = p1.otherCorner.Y - p0.corner.Y;
                if (mult(ref t, ref p0.aRot) >= -eps)
                    return false;

                return true;
            }

            return false;/*
            double eps = Curve.DistEps;
            
            double p1a = (p1.Corner - p0.Corner) * p0.aRot;

            if (p1a > p0.baRot + eps) {
                for (int i = 1; i < 4; i++) {
                    if ((p1.Vertex((Parallelogram.VertexId)i) - p0.corner) * p0.aRot <= p0.baRot + eps)
                        return false;
                }
                return true;
            } else if (p1a < -eps) {
                for (int i = 1; i < 4; i++) {

                    double delta = (p1.Vertex((Parallelogram.VertexId)i) - p0.corner) * p0.aRot;

                    if (delta >= -eps) {
                        return false;
                    }
                }
                return true;
            }

            return false;*/
        }
         static bool separByB(ref Parallelogram p0, ref Parallelogram p1) {
            double eps = ApproximateComparer.DistanceEpsilon;
            double p1a = (p1.Vertex(0) - p0.corner) * p0.bRot;

            if (p1a > p0.abRot + eps) {
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=371
                //SharpKit/Colin - can't cast ints to enum
                foreach (var i in p1.OtherVertices)
                    if ((i - p0.corner)*p0.bRot <= p0.abRot + eps)
                        return false;
#else
                for (int i = 1; i < 4; i++) {
                    if ((p1.Vertex((VertexId)i) - p0.corner) * p0.bRot <= p0.abRot + eps)
                        return false;
                }
#endif

                return true;
            } else if (p1a < -eps) {
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=371
                //SharpKit/Colin - can't cast ints to enum
                foreach (var i in p1.OtherVertices)
                    if ((i - p0.corner) * p0.bRot >= -eps)
                        return false;
#else
                for (int i = 1; i < 4; i++) {
                    if ((p1.Vertex((VertexId)i) - p0.corner) * p0.bRot >= -eps)
                        return false;
                }
#endif
                return true;
            }
            return false;
        }
        internal static bool CreateParallelogramOnSubSegOnBezierSeg(double start, double end, ICurve seg, ref Parallelogram box) {

            CubicBezierSegment trimSeg = seg.Trim(start, end) as CubicBezierSegment;


            B b = trimSeg.B;
            Point a = b(1) - b(0);

            box = new Parallelogram(b(0), a, b(3) - b(0));

            if (box.Contains(b(2)))
                return true;

            box = new Parallelogram(b(3), b(2) - b(3), b(0) - b(3));

            if (box.Contains(b(1)))
                return true;

            return false;
        }
        internal Parallelogram(Parallelogram box0, Parallelogram box1) {
            Point v = box0.Corner;
            double minX, maxX, minY, maxY;
            minX = maxX = v.X;
            minY = maxY = v.Y;


            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box0.aPlusCorner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box0.otherCorner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box0.bPlusCorner);

            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box1.corner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box1.aPlusCorner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box1.otherCorner);
            PumpMinMax(ref minX, ref maxX, ref minY, ref maxY, ref box1.bPlusCorner);

            this.corner = new Point(minX, minY);
            this.a = new Point(0, maxY - minY);
            this.b = new Point(maxX - minX, 0);

            aPlusCorner = a + corner;
            otherCorner = b + aPlusCorner;
            bPlusCorner = b + corner;

            this.aRot = new Point(-this.a.Y, this.a.X);
            if (aRot.Length > 0.5)
                aRot = aRot.Normalize();

            this.bRot = new Point(-this.b.Y, this.b.X);
            if (bRot.Length > 0.5)
                bRot = bRot.Normalize();

            abRot = this.a * bRot;
            baRot = this.b * aRot;


            if (abRot < 0) {
                abRot = -abRot;
                bRot = -bRot;
            }

            if (baRot < 0) {
                baRot = -baRot;
                aRot = -aRot;
            }

            isSeg = (this.a - this.b).Length < ApproximateComparer.DistanceEpsilon;
        }