2015-06-29 2 views
5

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

Позвольте мне бросить картину здесь для лучшего понимания проблемы: image of the problem

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

Сначала у меня было около 10 баллов, и я мог просто проверить каждую комбинацию, но, как вы уже можете предположить, это крайне неэффективно с увеличением количества очков. Что, если бы у меня было всего миллион очков, но все они были бы очень далеки друг от друга?

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

Если вы не знаете такого известного алгорима, все идеи приветствуются.

+1

Я не знаю, если это лучшая идея, но это лучше, чем ничего. Сохраните свое 2D-пространство в этой структуре: array (array (bool)), true, если есть точка, false, если нет. Поэтому, когда вы хотите найти точки в радиусе, вам не нужно оценивать всю матрицу, только позиции, находящиеся внутри радиуса –

+0

https://en.wikipedia.org/wiki/K-d_tree – amit

+0

@pablito. aven Это была одна из моих первых идей. Все еще не очень нравится идея проверки каждого пикселя вокруг вас. – Saraph

ответ

4

Вы по-прежнему придется повторять через каждую точку, но есть два оптимизаций вы можете выполнить:

1) Вы можете устранить очевидные моменты, проверяя, если x1 < радиус и если y1 < Радиус (как и Брент, уже упоминавшийся в другом ответе).

2) Вместо вычисления расстояния вы можете рассчитать квадрат расстояния и сравнить его с квадратом разрешенного радиуса. Это избавит вас от выполнения дорогостоящих вычислений с квадратным корнем.

Это, вероятно, лучшее качество, которое вы получите.

+0

Я думаю, что могу очень эффективно использовать оптимизацию номер 1, сохранив 2 кучи: один из них отсортирован по 'x' и по координате' y'. Когда точки перемещаются, вызов с помощью heapsort должен быть очень дешевым, учитывая, что эти координаты будут незначительно меняться на каждой итерации. Я вернусь (без цитаты из фильма), немного поиграв с этим. – Saraph

2

Если бы вы могли отсортировать эти точки по значениям x и y, вы могли бы быстро выбрать эти точки (бинарный поиск?), Которые находятся в ящике центральной точки: x + - r, y + - р. Когда у вас есть это подмножество точек, вы можете использовать формулу расстояния, чтобы увидеть, находятся ли они в радиусе.

+0

Практически говоря, этот подход может работать ... но что, если в этой коробке было миллион очков? Вы минимизируете количество баллов, которые вы должны проверить с помощью формулы расстояния, но нет никаких гарантированных ограничений или улучшений во время выполнения. – adao7000

+0

. Я не думаю, что есть способ сортировать коллекцию двухмерных точек, которая гарантирует, что каждая точка будет рядом со своими соседями. Например, если вы сортируете по x и затем используете y для таймерных прерываний, вы можете получить массив, подобный '[(0,0), (1, 999), (2,0)]'. (Я думаю, вы можете сортировать по эвклидовому расстоянию от контрольной точки, но затем вы вернетесь туда, где вы начали с O (n) времени выполнения). Таким образом, вы можете сузить свой поиск до точек с координатой x или координатой y, но не с обоими. – Kevin

+0

@Kevin у вас могут быть два индекса: один для 'x' и один для' y', а затем найдите пересечение обоих (как предложение JOIN в SQL). Даже если бы было миллион очков, это всего лишь несколько мегабайт памяти. –

7

Это проблема range searching. Более конкретно - 2-мерный круглый диапазон проблема.

Цитируя "Solving Query-Retrieval Problems by Compacting Voronoi Diagrams" [Aggarwal, Hansen, Leighton, 1990]:

  • Вход: Множество Р из п точек в плоскости E² евклидовой
  • Запрос: Найти все точки P, содержащихся в диске в E² с радиус r с центром в q.

Наилучшие результаты были получены в "Optimal Halfspace Range Reporting in Three Dimensions" [Afshani, Chan, 2009]. Их метод требует O (n) пространственной структуры данных, которая поддерживает запросы в O (log n + k) в худшем случае. Структура может быть предварительно обработана рандомизированным алгоритмом, который выполняется в ожидаемом времени O (n log n). (n - количество входных точек, k - количество выходных точек).

Библиотека CGAL поддерживает запросы поиска по круглому диапазону. См. here.

Смежные вопросы