#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 cubic bezier curve with two anchor and two control points.
/// </summary>
[Obsolete
("OpenTK.Math functions have been moved to the root OpenTK namespace (reason: XNA compatibility")]
[Serializable
]
public struct BezierCurveCubic
{
#region Fields
/// <summary>
/// Start anchor point.
/// </summary>
public Vector2 StartAnchor
;
/// <summary>
/// End anchor point.
/// </summary>
public Vector2 EndAnchor
;
/// <summary>
/// First control point, controls the direction of the curve start.
/// </summary>
public Vector2 FirstControlPoint
;
/// <summary>
/// Second control point, controls the direction of the curve end.
/// </summary>
public Vector2 SecondControlPoint
;
/// <summary>
/// Gets or sets 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.f to the orignal curve at any point.</remarks>
public float Parallel
;
#endregion
#region Constructors
/// <summary>
/// Constructs a new <see cref="BezierCurveCubic"/>.
/// </summary>
/// <param name="startAnchor">The start anchor point.</param>
/// <param name="endAnchor">The end anchor point.</param>
/// <param name="firstControlPoint">The first control point.</param>
/// <param name="secondControlPoint">The second control point.</param>
public BezierCurveCubic
(Vector2 startAnchor, Vector2 endAnchor, Vector2 firstControlPoint, Vector2 secondControlPoint
)
{
this.StartAnchor = startAnchor
;
this.EndAnchor = endAnchor
;
this.FirstControlPoint = firstControlPoint
;
this.SecondControlPoint = secondControlPoint
;
this.Parallel = 0
.0f
;
}
/// <summary>
/// Constructs a new <see cref="BezierCurveCubic"/>.
/// </summary>
/// <param name="parallel">The parallel value.</param>
/// <param name="startAnchor">The start anchor point.</param>
/// <param name="endAnchor">The end anchor point.</param>
/// <param name="firstControlPoint">The first control point.</param>
/// <param name="secondControlPoint">The second control point.</param>
public BezierCurveCubic
(float parallel, Vector2 startAnchor, Vector2 endAnchor, Vector2 firstControlPoint, Vector2 secondControlPoint
)
{
this.Parallel = parallel
;
this.StartAnchor = startAnchor
;
this.EndAnchor = endAnchor
;
this.FirstControlPoint = firstControlPoint
;
this.SecondControlPoint = secondControlPoint
;
}
#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
)
{
Vector2 r
= new Vector2
();
float c
= 1
.0f
- t
;
r
.X = (StartAnchor
.X * c
* c
* c
) + (FirstControlPoint
.X * 3 * t
* c
* c
) + (SecondControlPoint
.X * 3 * t
* t
* c
)
+ EndAnchor
.X * t
* t
* t
;
r
.Y = (StartAnchor
.Y * c
* c
* c
) + (FirstControlPoint
.Y * 3 * t
* c
* c
) + (SecondControlPoint
.Y * 3 * t
* t
* c
)
+ EndAnchor
.Y * t
* t
* t
;
if (Parallel
== 0
.0f
)
return r
;
Vector2 perpendicular
= new Vector2
();
if (t
== 0
.0f
)
perpendicular
= FirstControlPoint
- StartAnchor
;
else
perpendicular
= r
- CalculatePointOfDerivative
(t
);
return r
+ Vector2
.Normalize(perpendicular
).PerpendicularRight * Parallel
;
}
/// <summary>
/// Calculates the point with the specified t of the derivative of this function.
/// </summary>
/// <param name="t">The t, value between 0.0f and 1.0f.</param>
/// <returns>Resulting point.</returns>
private Vector2 CalculatePointOfDerivative
(float t
)
{
Vector2 r
= new Vector2
();
float c
= 1
.0f
- t
;
r
.X = (c
* c
* StartAnchor
.X) + (2 * t
* c
* FirstControlPoint
.X) + (t
* t
* SecondControlPoint
.X);
r
.Y = (c
* c
* StartAnchor
.Y) + (2 * t
* c
* FirstControlPoint
.Y) + (t
* t
* SecondControlPoint
.Y);
return r
;
}
/// <summary>
/// Calculates the length of this bezier curve.
/// </summary>
/// <param name="precision">The precision.</param>
/// <returns>Length of the curve.</returns>
/// <remarks>The precision gets better when the <paramref name="precision"/>
/// value gets smaller.</remarks>
public float CalculateLength
(float precision
)
{
float length
= 0
.0f
;
Vector2 old
= CalculatePoint
(0
.0f
);
for (float i
= precision
; i
< (1
.0f
+ precision
); i
+= precision
)
{
Vector2 n
= CalculatePoint
(i
);
length
+= (n
- old
).Length;
old
= n
;
}
return length
;
}
#endregion
}
}