Вычислить сплайзер безье для перехода от точки к точке

У меня есть 2 точки в X, Y + Вращение, и мне нужно вычислить сплайн Безье (набор квадратичных Безье), который плавно соединяет эти 2 точки. (см. рис.) Точка представляет собой юнит в игре, который может вращаться только медленно. Таким образом, чтобы добраться из пункта А в пункт Б, нужно пройти долгий путь. Прикрепленная картинка показывает довольно преувеличенно извилистый путь, но вы поняли идею.

alt text

Какие формулы я могу использовать для расчета такого сплайна Безье?

Ответ 1

Просто увидел, что я неправильно понял ваш вопрос. Не могли бы вы использовать один кубические гермитовые сплайны, так как у вас есть начальная и конечная точки и два направления (касательные)? Существуют ли дополнительные ограничения?

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

p0 = startpoint;
p1 = endpoint;
float scale = distance(p0, p1);
m0 = Vec2(cos(startangle), sin(startangle)) * scale;
m1 = Vec2(cos(endangle), sin(endangle)) * scale;

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

Ответ 2

Как вы, наверное, знаете, существуют бесконечные решения, даже если мы принимаем 2 контрольных точки.

Я нашел Алгоритм сглаживания с использованием кривых Безье, который отвечает на ваш вопрос (см. уравнения Bx(t) и By(t) в начале)

B x (t) = (1-t) 3 P 1x + 3 (1-t) 2 t P 2x + 3 (1-t) & tbsp; t 2 P 3x + t 3 P 4x

B y (t) = (1-t) 3 P 1y + 3 (1-t) 2 t P 2y + 3 (1-t) & tbsp; t 2 P 3y + t 3 P 4y

P 1 и P 4 - ваши конечные точки, а P 2 и P 3 - контрольные точки, которые вы можете выбрать по желаемым углам. Если ваша контрольная точка находится на расстоянии r вдоль угла & theta; из точки (x, y), координаты точки:

x '= x - r sin (& theta;)

y '= y - r cos (& theta;)

(в соответствии с системой координат, которую вы использовали, я думаю, что я правильно понял знаки). Единственный свободный параметр r, который вы можете выбрать по своему усмотрению. Вероятно, вы захотите использовать

r = & alpha; dist (P 1, P 4)

с & alpha; < 1.

Ответ 3

Я не помню, где я получил его, но я использовал это:

Vector2 CalculateBezierPoint(float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
{
      float u = 1 - t; 
      float tt = t*t;
      float uu = u*u;
      float uuu = uu * u;
      float ttt = tt * t;

      Vector2 p = uuu * p0; //first term
      p += 3 * uu * t * p1; //second term
      p += 3 * u * tt * p2; //third term
      p += ttt * p3; //fourth term

      return p;
}

где t - отношение вдоль пути между начальной и конечной точками.