Add cubic bezier functions.
This commit is contained in:
44
Assets/Cryville/Common/Math/CubicBezier.cs
Normal file
44
Assets/Cryville/Common/Math/CubicBezier.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using SMath = System.Math;
|
||||
|
||||
namespace Cryville.Common.Math {
|
||||
// Ported from https://github.com/arian/cubic-bezier/blob/master/index.js
|
||||
public static class CubicBezier {
|
||||
public static float Evaluate(float t, float x1, float y1, float x2, float y2, float epsilon) {
|
||||
float x = t, t0, t1, t2, tx, d2, i;
|
||||
for (t2 = x, i = 0; i < 8; i++) {
|
||||
tx = CurveX(t2, x1, x2) - x;
|
||||
if (SMath.Abs(tx) < epsilon) return CurveY(t2, y1, y2);
|
||||
d2 = DerivativeCurveX(t2, x1, x2);
|
||||
if (SMath.Abs(d2) < 1e-6) break;
|
||||
t2 -= tx / d2;
|
||||
}
|
||||
|
||||
t0 = 0; t1 = 1; t2 = x;
|
||||
|
||||
if (t2 < t0) return CurveY(t0, y1, y2);
|
||||
if (t2 > t1) return CurveY(t1, y1, y2);
|
||||
|
||||
while (t0 < t1) {
|
||||
tx = CurveX(t2, x1, x2);
|
||||
if (SMath.Abs(tx - x) < epsilon) return CurveY(t2, y1, y2);
|
||||
if (x > tx) t0 = t2;
|
||||
else t1 = t2;
|
||||
t2 = (t1 - t0) * .5f + t0;
|
||||
}
|
||||
|
||||
return CurveY(t2, y1, y2);
|
||||
}
|
||||
static float CurveX(float t, float x1, float x2) {
|
||||
float v = 1 - t;
|
||||
return 3 * v * v * t * x1 + 3 * v * t * t * x2 + t * t * t;
|
||||
}
|
||||
static float CurveY(float t, float y1, float y2) {
|
||||
float v = 1 - t;
|
||||
return 3 * v * v * t * y1 + 3 * v * t * t * y2 + t * t * t;
|
||||
}
|
||||
static float DerivativeCurveX(float t, float x1, float x2) {
|
||||
float v = 1 - t;
|
||||
return 3 * (2 * (t - 1) * t + v * v) * x1 + 3 * (-t * t * t + 2 * v * t) * x2;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user