Ejemplo n.º 1
0
        private static bool TryToRunSpiro(SpiroShape shape, IBezierContext bc)
        {
            if (shape == null || bc == null)
            {
                return(false);
            }

            try
            {
                var points = shape.Points.ToArray();
                if (shape.IsTagged)
                {
                    return(Spiro.TaggedSpiroCPsToBezier0(points, bc));
                }
                else
                {
                    return(Spiro.SpiroCPsToBezier0(points, points.Length, shape.IsClosed, bc));
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex.StackTrace);
            }

            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Convert a set of spiro control points into a set of bézier curves.
        /// 
        /// As it does so it will call the appropriate routine in your bézier context with this information 
        /// – this should allow you to create your own internal representation of those curves.
        /// 
        /// Open contours do not need to start with '{', nor to end with '}'.
        /// 
        /// Close contours do not need to end with 'z'.
        /// 
        /// This function is kept for backwards compatibility for older programs. 
        /// Please use the function that return success/failure replies when done.	
        /// </summary>
        /// <param name="spiros">An array of input spiros.</param>
        /// <param name="n">The number of elements in the spiros array.</param>
        /// <param name="isClosed">Whether this describes a closed (True) or open (False) contour.</param>
        /// <param name="bc">A bézier results output context.</param>
        /// <returns>An boolean success flag. True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</returns>
        /// <example>
        /// var points = new SpiroControlPoint[4];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.SpiroCPsToBezier0(points, 4, true, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        /// </example>
        public static bool SpiroCPsToBezier0(SpiroControlPoint[] spiros, int n, bool isClosed, IBezierContext bc)
        {
            SpiroSegment[] s;

            if (n <= 0)
                return false;
            if (isClosed)
                s = SpiroImpl.run_spiro(spiros, n);
            else
            {
                SpiroPointType oldty_start = spiros[0].Type;
                SpiroPointType oldty_end = spiros[n - 1].Type;
                spiros[0].Type = SpiroPointType.OpenContour;
                spiros[n - 1].Type = SpiroPointType.EndOpenContour;
                s = SpiroImpl.run_spiro(spiros, n);
                spiros[n - 1].Type = oldty_end;
                spiros[0].Type = oldty_start;
            }

            if (s != null)
            {
                SpiroImpl.spiro_to_bpath(s, n, bc);
                return true; // success
            }

            return false; // spiro did not converge or encountered non-finite values
        }
Ejemplo n.º 3
0
        public static void spiro_to_bpath(SpiroSegment[] s, int n, IBezierContext bc)
        {
            int    i, nsegs;
            double x0, y0, x1, y1;

            if (s == null || n <= 0 || bc == null)
            {
                return;
            }

            nsegs = s[n - 1].Type == SpiroPointType.EndOpenContour ? n - 1 : n;

            for (i = 0; i < nsegs; i++)
            {
                x0 = s[i].X; x1 = s[i + 1].X;
                y0 = s[i].Y; y1 = s[i + 1].Y;

                if (i == 0)
                {
                    bc.MoveTo(x0, y0, s[0].Type == SpiroPointType.OpenContour ? true : false);
                }

                bc.MarkKnot(i, get_knot_th(s, i), s[i].X, s[i].Y, s[i].Type);
                spiro_seg_to_bpath(s[i].ks, x0, y0, x1, y1, bc, 0);
            }

            if (nsegs == n - 1)
            {
                bc.MarkKnot(n - 1, get_knot_th(s, n - 1), s[n - 1].X, s[n - 1].Y, s[n - 1].Type);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Convert a tagged set of spiro control points into a set of bézier curves.
        ///
        /// As it does so it will call the appropriate routine in your bézier context with this information
        /// – this should allow you to create your own internal representation of those curves.
        ///
        /// The spiros array should indicate it's own end.
        ///
        /// Open contours must have the ty field of the first cp set to '{' and have the ty field of the last cp set to '}'.
        ///
        /// Closed contours must have an extra cp at the end whose ty is 'z' the x and y values of this extra cp are ignored.
        /// </summary>
        /// <param name="spiros">An array of input spiros.</param>
        /// <param name="bc">A bézier results output context.</param>
        /// <returns>An boolean success flag.True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</returns>
        /// <example>
        /// var points = new SpiroControlPoint[5];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// points[4].X = 0; points[4].Y = 0; points[4].Type = SpiroPointType.End;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        ///
        /// var points = new SpiroControlPoint[5];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// points[4].X = 0; points[4].Y = 0; points[4].Type = SpiroPointType.End;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        /// </example>
        public static bool TaggedSpiroCPsToBezier0(SpiroControlPoint[] spiros, IBezierContext bc)
        {
            var s = TaggedSpiroCPsToSegments(spiros);

            if (s != null)
            {
                SpiroImpl.spiro_to_bpath(s, s.Length - 1, bc);
                return(true); // success
            }

            return(false); // spiro did not converge or encountered non-finite values
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Convert a tagged set of spiro control points into a set of bézier curves.
        ///
        /// As it does so it will call the appropriate routine in your bézier context with this information
        /// – this should allow you to create your own internal representation of those curves.
        ///
        /// The spiros array should indicate it's own end.
        ///
        /// Open contours must have the ty field of the first cp set to '{' and have the ty field of the last cp set to '}'.
        ///
        /// Closed contours must have an extra cp at the end whose ty is 'z' the x and y values of this extra cp are ignored.
        /// </summary>
        /// <param name="spiros">An array of input spiros.</param>
        /// <param name="bc">A bézier results output context.</param>
        /// <returns>An boolean success flag.True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</returns>
        /// <example>
        /// var points = new SpiroControlPoint[5];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// points[4].X = 0; points[4].Y = 0; points[4].Type = SpiroPointType.End;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        ///
        /// var points = new SpiroControlPoint[5];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// points[4].X = 0; points[4].Y = 0; points[4].Type = SpiroPointType.End;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        /// </example>
        public static bool TaggedSpiroCPsToBezier0(SpiroControlPoint[] spiros, IBezierContext bc)
        {
            SpiroSegment[] s;
            int            n;

            n = 0;
            while (true)
            {
                if (spiros[n].Type == SpiroPointType.End || spiros[n].Type == SpiroPointType.EndOpenContour)
                {
                    break;
                }

                // invalid input
                if (n >= spiros.Length)
                {
                    return(false);
                }

                ++n;
            }

            if (spiros[n].Type == SpiroPointType.EndOpenContour)
            {
                ++n;
            }

            if (n <= 0)
            {
                return(false); // invalid input
            }
            s = SpiroImpl.run_spiro(spiros, n);

            if (s != null)
            {
                SpiroImpl.spiro_to_bpath(s, n, bc);
                return(true); // success
            }

            return(false); // spiro did not converge or encountered non-finite values
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Convert a tagged set of spiro control points into a set of bézier curves.
 ///
 /// As it does so it will call the appropriate routine in your bézier context with this information
 /// – this should allow you to create your own internal representation of those curves.
 ///
 /// The spiros array should indicate it's own end.
 ///
 /// Open contours must have the ty field of the first cp set to '{' and have the ty field of the last cp set to '}'.
 ///
 /// Closed contours must have an extra cp at the end whose ty is 'z' the x and y values of this extra cp are ignored.
 ///
 /// This function is kept for backwards compatibility for older programs.
 /// Please use the functions that return success/failure replies when done.
 /// </summary>
 /// <param name="spiros">An array of input spiros.</param>
 /// <param name="bc">A bézier results output context.</param>
 public static void TaggedSpiroCPsToBezier(SpiroControlPoint[] spiros, IBezierContext bc)
 {
     TaggedSpiroCPsToBezier0(spiros, bc);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Convert a set of spiro control points into a set of bézier curves.
 ///
 /// As it does so it will call the appropriate routine in your bézier context with this information
 /// – this should allow you to create your own internal representation of those curves.
 ///
 /// Open contours do not need to start with '{', nor to end with '}'.
 ///
 /// Close contours do not need to end with 'z'.
 ///
 /// This function is kept for backwards compatibility for older programs.
 /// Please use the function that return success/failure replies when done.
 /// </summary>
 /// <param name="spiros">An array of input spiros.</param>
 /// <param name="n">The number of elements in the spiros array.</param>
 /// <param name="isClosed">Whether this describes a closed (True) or open (False) contour.</param>
 /// <param name="bc">A bézier results output context.</param>
 public static void SpiroCPsToBezier(SpiroControlPoint[] spiros, int n, bool isClosed, IBezierContext bc)
 {
     SpiroCPsToBezier0(spiros, n, isClosed, bc);
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Convert a tagged set of spiro control points into a set of bézier curves.
 ///
 /// As it does so it will call the appropriate routine in your bézier context with this information
 /// – this should allow you to create your own internal representation of those curves.
 ///
 /// The spiros array should indicate it's own end.
 ///
 /// Open contours must have the ty field of the first cp set to '{' and have the ty field of the last cp set to '}'.
 ///
 /// Closed contours must have an extra cp at the end whose ty is 'z' the x and y values of this extra cp are ignored.
 ///
 /// If you can't use TaggedSpiroCPsToBezier0() this function is enhanced version of the original function,
 /// where spiro success/failure replies are passd back through done output parameter.
 /// </summary>
 /// <param name="spiros">An array of input spiros.</param>
 /// <param name="bc">A bézier results output context.</param>
 /// <param name="done">An boolean success flag.True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</param>
 public static void TaggedSpiroCPsToBezier1(SpiroControlPoint[] spiros, IBezierContext bc, out bool done)
 {
     done = TaggedSpiroCPsToBezier0(spiros, bc);
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Convert a set of spiro control points into a set of bézier curves.
 ///
 /// As it does so it will call the appropriate routine in your bézier context with this information
 /// – this should allow you to create your own internal representation of those curves.
 ///
 /// Open contours do not need to start with '{', nor to end with '}'.
 ///
 /// Close contours do not need to end with 'z'.
 ///
 /// If you can't use SpiroCPsToBezier0() this function is enhanced version of the original function,
 /// where spiro success/failure replies are passd back through done output parameter.
 /// </summary>
 /// <param name="spiros">An array of input spiros.</param>
 /// <param name="n">The number of elements in the spiros array.</param>
 /// <param name="isClosed">Whether this describes a closed (True) or open (False) contour.</param>
 /// <param name="bc">A bézier results output context.</param>
 /// <param name="done">An boolean success flag. True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</param>
 public static void SpiroCPsToBezier1(SpiroControlPoint[] spiros, int n, bool isClosed, IBezierContext bc, out bool done)
 {
     done = SpiroCPsToBezier0(spiros, n, isClosed, bc);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Convert a set of spiro control points into a set of bézier curves.
        ///
        /// As it does so it will call the appropriate routine in your bézier context with this information
        /// – this should allow you to create your own internal representation of those curves.
        ///
        /// Open contours do not need to start with '{', nor to end with '}'.
        ///
        /// Close contours do not need to end with 'z'.
        ///
        /// This function is kept for backwards compatibility for older programs.
        /// Please use the function that return success/failure replies when done.
        /// </summary>
        /// <param name="spiros">An array of input spiros.</param>
        /// <param name="n">The number of elements in the spiros array.</param>
        /// <param name="isClosed">Whether this describes a closed (True) or open (False) contour.</param>
        /// <param name="bc">A bézier results output context.</param>
        /// <returns>An boolean success flag. True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</returns>
        /// <example>
        /// var points = new SpiroControlPoint[4];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.SpiroCPsToBezier0(points, 4, true, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        /// </example>
        public static bool SpiroCPsToBezier0(SpiroControlPoint[] spiros, int n, bool isClosed, IBezierContext bc)
        {
            SpiroSegment[]? s = SpiroCPsToSegments(spiros, n, isClosed);
            if (s != null)
            {
                SpiroImpl.spiro_to_bpath(s, n, bc);
                return(true); // success
            }

            return(false); // spiro did not converge or encountered non-finite values
        }
Ejemplo n.º 11
0
        public static void spiro_to_bpath(SpiroSegment[] s, int n, IBezierContext bc)
        {
            int i, nsegs;
            double x0, y0, x1, y1;

            if (s == null || n <= 0 || bc == null)
                return;

            nsegs = s[n - 1].Type == SpiroPointType.EndOpenContour ? n - 1 : n;

            for (i = 0; i < nsegs; i++)
            {
                x0 = s[i].X; x1 = s[i + 1].X;
                y0 = s[i].Y; y1 = s[i + 1].Y;

                if (i == 0)
                    bc.MoveTo(x0, y0, s[0].Type == SpiroPointType.OpenContour ? true : false);

                bc.MarkKnot(i, get_knot_th(s, i), s[i].X, s[i].Y, s[i].Type);
                spiro_seg_to_bpath(s[i].ks, x0, y0, x1, y1, bc, 0);
            }

            if (nsegs == n - 1)
                bc.MarkKnot(n - 1, get_knot_th(s, n - 1), s[n - 1].X, s[n - 1].Y, s[n - 1].Type);
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Convert a set of spiro control points into a set of bézier curves.
 /// 
 /// As it does so it will call the appropriate routine in your bézier context with this information 
 /// – this should allow you to create your own internal representation of those curves.
 /// 
 /// Open contours do not need to start with '{', nor to end with '}'.
 /// 
 /// Close contours do not need to end with 'z'.
 /// 
 /// This function is kept for backwards compatibility for older programs. 
 /// Please use the function that return success/failure replies when done.	
 /// </summary>
 /// <param name="spiros">An array of input spiros.</param>
 /// <param name="n">The number of elements in the spiros array.</param>
 /// <param name="isClosed">Whether this describes a closed (True) or open (False) contour.</param>
 /// <param name="bc">A bézier results output context.</param>
 public static void SpiroCPsToBezier(SpiroControlPoint[] spiros, int n, bool isClosed, IBezierContext bc)
 {
     SpiroCPsToBezier0(spiros, n, isClosed, bc);
 }
Ejemplo n.º 13
0
        public static void spiro_seg_to_bpath(double[] ks, double x0, double y0, double x1, double y1, IBezierContext bc, int depth)
        {
            double bend, seg_ch, seg_th, ch, th, scale, rot;
            double th_even, th_odd, ul, vl, ur, vr;
            double thsub, xmid, ymid, cth, sth;

            double[] ksub = new double[4]; double[] xysub = new double[2]; double[] xy = new double[2];

            bend = Math.Abs(ks[0]) + Math.Abs(0.5 * ks[1]) + Math.Abs(0.125 * ks[2]) + Math.Abs((1.0 / 48) * ks[3]);

            if (bend <= 1e-8)
            {
                bc.LineTo(x1, y1);
            }
            else
            {
                seg_ch = hypot(x1 - x0, y1 - y0);
                seg_th = Math.Atan2(y1 - y0, x1 - x0);

                integrate_spiro(ks, xy, N);
                ch    = hypot(xy[0], xy[1]);
                th    = Math.Atan2(xy[1], xy[0]);
                scale = seg_ch / ch;
                rot   = seg_th - th;

                if (depth > 5 || bend < 1.0)
                {
                    th_even = (1.0 / 384) * ks[3] + (1.0 / 8) * ks[1] + rot;
                    th_odd  = (1.0 / 48) * ks[2] + 0.5 * ks[0];
                    ul      = (scale * (1.0 / 3)) * Math.Cos(th_even - th_odd);
                    vl      = (scale * (1.0 / 3)) * Math.Sin(th_even - th_odd);
                    ur      = (scale * (1.0 / 3)) * Math.Cos(th_even + th_odd);
                    vr      = (scale * (1.0 / 3)) * Math.Sin(th_even + th_odd);
                    bc.CurveTo(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1);
                }
                else
                {
                    // subdivide
                    ksub[0] = .5 * ks[0] - .125 * ks[1] + (1.0 / 64) * ks[2] - (1.0 / 768) * ks[3];
                    ksub[1] = .25 * ks[1] - (1.0 / 16) * ks[2] + (1.0 / 128) * ks[3];
                    ksub[2] = .125 * ks[2] - (1.0 / 32) * ks[3];
                    ksub[3] = (1.0 / 16) * ks[3];
                    thsub   = rot - .25 * ks[0] + (1.0 / 32) * ks[1] - (1.0 / 384) * ks[2] + (1.0 / 6144) * ks[3];
                    cth     = .5 * scale * Math.Cos(thsub);
                    sth     = .5 * scale * Math.Sin(thsub);
                    integrate_spiro(ksub, xysub, N);
                    xmid = x0 + cth * xysub[0] - sth * xysub[1];
                    ymid = y0 + cth * xysub[1] + sth * xysub[0];
                    spiro_seg_to_bpath(ksub, x0, y0, xmid, ymid, bc, depth + 1);
                    ksub[0] += .25 * ks[1] + (1.0 / 384) * ks[3];
                    ksub[1] += .125 * ks[2];
                    ksub[2] += (1.0 / 16) * ks[3];
                    spiro_seg_to_bpath(ksub, xmid, ymid, x1, y1, bc, depth + 1);
                }
            }
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Convert a tagged set of spiro control points into a set of bézier curves.
 /// 
 /// As it does so it will call the appropriate routine in your bézier context with this information 
 /// – this should allow you to create your own internal representation of those curves.
 /// 
 /// The spiros array should indicate it's own end.
 /// 
 /// Open contours must have the ty field of the first cp set to '{' and have the ty field of the last cp set to '}'.
 /// 
 /// Closed contours must have an extra cp at the end whose ty is 'z' the x and y values of this extra cp are ignored.
 /// 
 /// If you can't use TaggedSpiroCPsToBezier0() this function is enhanced version of the original function, 
 /// where spiro success/failure replies are passd back through done output parameter. 
 /// </summary>
 /// <param name="spiros">An array of input spiros.</param>
 /// <param name="bc">A bézier results output context.</param>
 /// <param name="done">An boolean success flag.True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</param>
 public static void TaggedSpiroCPsToBezier1(SpiroControlPoint[] spiros, IBezierContext bc, out bool done)
 {
     done = TaggedSpiroCPsToBezier0(spiros, bc);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Convert a tagged set of spiro control points into a set of bézier curves.
        /// 
        /// As it does so it will call the appropriate routine in your bézier context with this information 
        /// – this should allow you to create your own internal representation of those curves.
        /// 
        /// The spiros array should indicate it's own end.
        /// 
        /// Open contours must have the ty field of the first cp set to '{' and have the ty field of the last cp set to '}'.
        /// 
        /// Closed contours must have an extra cp at the end whose ty is 'z' the x and y values of this extra cp are ignored.
        /// </summary>
        /// <param name="spiros">An array of input spiros.</param>
        /// <param name="bc">A bézier results output context.</param>
        /// <returns>An boolean success flag.True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</returns>
        /// <example>
        /// var points = new SpiroControlPoint[5];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// points[4].X = 0; points[4].Y = 0; points[4].Type = SpiroPointType.End;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        /// 
        /// var points = new SpiroControlPoint[5];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// points[4].X = 0; points[4].Y = 0; points[4].Type = SpiroPointType.End;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        /// </example>
        public static bool TaggedSpiroCPsToBezier0(SpiroControlPoint[] spiros, IBezierContext bc)
        {
            SpiroSegment[] s;
            int n;

            n = 0;
            while (true)
            {
                if (spiros[n].Type == SpiroPointType.End || spiros[n].Type == SpiroPointType.EndOpenContour)
                    break;

                // invalid input
                if (n >= spiros.Length)
                    return false;

                ++n;
            }

            if (spiros[n].Type == SpiroPointType.EndOpenContour)
                ++n;

            if (n <= 0)
                return false; // invalid input

            s = SpiroImpl.run_spiro(spiros, n);

            if (s != null)
            {
                SpiroImpl.spiro_to_bpath(s, n, bc);
                return true; // success
            }

            return false; // spiro did not converge or encountered non-finite values
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Convert a tagged set of spiro control points into a set of bézier curves.
 ///
 /// As it does so it will call the appropriate routine in your bézier context with this information 
 /// – this should allow you to create your own internal representation of those curves.
 ///
 /// The spiros array should indicate it's own end.
 ///
 /// Open contours must have the ty field of the first cp set to '{' and have the ty field of the last cp set to '}'.
 ///
 /// Closed contours must have an extra cp at the end whose ty is 'z' the x and y values of this extra cp are ignored.
 ///
 /// This function is kept for backwards compatibility for older programs. 
 /// Please use the functions that return success/failure replies when done.
 /// </summary>
 /// <param name="spiros">An array of input spiros.</param>
 /// <param name="bc">A bézier results output context.</param>
 public static void TaggedSpiroCPsToBezier(SpiroControlPoint[] spiros, IBezierContext bc)
 {
     TaggedSpiroCPsToBezier0(spiros, bc);
 }
Ejemplo n.º 17
0
 /// <summary>
 /// Convert a set of spiro control points into a set of bézier curves.
 /// 
 /// As it does so it will call the appropriate routine in your bézier context with this information 
 /// – this should allow you to create your own internal representation of those curves.
 /// 
 /// Open contours do not need to start with '{', nor to end with '}'.
 /// 
 /// Close contours do not need to end with 'z'.
 /// 
 /// If you can't use SpiroCPsToBezier0() this function is enhanced version of the original function, 
 /// where spiro success/failure replies are passd back through done output parameter. 
 /// </summary>
 /// <param name="spiros">An array of input spiros.</param>
 /// <param name="n">The number of elements in the spiros array.</param>
 /// <param name="isClosed">Whether this describes a closed (True) or open (False) contour.</param>
 /// <param name="bc">A bézier results output context.</param>
 /// <param name="done">An boolean success flag. True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</param>
 public static void SpiroCPsToBezier1(SpiroControlPoint[] spiros, int n, bool isClosed, IBezierContext bc, out bool done)
 {
     done = SpiroCPsToBezier0(spiros, n, isClosed, bc);
 }
Ejemplo n.º 18
0
        private static bool TryToRunSpiro(SpiroShape shape, IBezierContext bc)
        {
            if (shape == null || bc == null)
                return false;

            try
            {
                var points = shape.Points.ToArray();
                if (shape.IsTagged)
                    return Spiro.TaggedSpiroCPsToBezier0(points, bc);
                else
                    return Spiro.SpiroCPsToBezier0(points, points.Length, shape.IsClosed, bc);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex.StackTrace);
            }

            return false;
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Convert a set of spiro control points into a set of bézier curves.
        ///
        /// As it does so it will call the appropriate routine in your bézier context with this information
        /// – this should allow you to create your own internal representation of those curves.
        ///
        /// Open contours do not need to start with '{', nor to end with '}'.
        ///
        /// Close contours do not need to end with 'z'.
        ///
        /// This function is kept for backwards compatibility for older programs.
        /// Please use the function that return success/failure replies when done.
        /// </summary>
        /// <param name="spiros">An array of input spiros.</param>
        /// <param name="n">The number of elements in the spiros array.</param>
        /// <param name="isClosed">Whether this describes a closed (True) or open (False) contour.</param>
        /// <param name="bc">A bézier results output context.</param>
        /// <returns>An boolean success flag. True = completed task and have valid bézier results, or False = unable to complete task, bézier results are invalid.</returns>
        /// <example>
        /// var points = new SpiroControlPoint[4];
        /// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
        /// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
        /// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
        /// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
        /// var bc = new PathBezierContext();
        /// var success = Spiro.SpiroCPsToBezier0(points, 4, true, bc);
        /// Console.WriteLine(bc);
        /// Console.WriteLine("Success: {0} ", success);
        /// </example>
        public static bool SpiroCPsToBezier0(SpiroControlPoint[] spiros, int n, bool isClosed, IBezierContext bc)
        {
            SpiroSegment[] s;

            if (n <= 0)
            {
                return(false);
            }
            if (isClosed)
            {
                s = SpiroImpl.run_spiro(spiros, n);
            }
            else
            {
                SpiroPointType oldty_start = spiros[0].Type;
                SpiroPointType oldty_end   = spiros[n - 1].Type;
                spiros[0].Type     = SpiroPointType.OpenContour;
                spiros[n - 1].Type = SpiroPointType.EndOpenContour;
                s = SpiroImpl.run_spiro(spiros, n);
                spiros[n - 1].Type = oldty_end;
                spiros[0].Type     = oldty_start;
            }

            if (s != null)
            {
                SpiroImpl.spiro_to_bpath(s, n, bc);
                return(true); // success
            }

            return(false); // spiro did not converge or encountered non-finite values
        }
Ejemplo n.º 20
0
        public static void spiro_seg_to_bpath(double[] ks, double x0, double y0, double x1, double y1, IBezierContext bc, int depth)
        {
            double bend, seg_ch, seg_th, ch, th, scale, rot;
            double th_even, th_odd, ul, vl, ur, vr;
            double thsub, xmid, ymid, cth, sth;
            double[] ksub = new double[4]; double[] xysub = new double[2]; double[] xy = new double[2];

            bend = Math.Abs(ks[0]) + Math.Abs(0.5 * ks[1]) + Math.Abs(0.125 * ks[2]) + Math.Abs((1.0 / 48) * ks[3]);

            if (bend <= 1e-8)
            {
                bc.LineTo(x1, y1);
            }
            else
            {
                seg_ch = hypot(x1 - x0, y1 - y0);
                seg_th = Math.Atan2(y1 - y0, x1 - x0);

                integrate_spiro(ks, xy, N);
                ch = hypot(xy[0], xy[1]);
                th = Math.Atan2(xy[1], xy[0]);
                scale = seg_ch / ch;
                rot = seg_th - th;

                if (depth > 5 || bend < 1.0)
                {
                    th_even = (1.0 / 384) * ks[3] + (1.0 / 8) * ks[1] + rot;
                    th_odd = (1.0 / 48) * ks[2] + 0.5 * ks[0];
                    ul = (scale * (1.0 / 3)) * Math.Cos(th_even - th_odd);
                    vl = (scale * (1.0 / 3)) * Math.Sin(th_even - th_odd);
                    ur = (scale * (1.0 / 3)) * Math.Cos(th_even + th_odd);
                    vr = (scale * (1.0 / 3)) * Math.Sin(th_even + th_odd);
                    bc.CurveTo(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1);
                }
                else
                {
                    // subdivide
                    ksub[0] = .5 * ks[0] - .125 * ks[1] + (1.0 / 64) * ks[2] - (1.0 / 768) * ks[3];
                    ksub[1] = .25 * ks[1] - (1.0 / 16) * ks[2] + (1.0 / 128) * ks[3];
                    ksub[2] = .125 * ks[2] - (1.0 / 32) * ks[3];
                    ksub[3] = (1.0 / 16) * ks[3];
                    thsub = rot - .25 * ks[0] + (1.0 / 32) * ks[1] - (1.0 / 384) * ks[2] + (1.0 / 6144) * ks[3];
                    cth = .5 * scale * Math.Cos(thsub);
                    sth = .5 * scale * Math.Sin(thsub);
                    integrate_spiro(ksub, xysub, N);
                    xmid = x0 + cth * xysub[0] - sth * xysub[1];
                    ymid = y0 + cth * xysub[1] + sth * xysub[0];
                    spiro_seg_to_bpath(ksub, x0, y0, xmid, ymid, bc, depth + 1);
                    ksub[0] += .25 * ks[1] + (1.0 / 384) * ks[3];
                    ksub[1] += .125 * ks[2];
                    ksub[2] += (1.0 / 16) * ks[3];
                    spiro_seg_to_bpath(ksub, xmid, ymid, x1, y1, bc, depth + 1);
                }
            }
        }