У меня есть карта Евклидова выхода тороидального выхода. Это - поверхность, плоский, Евклидов прямоугольник, но когда точка переместится в правильную границу, это будет казаться на левой границе (в том же значении y), данным x_new = x_old ширина %
В основном точки напечатаны на основе: * посмотрите редактирование
(x_new, y_new) = ( x_old % width, y_old % height)
Думайте Человек Pac - уходить от одного края экрана заставит Вас появиться на противоположном краю.
Что лучший способ состоит в том, чтобы вычислить кратчайшее расстояние между двумя точками? Типичная реализация предлагает большое расстояние для точек на противоположных углах карты, когда в действительности, реальное перенесенное расстояние очень близко.
Лучшим способом я могу думать, вычисляет Классическую Delta X и Перенесенную Delta X, и Классическую Delta Y и Перенесенную Delta Y, и использует ниже каждой пары в формуле расстояния Sqrt(x^2+y^2).
Но это включило бы много проверок, вычислений, операций - некоторые, что я чувствую, могло бы быть ненужным.
Существует ли лучший путь?
править
Когда объект перемещается, он перемещается в положение (x_old, y_old), прокручивает его вышеупомянутая формула и хранилища (x_new, y_new) как ее положение. Вышеупомянутая формула была только добавлена для разъяснения то, что происходит, когда объекты преодолевают границу; в действительности, только один (x, y) пара хранится в каждом объекте за один раз.
Лучший способ, который я могу придумать, это вычисление классической дельты X и обернутой дельты X, классической дельты Y и обернутой дельты Y, и использование меньшего из каждой пары в формуле расстояния Sqrt(x^2+y^2).
Вот и все, я не думаю, что есть более быстрый способ. Но это не слишком сложное вычисление; вы можете сделать что-то вроде
dx = abs(x1 - x2);
if (dx > width/2)
dx = width - dx;
// again with x -> y and width -> height
(я надеюсь, вы сможете перевести это на ваш любимый язык)
Чтобы найти наименьшую дельту на оси a
для новых координат со значениями a1
и a2
, где ] aBoundary
- это граница на оси a
:
def delta(a1, a2, aBoundary):
return min(abs(a2 - a1), abs(a2 + aBoundary - a1))
Итак, если у вас есть две точки с новыми координатами x1, y1
и x2, y2
, вы можете просто сделать:
sumOfSquares(delta(x1,x2,width), delta(y1,y2,height))
Фактически это то, что вы предлагаете, но я бы не сказал, что это «много проверок, вычислений и операций».
(delta_x, delta_y)=
(min(width - abs(x_new - x_new), abs(x_new - x_old)),
min(height - abs(y_new - y_old), abs(y_new - y_old)))
Никакое расстояние не может быть больше, чем ширина/2 и высота/2. Если разница (X1-X2) больше ширины/2, вычтите ширину/2, чтобы получить короткое расстояние. Затем рассчитайте расстояние как обычно.
вы не можете использовать функцию «abs» с оператором мода!
xd =(x1-x2+Width)%Width
yd=(y1-y2+Height)%Height
D=sqrt(xd^2+yd^2)