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)); }
internal ParallelogramLeaf(double low, double high, Parallelogram box, ICurve seg, double leafBoxesOffset) : base(seg, leafBoxesOffset) { this.low = low; this.high = high; this.Parallelogram = box; }
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); }
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; }
/// <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); }
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); }
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); }
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)); } }
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; }
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); }
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; }