/// <summary> /// create a box of the given width and height at center. /// </summary> /// <param name="c"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="center"></param> /// <returns></returns> static internal void CreateRectangle(Curve c, double width, double height, Point center) { double w = width / 2; double h = height / 2; double x = center.X; double y = center.Y; Point[] p = new Point[] { new Point(x - w, y - h), new Point(x + w, y - h), new Point(x + w, y + h), new Point(x - w, y + h) }; c.AddSegs(new LineSegment(p[0], p[1]), new LineSegment(p[1], p[2]), new LineSegment(p[2], p[3]), new LineSegment(p[3], p[0])); }
/// <summary> /// Creates a curve resembling a diamond large enough to inscribe within it a rectangle of the /// given width and height at center. /// </summary> /// <param name="width">the width of the inscribed rectangle</param> /// <param name="height">the height of the inscribed rectangle</param> /// <param name="center">the diamond center</param> /// <returns></returns> static public ICurve CreateDiamond(double width, double height, Point center) { double w = width; double h = height; double x = center.X; double y = center.Y; Curve c = new Curve(); Point[] p = new Point[] { new Point(x, y - h), new Point(x + w, y), new Point(x, y + h), new Point(x - w, y) }; c.AddSegs(new LineSegment(p[0], p[1]), new LineSegment(p[1], p[2]), new LineSegment(p[2], p[3]), new LineSegment(p[3], p[0])); return(c); }
/// <summary> /// Following "Biarc approximation of NURBS curves", Les A. Piegl, and Wayne Tiller. The paper has a bug in V, where they write that v=p0+p4, it is p0-p4. /// Also I treat special cases differently. /// </summary> /// <param name="p0"></param> /// <param name="ts"></param> /// <param name="p4"></param> /// <param name="te"></param> /// <returns></returns> internal static ICurve BiArc(Point p0, Point ts, Point p4, Point te) { Debug.Assert(ApproximateComparer.Close(ts.LengthSquared, 1)); Debug.Assert(ApproximateComparer.Close(te.LengthSquared, 1)); var v = p0 - p4; if (v.Length < ApproximateComparer.DistanceEpsilon) return null; var vtse = v * (ts - te); var tste = -ts * te; //solving a quadratic equation var a = 2 * (tste - 1); var b = 2 * vtse; var c = v * v; double al; if (Math.Abs(a) < ApproximateComparer.DistanceEpsilon) { //we have b*al+c=0 if (Math.Abs(b) > ApproximateComparer.DistanceEpsilon) { al = -c / b; } else { return null; } } else { var d = b * b - 4 * a * c; Debug.Assert(d >= -ApproximateComparer.Tolerance); if (d < 0) d = 0; d = Math.Sqrt(d); al = (-b + d) / (2 * a); if (al < 0) al = (-b - d) / (2 * a); } var p1 = p0 + al * ts; var p3 = p4 + al * te; var p2 = 0.5 * (p1 + p3); var curve = new Curve(); curve.AddSegs(ArcOn(p0, p1, p2), ArcOn(p2, p3, p4)); //bad input for BiArc. we shouldn't allow such cases during bundle bases construction if (ts * (p4 - p0) <= 0 && ts * te <= 0) { //switch to Bezier var curve2 = StandardBezier(p0, ts, p4, te); #if DEBUG && TEST_MSAGL /*List<DebugCurve> dc = new List<DebugCurve>(); dc.Add(new DebugCurve(curve)); dc.Add(new DebugCurve(0.3, "black", curve2)); dc.Add(new DebugCurve(0.1, "red", new LineSegment(p0, p0 + 3 * ts))); dc.Add(new DebugCurve(0.1, "blue", new LineSegment(p4, p4 + 3 * te))); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(dc);*/ #endif return curve2; } return curve; }
/// <summary> /// Creates a curve resembling a diamond large enough to inscribe within it a rectangle of the /// given width and height at center. /// </summary> /// <param name="width">the width of the inscribed rectangle</param> /// <param name="height">the height of the inscribed rectangle</param> /// <param name="center">the diamond center</param> /// <returns></returns> static public ICurve CreateDiamond(double width, double height, Point center) { double w = width; double h = height; double x = center.X; double y = center.Y; Curve c = new Curve(); Point[] p = new Point[] { new Point(x, y - h), new Point(x + w, y), new Point(x, y + h), new Point(x - w, y) }; c.AddSegs(new LineSegment(p[0], p[1]), new LineSegment(p[1], p[2]), new LineSegment(p[2], p[3]), new LineSegment(p[3], p[0])); return c; }
/// <summary> /// create a box of the given width and height at center. /// </summary> /// <param name="c"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="center"></param> /// <returns></returns> static internal void CreateRectangle(Curve c, double width, double height, Point center) { double w = width / 2; double h = height / 2; double x = center.X; double y = center.Y; Point[] p = new Point[] { new Point(x - w, y - h), new Point(x + w, y - h), new Point(x + w, y + h), new Point(x - w, y + h) }; c.AddSegs(new LineSegment(p[0], p[1]), new LineSegment(p[1], p[2]), new LineSegment(p[2], p[3]), new LineSegment(p[3], p[0])); }
private Curve ExtendCurveToEndpoints(Curve curve) { Point p = this.EdgePathPoint(0); if (!ApproximateComparer.Close(p, curve.Start)) { Curve nc = new Curve(); nc.AddSegs(new LineSegment(p, curve.Start), curve); curve = nc; } p = this.EdgePathPoint(edgePath.Count); if (!ApproximateComparer.Close(p, curve.End)) curve.AddSegment(new LineSegment(curve.End, p)); return curve; }
static ICurve GetTrimmedCurveForHookingUpAnywhere(ICurve curve, PolylinePoint lastPointInside, IntersectionInfo x0, IntersectionInfo x1) { var clockwise = Point.GetTriangleOrientation(x1.IntersectionPoint, x0.IntersectionPoint, lastPointInside.Point) == TriangleOrientation.Clockwise; double rightX = x0.Par0; double leftX = x1.Par0; ICurve tr0, tr1; Curve ret; if (clockwise) { if (rightX < leftX) return curve.Trim(rightX, leftX); tr0 = curve.Trim(rightX, curve.ParEnd); tr1 = curve.Trim(curve.ParStart, leftX); ret = new Curve(); return ret.AddSegs(tr0, tr1); } if (leftX < rightX) return curve.Trim(leftX, rightX); tr0 = curve.Trim(leftX, curve.ParEnd); tr1 = curve.Trim(curve.ParStart, rightX); ret = new Curve(); return ret.AddSegs(tr0, tr1); }