/GoliatEditor/OpenTK/1.1/Source/Compatibility/Math/BezierCurve.cs
C# | 262 lines | 127 code | 41 blank | 94 comment | 13 complexity | 6df3a4618f76d10f4f10fa542f17b374 MD5 | raw file
- #region --- License ---
- /* Licensed under the MIT/X11 license.
- * Copyright (c) 2006-2008 the OpenTK Team.
- * This notice may not be removed from any source distribution.
- * See license.txt for licensing detailed licensing details.
- *
- * Contributions by Georg W�chter.
- */
- #endregion
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace OpenTK.Math
- {
- /// <summary>
- /// Represents a bezier curve with as many points as you want.
- /// </summary>
- [Obsolete("OpenTK.Math functions have been moved to the root OpenTK namespace (reason: XNA compatibility")]
- [Serializable]
- public struct BezierCurve
- {
- #region Fields
- private List<Vector2> points;
- /// <summary>
- /// The parallel value.
- /// </summary>
- /// <remarks>This value defines whether the curve should be calculated as a
- /// parallel curve to the original bezier curve. A value of 0.0f represents
- /// the original curve, 5.0f i.e. stands for a curve that has always a distance
- /// of 5.0f to the orignal curve at any point.</remarks>
- public float Parallel;
- #endregion
- #region Properties
- /// <summary>
- /// Gets the points of this curve.
- /// </summary>
- /// <remarks>The first point and the last points represent the anchor points.</remarks>
- public IList<Vector2> Points
- {
- get
- {
- return points;
- }
- }
- #endregion
- #region Constructors
- /// <summary>
- /// Constructs a new <see cref="BezierCurve"/>.
- /// </summary>
- /// <param name="points">The points.</param>
- public BezierCurve(IEnumerable<Vector2> points)
- {
- if (points == null)
- throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");
- this.points = new List<Vector2>(points);
- this.Parallel = 0.0f;
- }
- /// <summary>
- /// Constructs a new <see cref="BezierCurve"/>.
- /// </summary>
- /// <param name="points">The points.</param>
- public BezierCurve(params Vector2[] points)
- {
- if (points == null)
- throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");
- this.points = new List<Vector2>(points);
- this.Parallel = 0.0f;
- }
- /// <summary>
- /// Constructs a new <see cref="BezierCurve"/>.
- /// </summary>
- /// <param name="parallel">The parallel value.</param>
- /// <param name="points">The points.</param>
- public BezierCurve(float parallel, params Vector2[] points)
- {
- if (points == null)
- throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");
- this.Parallel = parallel;
- this.points = new List<Vector2>(points);
- }
- /// <summary>
- /// Constructs a new <see cref="BezierCurve"/>.
- /// </summary>
- /// <param name="parallel">The parallel value.</param>
- /// <param name="points">The points.</param>
- public BezierCurve(float parallel, IEnumerable<Vector2> points)
- {
- if (points == null)
- throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");
- this.Parallel = parallel;
- this.points = new List<Vector2>(points);
- }
- #endregion
- #region Functions
- /// <summary>
- /// Calculates the point with the specified t.
- /// </summary>
- /// <param name="t">The t value, between 0.0f and 1.0f.</param>
- /// <returns>Resulting point.</returns>
- public Vector2 CalculatePoint(float t)
- {
- return BezierCurve.CalculatePoint(points, t, Parallel);
- }
- /// <summary>
- /// Calculates the length of this bezier curve.
- /// </summary>
- /// <param name="precision">The precision.</param>
- /// <returns>Length of curve.</returns>
- /// <remarks>The precision gets better as the <paramref name="precision"/>
- /// value gets smaller.</remarks>
- public float CalculateLength(float precision)
- {
- return BezierCurve.CalculateLength(points, precision, Parallel);
- }
- #region Static methods
- /// <summary>
- /// Calculates the length of the specified bezier curve.
- /// </summary>
- /// <param name="points">The points.</param>
- /// <param name="precision">The precision value.</param>
- /// <returns>The precision gets better as the <paramref name="precision"/>
- /// value gets smaller.</returns>
- public static float CalculateLength(IList<Vector2> points, float precision)
- {
- return BezierCurve.CalculateLength(points, precision, 0.0f);
- }
- /// <summary>
- /// Calculates the length of the specified bezier curve.
- /// </summary>
- /// <param name="points">The points.</param>
- /// <param name="precision">The precision value.</param>
- /// <param name="parallel">The parallel value.</param>
- /// <returns>Length of curve.</returns>
- /// <remarks><para>The precision gets better as the <paramref name="precision"/>
- /// value gets smaller.</para>
- /// <para>The <paramref name="parallel"/> parameter defines whether the curve should be calculated as a
- /// parallel curve to the original bezier curve. A value of 0.0f represents
- /// the original curve, 5.0f represents a curve that has always a distance
- /// of 5.0f to the orignal curve.</para></remarks>
- public static float CalculateLength(IList<Vector2> points, float precision, float parallel)
- {
- float length = 0.0f;
- Vector2 old = BezierCurve.CalculatePoint(points, 0.0f, parallel);
- for (float i = precision; i < (1.0f + precision); i += precision)
- {
- Vector2 n = CalculatePoint(points, i, parallel);
- length += (n - old).Length;
- old = n;
- }
- return length;
- }
- /// <summary>
- /// Calculates the point on the given bezier curve with the specified t parameter.
- /// </summary>
- /// <param name="points">The points.</param>
- /// <param name="t">The t parameter, a value between 0.0f and 1.0f.</param>
- /// <returns>Resulting point.</returns>
- public static Vector2 CalculatePoint(IList<Vector2> points, float t)
- {
- return BezierCurve.CalculatePoint(points, t, 0.0f);
- }
- /// <summary>
- /// Calculates the point on the given bezier curve with the specified t parameter.
- /// </summary>
- /// <param name="points">The points.</param>
- /// <param name="t">The t parameter, a value between 0.0f and 1.0f.</param>
- /// <param name="parallel">The parallel value.</param>
- /// <returns>Resulting point.</returns>
- /// <remarks>The <paramref name="parallel"/> parameter defines whether the curve should be calculated as a
- /// parallel curve to the original bezier curve. A value of 0.0f represents
- /// the original curve, 5.0f represents a curve that has always a distance
- /// of 5.0f to the orignal curve.</remarks>
- public static Vector2 CalculatePoint(IList<Vector2> points, float t, float parallel)
- {
- Vector2 r = new Vector2();
- double c = 1.0d - (double)t;
- float temp;
- int i = 0;
- foreach (Vector2 pt in points)
- {
- temp = (float)Functions.BinomialCoefficient(points.Count - 1, i) * (float)(System.Math.Pow(t, i) *
- System.Math.Pow(c, (points.Count - 1) - i));
- r.X += temp * pt.X;
- r.Y += temp * pt.Y;
- i++;
- }
- if (parallel == 0.0f)
- return r;
- Vector2 perpendicular = new Vector2();
- if (t != 0.0f)
- perpendicular = r - BezierCurve.CalculatePointOfDerivative(points, t);
- else
- perpendicular = points[1] - points[0];
- return r + Vector2.Normalize(perpendicular).PerpendicularRight * parallel;
- }
- /// <summary>
- /// Calculates the point with the specified t of the derivative of the given bezier function.
- /// </summary>
- /// <param name="points">The points.</param>
- /// <param name="t">The t parameter, value between 0.0f and 1.0f.</param>
- /// <returns>Resulting point.</returns>
- private static Vector2 CalculatePointOfDerivative(IList<Vector2> points, float t)
- {
- Vector2 r = new Vector2();
- double c = 1.0d - (double)t;
- float temp;
- int i = 0;
- foreach (Vector2 pt in points)
- {
- temp = (float)Functions.BinomialCoefficient(points.Count - 2, i) * (float)(System.Math.Pow(t, i) *
- System.Math.Pow(c, (points.Count - 2) - i));
- r.X += temp * pt.X;
- r.Y += temp * pt.Y;
- i++;
- }
- return r;
- }
- #endregion
- #endregion
- }
- }