Расчет производной для сплайна из кривых Безье
Для определения длины сплайна (состоит из нескольких кривых Безье) нужно рассчитать определенный интеграл кривой в интервале [0, 1].
Пока нашел длину кривой Безье при помощи квадратур Гаусса. Это работает.
Проблема в корректном расчете первой производной сплайна в этом коде на С# (Unity):
public static Vector3 GetFirstDerivative(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
t = Mathf.Clamp01(t);
float oneMinusT = 1f - t;
return
3f * oneMinusT * oneMinusT * (p1 - p0) +
6f * oneMinusT * t * (p2 - p1) +
3f * t * t * (p3 - p2);
}
public Vector3 GetFirstDerivative(float t)
{
int i;
if (t >= 1f)
{
t = 1f;
i = points.Length - 4;
}
else
{
t = Mathf.Clamp01(t) * CurveCount;
i = (int)t;
t -= i;
i *= 3;
}
return transform.TransformPoint(Bezier.GetFirstDerivative(points[i], points[i + 1], points[i + 2], points[i + 3], t));
}
Наивно посоветовали умножить первую производную на CurveCount, но я считаю это неправильным.
Конечно можно сложить длины кривых сплайна L = L1+L2+... Тогда сплайн снова разбивается на кривые для расчета (нужен номер кривой для выбора 4-х её точек).
Вопрос: есть-ли другой способ или это единственный ?
Посмотрите, пожалуйста, на результат.
Производные для 2-х кривых Безье.
Код вывода:
public Vector3 GetFirst(float t, int num)
{
int i = 0;
// Начинаем с 0
i = num * 3;
return Bezier.GetFirstDerivative(points[i], points[i + 1], points[i + 2], points[i + 3], t);
}
static void First1(BezierSpline spline, int steps)
{
Vector3 start = spline.GetFirst(0, 0);
for (int i = 1; i <= steps; i++)
{
Vector3 here = spline.GetFirst((i / (float)steps), 0);
Handles.DrawLine(start, here);
start = here;
}
}
Ответы (1 шт):
Производная кубической кривой Безье - квадратичная кривая Безье с контрольными точками
D0 = 3*(P1-P0)
D1 = 3*(P2-P1)
D2 = 3*(P3-P2)
Подставляя нужное значение t в уравнение
D(t) = D0*(1-t)^2 + D1*2*t*(1-t) + D2*t^2
получим компоненты (два для плоской или три для 3D) вектора производной в точке с параметром t. Как я вижу, выражение совпадает с тем, что у вас в первой функции.
А вот чего делает вторая функция?
Если сплайн состоит из нескольких кривых - то для каждой кривой производную нужно считать отдельно, а как же иначе?
У вас есть, например, набор n+1 точек F0..Fn. Вы математически рассчитываете, например, интерполирующий сплайн, состоящий из кубических кривых Безье. Для каждого отрезка F[i] и F[i+1] являются конечными точками кривой Безье P[i]_0 и P[i]_3, и ещё рассчитаны две контрольные точки P[i]_1, P[i]_2 , диапазон каждой кривой 0..1. Диапазон всего сплайна не определён, для удобства в некоторых методах делают какую-то общую параметризацию (равномерную по номеру точки, или по длине ломаной), но я не уверен, что вам это нужно.
То, что вы пишете - равномерная параметризация по номеру точки.
Номер кривой i = (int) tобщ/(1/n), параметр внутри неё вроде такой: t = n*(tобщ - i/n)

