79 lines
2.0 KiB
C#
79 lines
2.0 KiB
C#
using UnityEngine;
|
|
|
|
public static class Bezier
|
|
{
|
|
public static Vector3 GetPoint(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
|
|
{
|
|
t = Mathf.Clamp01(t);
|
|
float num = 1f - t;
|
|
return num * num * num * p0 + 3f * num * num * t * p1 + 3f * num * t * t * p2 + t * t * t * p3;
|
|
}
|
|
|
|
public static Vector3 GetFirstDerivative(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
|
|
{
|
|
t = Mathf.Clamp01(t);
|
|
float num = 1f - t;
|
|
return 3f * num * num * (p1 - p0) + 6f * num * t * (p2 - p1) + 3f * t * t * (p3 - p2);
|
|
}
|
|
|
|
public static float GetTotalLenght(Vector3[] points)
|
|
{
|
|
float num = 0f;
|
|
for (int i = 0; i < points.Length - 3; i += 3)
|
|
{
|
|
if (points.Length >= 3)
|
|
{
|
|
num += BezierSingleLength(new Vector3[4]
|
|
{
|
|
points[i],
|
|
points[i + 1],
|
|
points[i + 2],
|
|
points[i + 3]
|
|
});
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
|
|
public static float BezierSingleLength(Vector3[] p)
|
|
{
|
|
Vector3 lhs = p[0] - p[1];
|
|
Vector3 vector = p[2] - p[1];
|
|
Vector3 vector2 = default(Vector3);
|
|
Vector3 rhs = p[3] - p[2];
|
|
float magnitude = lhs.magnitude;
|
|
float magnitude2 = vector.magnitude;
|
|
float magnitude3 = rhs.magnitude;
|
|
if (magnitude > 0f)
|
|
{
|
|
lhs /= magnitude;
|
|
}
|
|
if (magnitude2 > 0f)
|
|
{
|
|
vector /= magnitude2;
|
|
}
|
|
if (magnitude3 > 0f)
|
|
{
|
|
rhs /= magnitude3;
|
|
}
|
|
vector2 = -vector;
|
|
float num = Mathf.Abs(Vector3.Dot(lhs, vector)) + Mathf.Abs(Vector3.Dot(vector2, rhs));
|
|
if (num > 1.98f || magnitude + magnitude2 + magnitude3 < (4f - num) * 8f)
|
|
{
|
|
return magnitude + magnitude2 + magnitude3;
|
|
}
|
|
Vector3[] array = new Vector3[4];
|
|
Vector3[] array2 = new Vector3[4];
|
|
array[0] = p[0];
|
|
array[1] = (p[0] + p[1]) * 0.5f;
|
|
Vector3 vector3 = (p[1] + p[2]) * 0.5f;
|
|
array[2] = (array[1] + vector3) * 0.5f;
|
|
array2[3] = p[3];
|
|
array2[2] = (p[2] + p[3]) * 0.5f;
|
|
array2[1] = (array2[2] + vector3) * 0.5f;
|
|
array2[0] = (array2[1] + array[2]) * 0.5f;
|
|
array[3] = array2[0];
|
|
return BezierSingleLength(array) + BezierSingleLength(array2);
|
|
}
|
|
}
|