void SetEndParamsSymmetrically() { Point targetPos = TargetBase.Position; Point sourcePos = SourceBase.Position; var dir = (targetPos - sourcePos).Normalize(); var perp = dir.Rotate90Ccw(); var middle = 0.5 * (targetPos + sourcePos); var a = middle + longEnoughSideLength * dir; var b = middle - longEnoughSideLength * dir; // [a,b] is a long enough segment //we are already fine if (SetRLParamsIfWidthIsFeasible(TotalRequiredWidth * perp / 2, a, b)) { SetInitialMidParams(); return; } //find the segment using binary search var uw = TotalRequiredWidth; var lw = 0.0; var mw = uw / 2; while (uw - lw > FeasibleWidthEpsilon) { if (SetRLParamsIfWidthIsFeasible(mw * perp / 2, a, b)) { lw = mw; } else { uw = mw; } mw = 0.5 * (uw + lw); } if (mw <= FeasibleWidthEpsilon) { //try one side if (SetRLParamsIfWidthIsFeasibleTwoPerps(2 * FeasibleWidthEpsilon * perp / 2, new Point(), a, b)) { mw = 2 * FeasibleWidthEpsilon; } else if (SetRLParamsIfWidthIsFeasibleTwoPerps(new Point(), -2 * FeasibleWidthEpsilon * perp / 2, a, b)) { mw = 2 * FeasibleWidthEpsilon; } } Debug.Assert(mw > FeasibleWidthEpsilon); SourceBase.InitialMidParameter = SourceBase.AdjustParam(SourceBase.ParRight + SourceBase.Span / 2); TargetBase.InitialMidParameter = TargetBase.AdjustParam(TargetBase.ParRight + TargetBase.Span / 2); }
void SetInitialMidParams() { double sourceParam, targetParam; var ls = TrimSegWithBoundaryCurves(new LineSegment(TargetBase.CurveCenter, SourceBase.CurveCenter), out sourceParam, out targetParam); if (ls != null) { SourceBase.InitialMidParameter = sourceParam; TargetBase.InitialMidParameter = targetParam; } else { SourceBase.InitialMidParameter = SourceBase.AdjustParam(SourceBase.ParRight + SourceBase.Span / 2); TargetBase.InitialMidParameter = TargetBase.AdjustParam(TargetBase.ParRight + TargetBase.Span / 2); } }
void ShrinkBasesToMakeTwoConsecutiveNeighborsHappy(BundleBase rBase, BundleBase lBase) { if (!rBase.Intersect(lBase)) return; //segments are now [l1..r1] and [l2..r2] double l1 = rBase.ParRight; double r1 = rBase.ParLeft; double l2 = lBase.ParRight; double r2 = lBase.ParLeft; double span = lBase.ParameterSpan; //make them regular if (l1 > r1) l1 -= span; if (l2 > r2) l2 -= span; //make them intersecting if (l2 > r1) { l2 -= span; r2 -= span; } if (l1 > r2) { l1 -= span; r1 -= span; } //they do intersect! Debug.Assert(!(l2 >= r1) && !(l1 >= r2)); double t = RegularCut(l1, r1, l2, r2, rBase.Span, lBase.Span); TriangleOrientation to = Point.GetTriangleOrientation(lBase.CurveCenter, lBase.OppositeBase.InitialMidPoint, rBase.OppositeBase.InitialMidPoint); if (to == TriangleOrientation.Clockwise) { r1 = t; l2 = t; } else if (to == TriangleOrientation.Counterclockwise) { r2 = t; l1 = t; } else { if (r2 - l1 >= r1 - l2) { r1 = t; l2 = t; } else { r2 = t; l1 = t; } } Debug.Assert(!rBase.Intersect(l1, r1, l2, r2)); lBase.ParRight = lBase.AdjustParam(l2); lBase.ParLeft = lBase.AdjustParam(r2); rBase.ParRight = rBase.AdjustParam(l1); rBase.ParLeft = rBase.AdjustParam(r1); }
void ShrinkBasesToMakeTwoConsecutiveNeighborsHappy(BundleBase rBase, BundleBase lBase) { if (!rBase.Intersect(lBase)) { return; } //segments are now [l1..r1] and [l2..r2] double l1 = rBase.ParRight; double r1 = rBase.ParLeft; double l2 = lBase.ParRight; double r2 = lBase.ParLeft; double span = lBase.ParameterSpan; //make them regular if (l1 > r1) { l1 -= span; } if (l2 > r2) { l2 -= span; } //make them intersecting if (l2 > r1) { l2 -= span; r2 -= span; } if (l1 > r2) { l1 -= span; r1 -= span; } //they do intersect! Debug.Assert(!(l2 >= r1) && !(l1 >= r2)); double t = RegularCut(l1, r1, l2, r2, rBase.Span, lBase.Span); TriangleOrientation to = Point.GetTriangleOrientation(lBase.CurveCenter, lBase.OppositeBase.InitialMidPoint, rBase.OppositeBase.InitialMidPoint); if (to == TriangleOrientation.Clockwise) { r1 = t; l2 = t; } else if (to == TriangleOrientation.Counterclockwise) { r2 = t; l1 = t; } else { if (r2 - l1 >= r1 - l2) { r1 = t; l2 = t; } else { r2 = t; l1 = t; } } Debug.Assert(!rBase.Intersect(l1, r1, l2, r2)); lBase.ParRight = lBase.AdjustParam(l2); lBase.ParLeft = lBase.AdjustParam(r2); rBase.ParRight = rBase.AdjustParam(l1); rBase.ParLeft = rBase.AdjustParam(r1); }