- Home /
Tangent for 5th order Bezier curve
I'm using Bezier curves for gameobject placement. Mostly it's enough to use cubic curve but in some cases I need more precision. I'm not strong in math, so I found 5th order equation in wiki and the curve looks fine. Now I just need set angles. Can anyone help me with tangent equation for 5th order Bezier curve? [1]:
//Cubic
public Vector3 GetPosition(float t)
{
return (1 - t) * (1 - t) * (1 - t) * _p0
+ 3 * (1 - t) * (1 - t) * t * _p1
+ 3 * (1 - t) * t * t * _p2
+ t * t * t * _p3;
}
public Vector3 GetTangent(float t)
{
float u = 1 - t;
float uu = u * u;
float tu = t * u;
float tt = t * t;
Vector3 P = _p0 * 3 * uu * (-1.0f);
P += _p1 * 3 * (uu - 2 * tu);
P += _p2 * 3 * (2 * tu - tt);
P += _p3 * 3 * tt;
return P.normalized;
}
//n5
public Vector3 GetPosition(float t)
{
float u = 1 - t;
float uu = u * u;
float uuu = uu * u;
float tt = t * t;
float ttt = t * tt;
Vector3 P = _p0 * uu * uuu;
P += _p1 * 5 * uu * uu * t;
P += _p2 * 10 * uuu * tt;
P += _p3 * 10 * ttt * uu;
P += _p4 * 5 * tt * tt * u;
P += _p5 * ttt * tt;
return P;
}
Answer by Bunny83 · May 26 at 03:58 PM
Since I like math I just derived the tangent function myself (actually two times in two different ways):
public Vector3 GetTangent(float t)
{
float u = 1f - t;
float uu = u * u;
float uuu = uu * u;
float tt = t * t;
float ttt = t * tt;
Vector3 T = _p0 * (uuu * u)
- _p1 * (uuu * (5 * t - 1))
+ _p2 * (2 * t * uu * (5 * t - 2))
- _p3 * (2 * tt * u * (5 * t - 3))
+ _p4 * (ttt * (5 * t - 4))
- _p5 * (ttt * t);
return T;
}
I have no time to test it, so feel free to try it out. Note I would recomment you also put brackets around your factors in your GetPosition method. Otherwise a lot performance would be wasted. A multiplication is carried out left to right by the compiler. So in your code you calculate _p0 * uu
which returns a new vector3 and then you multiply that result by uuu
. So those would be two Vector*float
multiplciations. When you group the float factors in brackets they are calculated first and you only do a single Vector - float multiplication per control point. So something like this:
public Vector3 GetPosition(float t)
{
float u = 1f - t;
float uu = u * u;
float uuu = uu * u;
float tt = t * t;
float ttt = t * tt;
Vector3 P = _p0 * (uu * uuu)
+ _p1 * (5 * u * uuu * t)
+ _p2 * (10 * uuu * tt)
+ _p3 * (10 * ttt * uu)
+ _p4 * (5 * t * ttt * u)
+ _p5 * (tt * ttt);
return P;
}
Thanks for the answer. Although it didn't worked for me as is and I had already found another solution, it still may be useful in future. I'll keep in mind vector/float multiplication order, thanks!
Answer by spirit_2 · May 26 at 09:48 AM
Suddenly it hit me
public Vector3 GetTangent(float t)
{
Vector3 p1 = GetPosition(t - 0.01f);
Vector3 p2 = GetPosition(t + 0.01f);
return (p2-p1).normalized;
}