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);
        }
        private Curve ExtendCurveToEndpoints(Curve curve)
        {
            Point p = headSite.Point;

            if (!ApproximateComparer.Close(p, curve.Start))
            {
                Curve nc = new Curve();
                nc.AddSegs(new LineSegment(p, curve.Start), curve);
                curve = nc;
            }
            p = TailSite.Point;
            if (!ApproximateComparer.Close(p, curve.End))
            {
                curve.AddSegment(new LineSegment(curve.End, p));
            }
            return(curve);
        }
Exemple #3
0
        /// <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);
        }