Я думаю, что эту проблему лучше всего решить с помощью серии преобразований координат. Для простоты обозначений предположим, что у вас есть две точки: u и v.
Предположим, что вы работаете в действительно простом случае - точки u и v находятся в точках (1, 0) и (-1, 0), соответственно, а длина большой оси в эллипсе равна 1. Тогда вы просто прослеживаете полукруг. Предполагая, что вы хотите интерполировать между точками с постоянной скоростью, вы можете использовать эту формулу:
x(t) = cos(pi * t)
y(t) = sin(pi * t)
Конечно, вам не обязательно повезло, что вы находитесь в этой настройке, и поэтому мы можем выполнить серию преобразований координат, чтобы привести вас в эту конфигурацию. Для начала давайте определим точку w как точку на полпути между u = (x0, y0) и v = (x1, y1). То есть:
w = (x2, y2) = ((x0 + x1) / 2, (y0 + y1) / 2)
Теперь предположим, что вы перевели u и v так, что w находится в начале координат. Это означает, что u и v равноудалены от начала координат вдоль противоположных векторов. Если мы используем матрицы и однородные координаты, то вы можете представить это как
| 1 0 -x2 |
T = | 0 1 -y2 |
| 0 0 1 |
Позиции u и v после этого перевода задаются Tu
и Tv
. Давайте назовем эти точки u 'и v'. Они даны
u' = (x0 - x2, x1 - y2) = (x0 / 2 - x1 / 2, y0 / 2 - y1 / 2)
v' = (x1 - x2, y1 - y2) = (x1 / 2 - x0 / 2, y1 / 2 - y0 / 2)
Теперь мы ближе к решению исходной задачи, но у нас есть проблема, заключающаяся в том, что u 'и v' не очень хорошо выровнены по оси x, как это было в исходной задаче. Чтобы исправить это, мы применим преобразование вращения так, что u 'заканчивается в (1, 0), а v' заканчивается в (0, 1). Чтобы сделать это, мы хотим установить систему координат, в которой один из базовых векторов находится в направлении u ', а другой - в направлении, перпендикулярном к нему. Для этого мы выберем наши единичные векторы следующим образом:
e0 = u' / ||u||
e1 = perp(e0)
Где perp
- некоторый единичный вектор, перпендикулярный e0
. Один из способов получить это - сказать, что если e0 = (x3, y3)
, то e1 = perp(e0) = (-y3, x3)
. Вы можете проверить, что этот вектор перпендикулярен (x3, y3)
, так как их скалярное произведение равно нулю.
Учитывая эти векторы, мы можем определить преобразование, которое будет отображать (1, 0) в e0
и (0, 1) в e1
на
|x3 -y3 0|
|y3 x3 0|
| 0 0 1|
(последний столбец для однородной системы координат)
Конечно, это противоположность того, что мы хотим - мы пытаемся отобразить с e0
на (1, 0) и с e1
на (0, 1). Чтобы получить эту матрицу, мы просто инвертируем вышеуказанную матрицу. К счастью, поскольку мы выбрали e0
и e1
как ортонормированные, вышеуказанная матрица является ортогональной, поэтому ее обратная сторона является транспонированной:
| x3 y3 0|
R = |-y3 x3 0|
| 0 0 1|
Теперь, если мы применим R
к u'
и v'
, мы получим векторы (1, 0) и (-1, 0), что мы и хотим, чтобы они были. Проблема в том, что эллипс, который мы хотим отследить, не обязательно имеет высоту блока. Например, если мы назовем его высоту h
, то мы будем отслеживать эллиптический путь с большой полуосью h
и полуминорной осью 1
. Но это легко исправить с помощью другого преобразования координат, на этот раз масштабируя высоту системы кородината с коэффициентом 1 / h
, так что высота эллипса, который мы хотим отследить, равна 1. Это можно сделать с помощью следующей матрицы масштабирования:
| 1 0 0 |
S = | 0 1/h 0 |
| 0 0 1 |
Причина, по которой эта установка полезна, состоит в том, что мы знаем, что если мы возьмем любую точку на желаемом эллипсе между u
и v
, а затем применим к ней матрицу SRT
, то мы в итоге преобразуем ее использовать соответствующую точку на единичной окружности, которая является путем от (1, 0) до (-1, 0). Что еще более важно, тем не менее, это работает наоборот. Если мы применим обратное из SRT
к любой точке на круге единицы, мы в конечном итоге получим соответствующую точку на исходном эллиптическом пути между u
и v
! Чтобы заключить сделку, мы знаем, как найти точки на пути от (1, 0) до (-1, 0), и поэтому у нас есть алгоритм для решения этой проблемы:
- В течение заданного времени
t
найдите точку, в которой вы бы находились на круге юнита, если бы вы двигались от (1, 0) к (-1, 0) в момент времени t
. Назовите это p
.
- Вычислить p '= (SRT) -1 p.
p'
- это точка, которую вы ищете.
Вопрос в том, что такое (СТО) -1 . К счастью, у нас есть (SRT) -1 = T -1 R -1 S -1 и все эти матрицы может быть легко вычислено:
| 1 0 -x2 | | 1 0 x2 |
T = | 0 1 -y2 | T^-1 = | 0 1 y2 |
| 0 0 1 | | 0 0 1 |
| x3 y3 0| | x3 -y3 0 |
R = |-y3 x3 0| R^-1 = | y3 x3 0 |
| 0 0 1| | 0 0 1 |
| 1 0 0 | | 1 0 0 |
S = | 0 1/h 0 | S^-1 = | 0 h 0 |
| 0 0 1 | | 0 0 1 |
Короче говоря, окончательный алгоритм выглядит следующим образом:
- Учитывая u = (x0, y0) и v = (x1, y1), пусть w = (x2, y2) = ((x0 + x1) / 2, (y0 + y1) / 2).
- Пусть u '= u / || u || = (x3, y3).
- В момент времени t (для 0 & le; t & le; 1) пусть p = (cos (& pi; t), sin (& pi; t))
- Вычислить p '= S -1 p = (cos (& pi; t), h sin (& pi; t))
- Вычислить p '' = R -1 p '= (x3 cos (& pi; t) - y3 sin (& pi; t), y3 cos (& pi; t) + x3 sin (& pi; т))
- Вычислить p '' '= T -1 p' '= (x3 cos (& pi; t) - y3 sin (& pi; t) + x2, y3 cos (& pi; t) + x3 грех (& pi; t) + y2)
- Выведите p '' 'в качестве вашей точки.
Извините, если это много математики, но ваш ответ должен (надеюсь!) Дать вышеописанную процедуру.