Перемещение объекта по траектории кривой Безье

Я хочу переместить свое изображение на кривой кривой Безье сверху вниз, но я не могу понять, как я могу вычислить точки 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

Ответ 4

Если у вас есть только 2 контрольные точки, кривая Безье будет линейной.

Если у вас 3, у вас есть квадратичная кривая. 4 контрольных точки определяют кубическую кривую.

Кривые Безье - это функции, зависящие от "времени". Он идет от 0.0 до 1.0. Если вы введете 0 в уравнение, вы получите значение в начале кривой. Если вы введете 1.0, значение в конце.

Кривые Безье интерполируют первую и последнюю контрольные точки, поэтому это будут ваши начальные и конечные точки. Посмотрите внимательно, какой пакет или библиотеку вы используете для генерации кривой.

Чтобы сориентировать изображение с касательным вектором кривой, вы должны дифференцировать уравнение кривой (вы можете искать уравнение кривой кубического безье на вики). Это даст вам касательный вектор для ориентации вашего изображения.

Ответ 5

Обратите внимание, что изменение параметра в параметрической форме кубического безье не приводит к линейным результатам. Другими словами, установка t = 0,5 не дает вам точки, находящейся на полпути вдоль кривой. В зависимости от кривизны (которая определяется контрольными точками) на пути будут нелинейности.

Ответ 6

Для тех, кому нужно рассчитать статические значения точек кривой Безье Калькулятор кривой Безье является хорошим источником. Особенно, если вы используете четвертый квадрант (т.е. Между линией X и -Y). Затем вы можете полностью сопоставить его с системой координат Android, использующей mod на отрицательном значении.