Перемещение объекта по траектории кривой Безье
Я хочу переместить свое изображение на кривой кривой Безье сверху вниз, но я не могу понять, как я могу вычислить точки x/y и наклон от этого пути. Путь выглядит следующим образом:
![enter image description here]()
У меня есть начальные точки, конечные точки и две контрольные точки.
Path path = new Path();
Point s = new Point(150, 5);
Point cp1 = new Point(140, 125);
Point cp2 = new Point(145, 150);
Point e = new Point(200, 250);
path.moveTo(s.x, s.y);
path.cubicTo(cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y);
Ответы
Ответ 1
Это кубическая кривая Безье, для которой формула просто [x,y]=(1–t)^3*P0+3(1–t)^2*t*P1+3(1–t)t^2*P2+t^3*P3
. С этим вы можете решить для каждой точки путем вычисления уравнения. В Java это можно сделать следующим образом:
/* t is time(value of 0.0f-1.0f; 0 is the start 1 is the end) */
Point CalculateBezierPoint(float t, Point s, Point c1, Point c2, Point e)
{
float u = 1 – t;
float tt = t*t;
float uu = u*u;
float uuu = uu * u;
float ttt = tt * t;
Point p = new Point(s.x * uuu, s.y * uuu);
p.x += 3 * uu * t * c1.x;
p.y += 3 * uu * t * c1.y;
p.x += 3 * u * tt * c2.x;
p.y += 3 * u * tt * c2.y;
p.x += ttt * e.x;
p.y += ttt * e.y;
return p;
}
Итак, если вы хотите переместить спрайт вдоль пути, вы просто установите значение t из значения 0 - 1 в зависимости от того, насколько далеко по пути вы хотите. Пример:
int percentMovedPerFrame = 1;// Will complete path in 100 frames
int currentPercent = 0;
update() {
if (currentPercent < 100) {
this.pos = CalculateBezierPoint(currentPercent / 100.0f, this.path.s, this.path.c1, this.path.c2, this.path.e);
currentPercent += percentMovedPerFrame
}
}
Ответ 2
Android дает вам API для выполнения того, что вы хотите. Используйте класс под названием android.graphics.PathMeasure. Есть два метода, которые вы найдете полезными: getLength(), чтобы получить общую длину в пикселях пути и getPosTan(), чтобы получить положение X, Y точки на кривой на определенном расстоянии (а также касательная в этом месте.)
Например, если getLength() возвращает 200 и вы хотите знать положение X, Y точки в середине кривой, вызовите getPosTan() с расстоянием = 100.
Дополнительная информация: http://developer.android.com/reference/android/graphics/PathMeasure.html
Ответ 3
Чтобы найти точку на кривой Безье, вы можете использовать алгоритм Де Кастеляу.
См. например http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html или используйте Google, чтобы найти некоторые реализации.
Ответ 4
Если у вас есть только 2 контрольные точки, кривая Безье будет линейной.
Если у вас 3, у вас есть квадратичная кривая. 4 контрольных точки определяют кубическую кривую.
Кривые Безье - это функции, зависящие от "времени". Он идет от 0.0 до 1.0. Если вы введете 0 в уравнение, вы получите значение в начале кривой. Если вы введете 1.0, значение в конце.
Кривые Безье интерполируют первую и последнюю контрольные точки, поэтому это будут ваши начальные и конечные точки. Посмотрите внимательно, какой пакет или библиотеку вы используете для генерации кривой.
Чтобы сориентировать изображение с касательным вектором кривой, вы должны дифференцировать уравнение кривой (вы можете искать уравнение кривой кубического безье на вики). Это даст вам касательный вектор для ориентации вашего изображения.
Ответ 5
Обратите внимание, что изменение параметра в параметрической форме кубического безье не приводит к линейным результатам. Другими словами, установка t = 0,5 не дает вам точки, находящейся на полпути вдоль кривой. В зависимости от кривизны (которая определяется контрольными точками) на пути будут нелинейности.
Ответ 6
Для тех, кому нужно рассчитать статические значения точек кривой Безье Калькулятор кривой Безье является хорошим источником. Особенно, если вы используете четвертый квадрант (т.е. Между линией X и -Y). Затем вы можете полностью сопоставить его с системой координат Android, использующей mod на отрицательном значении.