Число очков количества в кругу быстро

  • Resharper (Согласовывают его, сосет Вас, должны заплатить дополнительный для получения этого, но хорошо работать деньги)
  • GhostDoc (Устраняет любое оправдание за то, что не имелись комментарии в коде)

  • PowerCommands для VS 2008 (Забыл, что мне даже установили это, потому что это просто добавляет небольшие вещи, которые должны были быть там все время)

10
задан Community 3 April 2017 в 23:35
поделиться

5 ответов

Создайте структуру пространственного подразделения, такую ​​как квадродерево или KD-дерево точек. В каждом узле храните количество точек, покрытых этим узлом. Затем, когда вам нужно подсчитать точки, охватываемые кругом поиска, обойдите дерево и для каждого подразделения в узле проверьте, полностью ли оно находится за пределами круга, затем проигнорируйте его, если оно полностью внутри круга, добавьте его счет к всего, если он пересекается с кругом, рекурсивно, когда вы доберетесь до листа, проверьте точку (точки) внутри листа на предмет сдерживания.

Это все еще O (n) худший случай (например, если все точки лежат на периметр круга), но средний случай - O (log (n)).

13
ответ дан 3 December 2019 в 16:53
поделиться

MBO's ответ отлично работает, но иногда мне легче использовать параметр «очень волшебный» \ v , поэтому мне не нужно избегать всего; делает регулярное выражение более читабельным.

См. также:

8
ответ дан 3 December 2019 в 16:53
поделиться

Предположим, у вас есть набор точек S в декартовой плоскости с координатами (x i , y i ), заданной произвольной окружностью с центром (x c , y c ) и радиус r вы хотите найти все точки, содержащиеся в этом круге.

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

На ум приходят три вещи, которые могут это ускорить:

Во-первых, вы можете проверить:

(xi-xc)^2 + (yi-yc)^2 <= r^2

вместо

sqrt((xi-xc)^2 + (yi-yc)^2) <= r

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

  • x i находится в диапазоне [x c -r, x c + r]; и
  • y i находится в диапазоне [y c -r, y c + r]; и

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

Наконец, отсортируйте свои точки в порядке x или y, а затем вы можете выполнить поиск пополам чтобы найти набор точек, которые, возможно, находятся в пределах вашего ограничивающего прямоугольника, дополнительно сокращая ненужные проверки.

1
ответ дан 3 December 2019 в 16:53
поделиться

в зависимости от того, сколько времени на предварительное вычисление у вас есть, вы можете построить такое дерево:

ветви первого узла - это значения x, ниже это узлы значения y, а под ними узлы значения радиуса. на каждом листе находится хэш-набор точек.

Если вы хотите вычислить точки в x, y, r: пройдите по дереву и спуститесь по ветви, которая соответствует вашим ближайшим значениям x, y. когда вы спускаетесь на корневой уровень, вам нужно сделать небольшое совпадение (постоянное время), но вы можете найти такой радиус, чтобы все точки в этом круге (определяемом путем в дереве) находились внутри указанного круга на x, y, r и другой круг (тот же x_tree, y_tree в дереве, как и раньше, но другое r_tree), так что все точки в исходном круге (заданном как x, y, r) находятся в этом круге.

оттуда пройдитесь по всем точкам в большем из два древовидных круга: если точка находится в меньшем круге, добавьте ее к результатам, если нет, запустите проверку расстояния на ней.

Единственная проблема в том, что предварительное вычисление дерева занимает очень много времени. хотя вы можете указать количество времени, которое хотите потратить, изменив количество ветвей x, y и r, которое вы хотите иметь в своем дереве.

запустите на нем проверку расстояния.

Единственная проблема в том, что предварительное вычисление дерева занимает очень много времени. хотя вы можете указать количество времени, которое хотите потратить, изменив количество ветвей x, y и r, которое вы хотите иметь в своем дереве.

запустите проверку расстояния

. Единственная проблема в том, что предварительное вычисление дерева занимает очень много времени. хотя вы можете указать количество времени, которое хотите потратить, изменив количество ветвей x, y и r, которое вы хотите иметь в своем дереве.

0
ответ дан 3 December 2019 в 16:53
поделиться

Если моя цель - скорость, а количество точек не было огромным (миллионы), я бы сосредоточился на объеме памяти не меньше, чем на алгоритмической сложности.

Несбалансированное дерево kd - это лучше всего на бумаге, но для этого требуются указатели, которые могут увеличить объем памяти в 3 раза +, поэтому его нет.

