Я просто потратил некоторое время на то, чтобы разобраться с описанием алгоритма Wikipedia , и придумал следующую реализацию Python, которая может помочь: https://gist.github.com/863301
Первый этап closest_point
- это простой поиск в глубину, чтобы найти наилучший подходящий листовой узел.
Вместо того, чтобы просто возвращать лучший узел, найденный в стеке вызовов, на втором этапе проверяется, не может ли быть более близкий узел на стороне «выезда»: (художественная схема ASCII)
n current node
b | best match so far
| p | point we're looking for
|< >| | error
|< >| distance to "away" side
|< | >| error "sphere" extends to "away" side
| x possible better match on the "away" side
Текущий узел n
разделяет пробел вдоль линии, поэтому нам нужно смотреть на сторону «вдали» только в том случае, если «ошибка» между точкой p
и наилучшим соответствием b
больше, чем расстояние от точки p
до линии n
. Если это так, то мы проверяем, есть ли какие-либо точки на стороне «подальше», которые находятся ближе.
Поскольку наш лучший соответствующий узел передан во второй тест, он не должен выполнять полный обход ветви и остановится довольно быстро, если он находится на неправильном пути (только направляясь вниз по «близким» дочерним узлам до это ударяет лист.)
Чтобы вычислить расстояние между точкой p
и линией, разделяющей пространство через узел n
, мы можем просто «спроецировать» точку вниз на ось, скопировав соответствующую координату, поскольку все оси ортогональны ( горизонтальный или вертикальный).