Переместить объект по кривой Безье - PullRequest
10 голосов
/ 29 февраля 2012

Я хочу переместить свое изображение по кривой кривой Безье сверху вниз, но не могу понять, как я могу рассчитать точки х / у и наклон этой траектории.Путь выглядит следующим образом:

A line that curves slightly to the right as it goes down the page.

У меня есть начальные, конечные и две контрольные точки.

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); 

Ответы [ 6 ]

17 голосов
/ 02 марта 2012

Android дает вам API для достижения того, что вы хотите.Используйте класс с именем android.graphics.PathMeasure.Есть два метода, которые вы найдете полезными: getLength (), чтобы получить общую длину в пикселях пути, и getPosTan (), чтобы получить координаты X, Y точки на кривой на указанном расстоянии (а такжекасательная в этом месте.)

Например, если getLength () возвращает 200 и вы хотите узнать положение X, Y точки в середине кривой, вызовите getPosTan () с расстоянием = 100.

Дополнительная информация: http://developer.android.com/reference/android/graphics/PathMeasure.html

11 голосов
/ 09 марта 2012

Это кубическая кривая Безье, для которой формула просто [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
   }
}
7 голосов
/ 02 марта 2012

Чтобы найти точку на кривой Безье, вы можете использовать алгоритм Де Кастельжау.

См., Например, http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html или используйте Google, чтобы найти некоторые реализации.

4 голосов
/ 29 февраля 2012

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

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

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

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

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

3 голосов
/ 09 марта 2012

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

0 голосов
/ 21 июня 2016

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

...