Сбалансированное дерево kd не требует хранилища, кроме массива с одним скаляром для каждой точки. Но у него тоже есть недостаток: скаляры нельзя квантовать - они должны быть теми же 32-битными числами с плавающей запятой, что и в исходных точках. Если они квантованы, больше невозможно гарантировать, что точка, которая появляется раньше в массиве, находится либо на плоскости разделения, либо слева от нее, И что точка, которая появляется позже в массиве, находится либо на плоскости разделения, либо справа.

Я разработал структуру данных, которая решает эту проблему. Специалисты по синергетике говорят нам, что объем экспериментально четырехсторонний. Предположим, что плоскость также является трехсторонней.

Мы привыкли пересекать плоскость в четырех направлениях -x, + x, -y и + y, но проще использовать три направления a, b и c, которые указывают на вершины равностороннего треугольника.

При построении сбалансированного дерева kd спроецируйте каждую точку на оси a, b и c. Сортируйте точки, увеличивая a. Для средней точки округлите в меньшую сторону, квантовайте и сохраните. Затем для подмассивов слева и справа от медианы отсортируйте, увеличивая b, а для средних точек округлите вниз, квантуйте и сохраните b. Повторяйте и повторяйте, пока каждая точка не сохранит значение.

Затем, проверяя круг (или что-то еще) на структуре, сначала вычислите максимальные координаты a, b и c круга. Это описывает треугольник. В структуре данных, которую мы создали в предыдущем абзаце, сравните координату средней точки с координатой максимума круга. Если точка a больше круга a, мы можем дисквалифицировать все точки после медианы. Затем для подмассивов слева и справа (если они не дисквалифицированы) от медианы, сравните b круга с координатой b медианной точки. Повторяйте и повторяйте до тех пор, пока не останется больше точек для посещения.

Это похоже на структуру данных BIH , но не требует интервалов -x и + x, -y и + y, потому что a, b и c так же хорошо пересекают плоскость, и для этого требуется на одно направление меньше.

Это описывает треугольник. В структуре данных, которую мы создали в последнем абзаце, сравните координату средней точки с максимальной координатой круга. Если точка a больше круга a, мы можем дисквалифицировать все точки после медианы. Затем для подмассивов слева и справа (если они не дисквалифицированы) от медианы, сравните b круга с координатой b медианной точки. Повторяйте и повторяйте до тех пор, пока не останется больше точек для посещения.

Это похоже на структуру данных BIH , но не требует интервалов -x и + x, -y и + y, потому что a, b и c так же хорошо пересекают плоскость, и для этого требуется на одно направление меньше.

Это описывает треугольник. В структуре данных, которую мы создали в последнем абзаце, сравните координату средней точки с максимальной координатой круга. Если точка a больше круга a, мы можем дисквалифицировать все точки после медианы. Затем для подмассивов слева и справа (если они не дисквалифицированы) от медианы, сравните b круга с координатой b медианной точки. Повторяйте и повторяйте до тех пор, пока не останется больше точек для посещения.

Это похоже на структуру данных BIH , но не требует интервалов -x и + x, -y и + y, потому что a, b и c так же хороши для пересечения плоскости, и для этого требуется на одно направление меньше.

координата sa до максимума круга координата. Если точка a больше круга a, мы можем дисквалифицировать все точки после медианы. Затем для подмассивов слева и справа (если они не дисквалифицированы) от медианы, сравните b окружности с координатой b медианной точки. Повторяйте и повторяйте до тех пор, пока не останется больше точек для посещения.

Это похоже на структуру данных BIH , но не требует интервалов -x и + x, -y и + y, потому что a, b и c так же хорошо пересекают плоскость, и для этого требуется на одно направление меньше.

координата sa до максимума круга координата. Если точка a больше круга a, мы можем дисквалифицировать все точки после медианы. Затем для подмассивов слева и справа (если они не дисквалифицированы) от медианы, сравните b окружности с координатой b медианной точки. Повторяйте и повторяйте до тех пор, пока не останется больше точек для посещения.

Это похоже на структуру данных BIH , но не требует интервалов -x и + x, -y и + y, потому что a, b и c так же хороши для пересечения плоскости, и для этого требуется на одно направление меньше.

sb к координате b средней точки. Повторяйте и повторяйте до тех пор, пока не останется больше точек для посещения.

Это похоже на структуру данных BIH , но не требует интервалов -x и + x, -y и + y, потому что a, b и c так же хороши для пересечения плоскости, и для этого требуется на одно направление меньше.

sb к координате b средней точки. Повторяйте и повторяйте до тех пор, пока не останется больше точек для посещения.

Это похоже на структуру данных BIH , но не требует интервалов -x и + x, -y и + y, потому что a, b и c так же хороши для пересечения плоскости, и для этого требуется на одно направление меньше.

2
ответ дан 3 December 2019 в 16:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: