Проверка, находится ли точка внутри или снаружи полукруга (или прямоугольника в этом отношении), является операцией постоянного времени.
Проверка N точек лежит внутри или снаружи полукруга или прямоугольника O (N).
Сортировка ваших N баллов O (N * LG (N)).
Асимптотически быстрее последовательно проверять все точки, чем сортировать, а затем быстро отбирать точки на основе двоичного поиска.
Это может быть один из тех случаев, когда то, что кажется быстрым, и то, что быстро, - это две разные вещи.
EDIT
Существует также очень простой способ проверить наличие точки в полукруге, не разбираясь с поворотами, преобразованиями и т. П.
Представляет полукруг как две составляющие:
- отрезок прямой от точки a до b , представляющий диаметр полукруга
- ориентация либо слева от или справа от , указывающая, что полукруг находится либо слева, либо справа от отрезка ab , когда путешествие от a до b
Вы можете использовать правило правой руки, чтобы определить, находится ли точка внутри полукруга.
Затем некоторый псевдокод для проверки, находится ли точка p в полукруге, как:
procedure bool is_inside:
radius = distance(a,b)/2
center_pt = (a+b)/2
vec1 = b - center_pt
vec2 = p - center_pt
prod = cross_product(vec1,vec2)
if orientation == 'left-of'
return prod.z >= 0 && distance(center_pt,p) <= radius
else
return prod.z <= 0 && distance(center_pt,p) <= radius
Этот метод имеет дополнительное преимущество, заключающееся в том, что не используются никакие триггерные функции, и вы можете исключить все квадратные корни, сравнивая их с квадратом расстояния. Вы также можете ускорить его, кэшируя вычисление 'vec1', вычисление радиуса, вычисление center_pt и переупорядочивая пару операций для раннего освобождения. Но я пытался понять это.
'cross_product' возвращает значение (x, y, z). Он проверяет, является ли z-компонент положительным или отрицательным. Это также можно ускорить, если не использовать истинное перекрестное произведение и только рассчитать z-компонент.