/// <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); }
/// <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; }