Пример #1
0
        /// <summary>
        /// Construct bezier curve from data points
        /// </summary>
        /// <param name="data">In: Data points</param>
        /// <param name="fitError">In: tolerated error</param>
        /// <returns>Whether bezier construction is possible</returns>
        private bool ConstructFromData(CuspData data, double fitError)
        {
            // Check for empty stroke
            if (data.Count < 2)
            {
                return(false);
            }

            // Add the first point
            AddBezierPoint(data.XY(0));

            // Special cases - 2 or 3 points
            if (data.Count == 3)
            {
                AddParabola(data, 0);
                return(true);
            }
            else if (data.Count == 2)
            {
                AddLine(data, 0, 1);
                return(true);
            }

            // For default case error passed in will be 0.
            // 3% is the default value
            if (DoubleUtil.DBL_EPSILON > fitError)
            {
                fitError = 0.03f * (data.Distance() * StrokeCollectionSerializer.HimetricToAvalonMultiplier);
            }

            data.SetTanLinks(0.5f * fitError);

            // otherwise use the value specified in the drawing attribute
            // get (error)^2
            fitError *= (fitError);

            bool   done      = false;
            int    to        = 0;
            int    next_cusp = 0;
            int    prev_cusp = 0;
            bool   is_a_cusp = true;
            Vector tanEnd    = new Vector(0, 0);
            Vector tanStart  = new Vector(0, 0);

            for (int from = 0; !done; from = to)
            {
                if (is_a_cusp)
                {
                    prev_cusp = next_cusp;
                    next_cusp = data.GetNextCusp(from);
                    if (!data.Tangent(ref tanStart, from, prev_cusp, next_cusp, false, true))
                    {
                        return(false);
                    }
                }
                else
                {
                    tanStart.X = -tanEnd.X;
                    tanStart.Y = -tanEnd.Y;
                }

                to = from + 3;

                // No meat in this loop, just extending the index range
                while (ExtendingRange(fitError, data, from, next_cusp, ref to, ref is_a_cusp, ref done))
                {
                    ;
                }

                // Find the tangent
                if (!data.Tangent(ref tanEnd, to, prev_cusp, next_cusp, true, is_a_cusp))
                {
                    return(false);
                }

                // Add bezier segment
                if (!AddBezierSegment(data, from, ref tanStart, to, ref tanEnd))
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #2
0
        /// <summary>
        /// Construct bezier curve from data points
        /// </summary>
        /// <param name="data">In: Data points</param>
        /// <param name="fitError">In: tolerated error</param>
        /// <returns>Whether bezier construction is possible</returns>
        private bool ConstructFromData(CuspData data, double fitError)
        {
            // Check for empty stroke 
            if (data.Count < 2)
            {
                return false;
            }

            // Add the first point
            AddBezierPoint(data.XY(0));

            // Special cases - 2 or 3 points
            if (data.Count == 3)
            {
                AddParabola(data, 0);
                return true;
            }
            else if (data.Count == 2)
            {
                AddLine(data, 0, 1);
                return true;
            }

            // For default case error passed in will be 0.
            // 3% is the default value
            if (DoubleUtil.DBL_EPSILON > fitError)
                fitError = 0.03f * (data.Distance() * StrokeCollectionSerializer.HimetricToAvalonMultiplier);

            data.SetTanLinks(0.5f * fitError);

            // otherwise use the value specified in the drawing attribute
            // get (error)^2
            fitError *= (fitError);

            bool done = false;
            int to = 0;
            int next_cusp = 0;
            int prev_cusp = 0;
            bool is_a_cusp = true;
            Vector tanEnd = new Vector(0, 0);
            Vector tanStart = new Vector(0, 0);

            for (int from = 0; !done; from = to)
            {
                if (is_a_cusp)
                {
                    prev_cusp = next_cusp;
                    next_cusp = data.GetNextCusp(from);
                    if (!data.Tangent(ref tanStart, from, prev_cusp, next_cusp, false, true))
                    {
                        return false;
                    }
                }
                else
                {
                    tanStart.X = -tanEnd.X;
                    tanStart.Y = -tanEnd.Y;
                }

                to = from + 3;

                // No meat in this loop, just extending the index range
                while (ExtendingRange(fitError, data, from, next_cusp, ref to, ref is_a_cusp, ref done));

                // Find the tangent 
                if (!data.Tangent(ref tanEnd, to, prev_cusp, next_cusp, true, is_a_cusp))
                {
                    return false;
                }

                // Add bezier segment
                if (!AddBezierSegment(data, from, ref tanStart, to, ref tanEnd))
                {
                    return false;
                }
            }

            return true;
        }