Added xml comments
This commit is contained in:
Родитель
926dbcca1c
Коммит
7378baa794
|
@ -23,17 +23,41 @@ using System;
|
|||
|
||||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// The band matrix.
|
||||
/// </summary>
|
||||
internal struct BandMatrix
|
||||
{
|
||||
public double[] a; // new double[11];
|
||||
public double[] al; // new double[5];
|
||||
/// <summary>
|
||||
/// The band-diagonal matrix.
|
||||
/// A double's array of size 11.
|
||||
/// </summary>
|
||||
public double[] a;
|
||||
|
||||
/// <summary>
|
||||
/// Lower part of band-diagonal decomposition.
|
||||
/// A double's array of size 5.
|
||||
/// </summary>
|
||||
public double[] al;
|
||||
|
||||
/// <summary>
|
||||
/// Copy band matrix from source band matrix to current instance of band matrix.
|
||||
/// </summary>
|
||||
/// <param name="from">The source band matrix.</param>
|
||||
private void CopyFrom(ref BandMatrix from)
|
||||
{
|
||||
Array.Copy(from.a, 0, a, 0, 11);
|
||||
Array.Copy(from.al, 0, al, 0, 5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The source band matrix.
|
||||
/// </summary>
|
||||
/// <param name="src">The source band matrix.</param>
|
||||
/// <param name="srcIndex">The source band matrix start element index.</param>
|
||||
/// <param name="dst">The destination band matrix.</param>
|
||||
/// <param name="dstIndex">The destination band matrix start element index.</param>
|
||||
/// <param name="length">Number of elements to copy from source band matrix.</param>
|
||||
public static void Copy(BandMatrix[] src, int srcIndex, BandMatrix[] dst, int dstIndex, int length)
|
||||
{
|
||||
for (int i = 0; i < length; ++i)
|
||||
|
|
|
@ -23,12 +23,57 @@ using System;
|
|||
|
||||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract type that handles the creation of particular representation of bézier splines.
|
||||
///
|
||||
/// Spiro will 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.
|
||||
/// </summary>
|
||||
public interface IBezierContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Called by spiro to start a contour.
|
||||
/// </summary>
|
||||
/// <param name="x">The X coordinate of the new start point.</param>
|
||||
/// <param name="y">The Y coordinate of the new start point.</param>
|
||||
/// <param name="isOpen">An boolean flag indicating wheter spline is open (True) or closed (False).</param>
|
||||
void MoveTo(double x, double y, bool isOpen);
|
||||
|
||||
/// <summary>
|
||||
/// Called by spiro to move from the last point to the next one on a straight line.
|
||||
/// </summary>
|
||||
/// <param name="x">The X coordinate of the new end point.</param>
|
||||
/// <param name="y">The Y coordinate of the new end point.</param>
|
||||
void LineTo(double x, double y);
|
||||
|
||||
/// <summary>
|
||||
/// Called by spiro to move from the last point to the next along a quadratic bezier spline
|
||||
/// (x1,y1) is the quadratic bezier control point and (x2,y2) will be the new end point.
|
||||
/// </summary>
|
||||
/// <param name="x1">The X coordinate of quadratic bezier bezier control point.</param>
|
||||
/// <param name="y1">The Y coordinate of quadratic bezier bezier control point.</param>
|
||||
/// <param name="x2">The X coordinate of the new end point.</param>
|
||||
/// <param name="y2">The Y coordinate of the new end point.</param>
|
||||
void QuadTo(double x1, double y1, double x2, double y2);
|
||||
|
||||
/// <summary>
|
||||
/// Called by spiro to move from the last point to the next along a cubic bezier spline
|
||||
/// (x1,y1) and (x2,y2) are the two off-curve control point and (x3,y3) will be the new end point.
|
||||
/// </summary>
|
||||
/// <param name="x1">The X coordinate of first cubic bezier spline off-curve control point.</param>
|
||||
/// <param name="y1">The Y coordinate of first cubic bezier spline off-curve control point.</param>
|
||||
/// <param name="x2">The X coordinate of second cubic bezier spline off-curve control point.</param>
|
||||
/// <param name="y2">The Y coordinate of second cubic bezier spline off-curve control point.</param>
|
||||
/// <param name="x3">The X coordinate of the new end point.</param>
|
||||
/// <param name="y3">The Y coordinate of the new end point.</param>
|
||||
void CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
|
||||
/// <summary>
|
||||
/// Called by spiro to mark current control point knot.
|
||||
/// </summary>
|
||||
/// <param name="knotIndex">The current spiros control point knot index.</param>
|
||||
void MarkKnot(int knotIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,16 +24,31 @@ using System.Text;
|
|||
|
||||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Bezier context implementation that handles the creation of Path data representation of bézier splines.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Internally class used StringBuilder object to append generated Path data.
|
||||
/// </remarks>
|
||||
public class PathBezierContext : IBezierContext
|
||||
{
|
||||
private bool _needToClose = false;
|
||||
private StringBuilder _sb = new StringBuilder();
|
||||
|
||||
/// <summary>
|
||||
/// Format double value using en-GB culture info.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
private static string Format(double value)
|
||||
{
|
||||
return value.ToString(CultureInfo.GetCultureInfo("en-GB"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get output Path data string format.
|
||||
/// </summary>
|
||||
/// <returns>The Path data string format.</returns>
|
||||
public string GetData()
|
||||
{
|
||||
if (_needToClose)
|
||||
|
@ -45,11 +60,21 @@ namespace SpiroNet
|
|||
return _sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get output Path data string format.
|
||||
/// </summary>
|
||||
/// <returns>The Path data string format.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return GetData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a contour.
|
||||
/// </summary>
|
||||
/// <param name="x">The X coordinate of the new start point.</param>
|
||||
/// <param name="y">The Y coordinate of the new start point.</param>
|
||||
/// <param name="isOpen">An boolean flag indicating wheter spline is open (True) or closed (False).</param>
|
||||
public void MoveTo(double x, double y, bool isOpen)
|
||||
{
|
||||
if (_needToClose)
|
||||
|
@ -62,25 +87,52 @@ namespace SpiroNet
|
|||
_sb.AppendLine(move);
|
||||
_needToClose = !isOpen;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Move from the last point to the next one on a straight line.
|
||||
/// </summary>
|
||||
/// <param name="x">The X coordinate of the new end point.</param>
|
||||
/// <param name="y">The Y coordinate of the new end point.</param>
|
||||
public void LineTo(double x, double y)
|
||||
{
|
||||
var line = string.Format("L {0},{1}", Format(x), Format(y));
|
||||
_sb.AppendLine(line);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Move from the last point to the next along a quadratic bezier spline.
|
||||
/// </summary>
|
||||
/// <param name="x1">The X coordinate of quadratic bezier bezier control point.</param>
|
||||
/// <param name="y1">The Y coordinate of quadratic bezier bezier control point.</param>
|
||||
/// <param name="x2">The X coordinate of the new end point.</param>
|
||||
/// <param name="y2">The Y coordinate of the new end point.</param>
|
||||
public void QuadTo(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
var quad = string.Format("Q {0},{1} {2},{3}", Format(x1), Format(y1), Format(x2), Format(y2));
|
||||
_sb.AppendLine(quad);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Move from the last point to the next along a cubic bezier spline.
|
||||
/// </summary>
|
||||
/// <param name="x1">The X coordinate of first cubic bezier spline off-curve control point.</param>
|
||||
/// <param name="y1">The Y coordinate of first cubic bezier spline off-curve control point.</param>
|
||||
/// <param name="x2">The X coordinate of second cubic bezier spline off-curve control point.</param>
|
||||
/// <param name="y2">The Y coordinate of second cubic bezier spline off-curve control point.</param>
|
||||
/// <param name="x3">The X coordinate of the new end point.</param>
|
||||
/// <param name="y3">The Y coordinate of the new end point.</param>
|
||||
public void CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
|
||||
{
|
||||
var curve = string.Format("C {0},{1} {2},{3} {4},{5}", Format(x1), Format(y1), Format(x2), Format(y2), Format(x3), Format(y3));
|
||||
_sb.AppendLine(curve);
|
||||
}
|
||||
|
||||
public void MarkKnot(int knot_idx) { }
|
||||
|
||||
/// <summary>
|
||||
/// Mark current control point knot. Currenlty not implemented, may be usefull for marking generated curves to original spiro code points.
|
||||
/// </summary>
|
||||
/// <param name="knotIndex">The current spiros control point knot index.</param>
|
||||
public void MarkKnot(int knot_idx)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,14 +24,40 @@ using System.Linq;
|
|||
|
||||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// The spiro shape used to generate Path data.
|
||||
/// </summary>
|
||||
public class PathShape
|
||||
{
|
||||
/// <summary>
|
||||
/// Spiro control points array.
|
||||
/// </summary>
|
||||
public IList<SpiroControlPoint> Points { get; set; }
|
||||
public bool IsClosed { get; set; }
|
||||
public bool IsTagged { get; set; }
|
||||
public string Source { get; set; }
|
||||
|
||||
public bool UpdateSource()
|
||||
/// <summary>
|
||||
/// Is closed spiro shape.
|
||||
/// Whether points describe a closed (True) or open (False) contour.
|
||||
/// </summary>
|
||||
public bool IsClosed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is tagged spiro shape.
|
||||
/// This requires that spiro control points be tagged according to convention. A closed curve will have an extra control point attached to the end of it with a type of 'End'.
|
||||
/// The location of this last point is irrelevant.
|
||||
/// In an open contour the point types of the first and last control points are going to be ignored.
|
||||
/// </summary>
|
||||
public bool IsTagged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The generated Path data.
|
||||
/// </summary>
|
||||
public string Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Generate Path shape data using path bezier context implementation.
|
||||
/// </summary>
|
||||
/// <returns>True when Data was generated successfully.</returns>
|
||||
public bool UpdateData()
|
||||
{
|
||||
var points = this.Points.ToArray();
|
||||
var bc = new PathBezierContext();
|
||||
|
@ -40,9 +66,9 @@ namespace SpiroNet
|
|||
{
|
||||
var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
|
||||
if (success)
|
||||
this.Source = bc.ToString();
|
||||
this.Data = bc.ToString();
|
||||
else
|
||||
this.Source = string.Empty;
|
||||
this.Data = string.Empty;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -50,9 +76,9 @@ namespace SpiroNet
|
|||
{
|
||||
var success = Spiro.SpiroCPsToBezier0(points, points.Length, this.IsClosed, bc);
|
||||
if (success)
|
||||
this.Source = bc.ToString();
|
||||
this.Data = bc.ToString();
|
||||
else
|
||||
this.Source = string.Empty;
|
||||
this.Data = string.Empty;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -24,15 +24,23 @@ using System;
|
|||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// C# implementation of third-order polynomial spirals.
|
||||
/// Interface routines for Raph's spiro package.
|
||||
/// </summary>
|
||||
public static class Spiro
|
||||
{
|
||||
/// <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.
|
||||
/// This function is kept for backwards compatibility.
|
||||
///
|
||||
/// 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>
|
||||
|
@ -47,7 +55,11 @@ namespace SpiroNet
|
|||
/// 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.
|
||||
/// This function is kept for backwards compatibility.
|
||||
/// 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&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>
|
||||
|
@ -58,8 +70,16 @@ namespace SpiroNet
|
|||
|
||||
/// <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>
|
||||
|
@ -107,8 +127,15 @@ namespace SpiroNet
|
|||
|
||||
/// <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&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>
|
||||
|
@ -162,8 +189,16 @@ namespace SpiroNet
|
|||
|
||||
/// <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>
|
||||
|
@ -177,8 +212,18 @@ namespace SpiroNet
|
|||
|
||||
/// <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&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>
|
||||
|
|
|
@ -23,10 +23,24 @@ using System;
|
|||
|
||||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// User passes an array of spiros control points in this format for Spiro to solve.
|
||||
/// </summary>
|
||||
public struct SpiroControlPoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Spiro code point X location.
|
||||
/// </summary>
|
||||
public double X;
|
||||
|
||||
/// <summary>
|
||||
/// Spiro code point Y location.
|
||||
/// </summary>
|
||||
public double Y;
|
||||
|
||||
/// <summary>
|
||||
/// Spiro code point Type.
|
||||
/// </summary>
|
||||
public SpiroPointType Type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,15 +25,35 @@ using System;
|
|||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal implementation of spiro.
|
||||
/// C# implementation of third-order polynomial spirals.
|
||||
/// Internal implementation of spiro using ORDER equal to 12.
|
||||
/// </summary>
|
||||
internal static class SpiroImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// Compute hypotenuse. The function returns what would be the square root of the sum of the squares of x and y (as per the Pythagorean theorem), but without incurring in undue overflow or underflow of intermediate values.
|
||||
/// </summary>
|
||||
/// <param name="x">The X floating point value corresponding to the legs of a right-angled triangle for which the hypotenuse is computed.</param>
|
||||
/// <param name="y">The Y floating point value corresponding to the legs of a right-angled triangle for which the hypotenuse is computed.</param>
|
||||
/// <returns>Returns the hypotenuse of a right-angled triangle whose legs are x and y.</returns>
|
||||
public static double hypot(double x, double y)
|
||||
{
|
||||
return Math.Sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether x is a finite value.
|
||||
/// A finite value is any floating-point value that is neither infinite nor NaN (Not-A-Number).
|
||||
///
|
||||
/// IsFinite() equivalent:
|
||||
/// http://stackoverflow.com/questions/10030070/isfinite-equivalent
|
||||
/// References:
|
||||
/// http://pubs.opengroup.org/onlinepubs/009604499/functions/isfinite.html
|
||||
/// http://msdn.microsoft.com/en-us/library/system.double.isinfinity.aspx
|
||||
/// http://msdn.microsoft.com/en-us/library/system.double.isnan.aspx
|
||||
/// </summary>
|
||||
/// <param name="x">A floating-point value.</param>
|
||||
/// <returns>A non-zero value (true) if x is finite; and zero (false) otherwise.</returns>
|
||||
public static int IsFinite(double x)
|
||||
{
|
||||
return !double.IsInfinity(x) && !double.IsNaN(x) ? 1 : 0;
|
||||
|
@ -41,6 +61,7 @@ namespace SpiroNet
|
|||
|
||||
public const int N = 4;
|
||||
|
||||
// Integrate polynomial spiral curve over range -.5 .. .5.
|
||||
public static void integrate_spiro(double[] ks, double[] xy, int n)
|
||||
{
|
||||
double th1 = ks[0];
|
||||
|
@ -226,6 +247,7 @@ namespace SpiroNet
|
|||
SpiroSegment[] r;
|
||||
|
||||
#if CHECK_INPUT_FINITENESS
|
||||
// Verify that input values are within realistic limits
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (IsFinite(src[i].X) == 0 || IsFinite(src[i].Y) == 0)
|
||||
|
@ -292,6 +314,7 @@ namespace SpiroNet
|
|||
int i, j, k, l, pivot;
|
||||
double pivot_val, pivot_scale, tmp, x;
|
||||
|
||||
// pack top triangle to the left.
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
for (j = 0; j < i + 6; j++)
|
||||
|
@ -352,6 +375,7 @@ namespace SpiroNet
|
|||
int i, k, l;
|
||||
double tmp, x;
|
||||
|
||||
// forward substitution
|
||||
l = 5;
|
||||
|
||||
for (k = 0; k < n; k++)
|
||||
|
@ -372,6 +396,7 @@ namespace SpiroNet
|
|||
v[i] -= m[k].al[i - k - 1] * v[k];
|
||||
}
|
||||
|
||||
// back substitution
|
||||
l = 1;
|
||||
|
||||
for (i = n - 1; i >= 0; i--)
|
||||
|
@ -484,6 +509,7 @@ namespace SpiroNet
|
|||
|
||||
compute_pderivs(ref s[i], ends, derivs, jinc);
|
||||
|
||||
// constraints crossing left
|
||||
if (ty0 == SpiroPointType.G4 || ty0 == SpiroPointType.G2 || ty0 == SpiroPointType.Left || ty0 == SpiroPointType.Right)
|
||||
{
|
||||
jthl = jj++;
|
||||
|
@ -498,6 +524,7 @@ namespace SpiroNet
|
|||
}
|
||||
}
|
||||
|
||||
// constraints on left
|
||||
if ((ty0 == SpiroPointType.Left || ty0 == SpiroPointType.Corner || ty0 == SpiroPointType.OpenContour || ty0 == SpiroPointType.G2) && jinc == 4)
|
||||
{
|
||||
if (ty0 != SpiroPointType.G2)
|
||||
|
@ -506,6 +533,7 @@ namespace SpiroNet
|
|||
jk2l = jj++;
|
||||
}
|
||||
|
||||
// constraints on right
|
||||
if ((ty1 == SpiroPointType.Right || ty1 == SpiroPointType.Corner || ty1 == SpiroPointType.EndOpenContour || ty1 == SpiroPointType.G2) && jinc == 4)
|
||||
{
|
||||
if (ty1 != SpiroPointType.G2)
|
||||
|
@ -514,6 +542,7 @@ namespace SpiroNet
|
|||
jk2r = jj++;
|
||||
}
|
||||
|
||||
// constraints crossing right
|
||||
if (ty1 == SpiroPointType.G4 || ty1 == SpiroPointType.G2 || ty1 == SpiroPointType.Left || ty1 == SpiroPointType.Right)
|
||||
{
|
||||
jthr = jj;
|
||||
|
@ -583,6 +612,7 @@ namespace SpiroNet
|
|||
|
||||
public static bool check_finiteness(SpiroSegment[] segs, int num_segs)
|
||||
{
|
||||
// Check if all values are "finite", return true, else return fail=false
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < num_segs; ++i)
|
||||
|
@ -605,7 +635,7 @@ namespace SpiroNet
|
|||
n_alloc = nmat;
|
||||
|
||||
if (nmat == 0)
|
||||
return 1;
|
||||
return 1; // just means no convergence problems
|
||||
if (s[0].Type != SpiroPointType.OpenContour && s[0].Type != SpiroPointType.Corner)
|
||||
n_alloc *= 3;
|
||||
if (n_alloc < 5)
|
||||
|
@ -621,7 +651,7 @@ namespace SpiroNet
|
|||
v = new double[n_alloc];
|
||||
perm = new int[n_alloc];
|
||||
|
||||
i = converged = 0;
|
||||
i = converged = 0; // not solved (yet)
|
||||
if (m != null && v != null && perm != null)
|
||||
{
|
||||
while (i++ < 60)
|
||||
|
@ -677,6 +707,7 @@ namespace SpiroNet
|
|||
}
|
||||
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];
|
||||
|
@ -709,7 +740,7 @@ namespace SpiroNet
|
|||
if (s != null)
|
||||
{
|
||||
nseg = src[0].Type == SpiroPointType.OpenContour ? n - 1 : n;
|
||||
converged = 1;
|
||||
converged = 1; // this value is for when nseg == 1; else actual value determined below
|
||||
if (nseg > 1)
|
||||
converged = solve_spiro(s, nseg);
|
||||
|
||||
|
|
|
@ -23,15 +23,58 @@ using System;
|
|||
|
||||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Possible values of the spiro control point Type property.
|
||||
/// </summary>
|
||||
public enum SpiroPointType
|
||||
{
|
||||
/// <summary>
|
||||
/// A corner point.
|
||||
/// Where the slopes and curvatures of the incoming and outgoing splines are unconstrained.
|
||||
/// </summary>
|
||||
Corner = 'v',
|
||||
|
||||
/// <summary>
|
||||
/// A G4 curve point.
|
||||
/// Continuous up to the fourth derivative.
|
||||
/// </summary>
|
||||
G4 = 'o',
|
||||
|
||||
/// <summary>
|
||||
/// A G2 curve point.
|
||||
/// Continuous up to the second derivative.
|
||||
/// </summary>
|
||||
G2 = 'c',
|
||||
|
||||
/// <summary>
|
||||
/// A left constraint point.
|
||||
/// Used to connect a curved line to a straight one.
|
||||
/// </summary>
|
||||
Left = '[',
|
||||
|
||||
/// <summary>
|
||||
/// A right constraint point.
|
||||
/// Used to connect a straight line to a curved one.
|
||||
/// If you have a contour which is drawn clockwise, and you have a straight segment at the top, then the left point of that straight segment should be a left constraint, and the right point should be a right constraint.
|
||||
/// </summary>
|
||||
Right = ']',
|
||||
|
||||
/// <summary>
|
||||
/// End point.
|
||||
/// For a closed contour add an extra cp with a ty set to 'end'.
|
||||
/// </summary>
|
||||
End = 'z',
|
||||
|
||||
/// <summary>
|
||||
/// Open contour.
|
||||
/// For an open contour the first cp must have a ty set to 'open contour'.
|
||||
/// </summary>
|
||||
OpenContour = '{',
|
||||
|
||||
/// <summary>
|
||||
/// End open contour.
|
||||
/// For an open contour the last cp must have a ty set to 'end open contour'.
|
||||
/// </summary>
|
||||
EndOpenContour = '}'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,15 +23,50 @@ using System;
|
|||
|
||||
namespace SpiroNet
|
||||
{
|
||||
/// <summary>
|
||||
/// The run_spiro() uses array of information given in the spiro control point structure
|
||||
/// and creates an array in this structure format to use by spiro_to_bpath for building bezier curves.
|
||||
/// </summary>
|
||||
public struct SpiroSegment
|
||||
{
|
||||
/// <summary>
|
||||
/// Spiro code point segment_chord startX.
|
||||
/// </summary>
|
||||
public double X;
|
||||
|
||||
/// <summary>
|
||||
/// Spiro code point segment_chord startY.
|
||||
/// </summary>
|
||||
public double Y;
|
||||
|
||||
/// <summary>
|
||||
/// Spiro code point Type.
|
||||
/// </summary>
|
||||
public SpiroPointType Type;
|
||||
|
||||
/// <summary>
|
||||
/// Bend theta between this vector and next vector.
|
||||
/// </summary>
|
||||
public double bend_th;
|
||||
public double[] ks; // new double[4]
|
||||
|
||||
/// <summary>
|
||||
/// A double's array of size 4.
|
||||
/// </summary>
|
||||
public double[] ks;
|
||||
|
||||
/// <summary>
|
||||
/// The segment_chord distance from xy to next spiro code point.
|
||||
/// </summary>
|
||||
public double seg_ch;
|
||||
|
||||
/// <summary>
|
||||
/// The segment_theta angle for this spiro code point.
|
||||
/// </summary>
|
||||
public double seg_th;
|
||||
|
||||
/// <summary>
|
||||
/// Unused.
|
||||
/// </summary>
|
||||
public double l;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче