Вычисление расстояния между двумя координатами X, Y в PHP
Автор вопроса: UmopepisdnОтветов: 7
Я пишу инструмент для игры, которая включает в себя вычисление расстояния между двумя координатами на тороидальной плоскости 500 единиц в поперечнике. То есть от [0,0] до [499,499] являются допустимыми координатами, а [0,0] и [499,499] также находятся рядом друг с другом.
В настоящее время в моем приложении я сравниваю расстояние между городом с местоположением [X, Y] относительно собственного местоположения пользователя [X, Y], которое они настроили заранее.
Для этого я нашел такой алгоритм, который вроде работает:
Math.sqrt ( dx * dx + dy * dy );
Поскольку сортировка списка страниц по расстоянию полезна, я реализовал этот алгоритм в запросе MySQL и сделал его доступным для своего приложения, используя следующую часть моего оператора SELECT:
Хорошо, из ваших собственных комментариев кажется, что вы действительно имеете в виду тор - поверхность пончика - а не сферу. (Это большая разница, и вам следует отредактировать свой вопрос: называть его сферой неправильно.)
На это ответ довольно прост - приведенная вами декартова формула более или менее правильна. Однако вам нужно обернуть расстояния так, чтобы все, что больше или равно 250 = 500/2, было переведено в диапазон от 0 до 250.
Итак, ответ примерно такой (я вообще не знаю PHP, поэтому, возможно, его нужно изменить для синтаксиса)
(Это предполагает, что вы определили dx и dy как абсолютное значение разностей.)
Только что нашел эту процедуру, которая реализует тот же расчет в красиво упакованная функция.
Исходный ответ (сфера):
Вы не объяснили, как ваши координаты (x, y) сопоставляются с точками на сфере!
Существует (буквально) бесконечное количество вариантов, каждый из которых соответствует своей картографической проекции, и формула для каждого из них разная. Обратите внимание, что независимо от того, какой выбор вы сделаете, значение двух координат сильно различается.
Если ваши (x, y) действительно являются долготой и широтой, например, существует множество стандартных формул (например, гаверсинус), но вам придется сначала перевести 0-> 499 в 0-> 360 градусов для долготы и -90 ->90 градусов для широты. (Обратите внимание, что долгота и широта ведут себя на сфере совершенно по-разному!)
Но я подчеркиваю, что любой выбор, который вы сделаете, будет искажать плоскую геометрию, которую вы получите, если нанесете график в (x,y), по сравнению с тем, как он действительно выглядит на сфере.
(Наконец, если вы действительно имеете в виду, что верхний край такой же, как нижний, а правый такой же, как левый, то у вас, вероятно, тор, а не сфера!)
Ответ 2 · рейтинг 7 · Ishtar
Я предполагаю, что вы имеете в виду перенос координат и ничего сферического. Как плоский лист бумаги, концы которого волшебным образом соединены друг с другом.
Это означает, что для карты размером 500x500 расстояние в направлении x (или y) не превышает 250. (Если бы это было более 250 шагов, мы могли бы пройти 500-x шагов назад.)
Простым способом исправить это было бы
dx = Math.abs(dx);
dy = Math.abs(dy);
if (dx > 250)
dx = 500 - dx;
if (dy > 250)
dy = 500 - dy;
distance = Math.sqrt ( dx * dx + dy * dy );
Ответ 3 · рейтинг 1 · Agnius Vasiliauskas
Если вы знаете широту и долготу двух точек, вы можете использовать формулу гаверсина для вычисления расстояния между двумя точками на сфере.
Но, как я понял, вам нужна формула, точная для почти противоположных точек. Формула Хаверсина здесь не работает. В таком случае вам нужна формула Винсенти, которая точна даже в противоположных случаях.
Похоже, вы просто используете специальное конечное декартово пространство, которое "плиточное". В этом случае каждый объект не имеет уникальной позиции. Вместо (x, y) это (x + i*w, y + j*h) для всех возможных целых значений i и j, где w и h - ширина и высота вашего "окна" соответственно.
Очевидно, что тогда расстояние не уникально, а минимальное расстояние равно min(d(p1,p2))) по всем i, j.
Если ваши координаты завернуты, вам просто нужно вычислить их для i = -1,0,1 и j = -1,0,1, а затем взять наименьший.
Ответ 5 · duffymo
Этот общий алгоритм хорош для прямоугольных систем координат или очень точных расстояний в сферических координатах, но не подходит для сферической системы координат.
Я думаю, что лучший подход будет основан на широте и долготе, например:
http://jan.ucc.nau.edu/~cvm/latlongdist.html а>
В MySQL встроено геокодирование. Почему бы не использовать это?
Я пишу ответ, если две координаты находятся в двумерной плоскости, где концы не встречаются друг с другом, о чем ОП не спрашивал. Но это может помочь кому-то в будущем.
Если ваши точки находятся в двумерной плоскости, расстояние между точками (x1, y1) и (x2, y2) определяется теоремой Пифагора: