У меня есть 3 точки (A, B и X) и расстояние (d). Мне нужно сделать функцию, которая проверяет, находится ли точка X ближе, чем расстояние d к любой точке на отрезке AB.
Вопрос, во-первых, правильное ли мое решение, а затем найти лучшее (более быстрое) решение.
Мой первый проход выглядит следующим образом
AX = X-A
BX = X-B
AB = A-B
// closer than d to A (done squared to avoid needing to compute the sqrt in mag)
If d^2 > AX.mag^2 return true
// closer than d to B
If d^2 > BX.mag^2 return true
// "beyond" B
If (dot(BX,AB) < 0) return false
// "beyond" A
If (dot(AX,AB) > 0) return false
// find component of BX perpendicular to AB
Return (BX.mag)^2 - (dot(AB,BX)/AB.mag)^2 < d^2
Этот код будет выполняться для большого набора P и большого набора триплетов A / B / d с целью найти все P, которые проходят по крайней мере для одного A / B / d, поэтому я подозреваю, что это способ снизить общую стоимость, основанную на этом, но я еще не рассматривал это.
(Кстати: я знаю, что некоторые переупорядочения, некоторые временные значения и некоторые алгебраические тождества могут снизить стоимость вышеупомянутого. Я просто опущил их для ясности.)
РЕДАКТИРОВАТЬ: это двумерная проблема (но решение, которое обобщается на 3D, было бы круто
Редактировать: при дальнейшем осмыслении я ожидаю, что коэффициент попадания будет около 50% Точка X может быть сформирована во вложенной иерархии, поэтому я ожидаю, что смогу обрезать большие поддеревья как все проходные и все неудачные. A / B / d, ограничивающий триплеты, будет больше хитростью.
Редактировать: d в том же порядке, что и AB.
edit: Артелиус опубликовал хорошее решение. Я не уверен, что точно понимаю, к чему он клонит, когда я приступил к касательной, прежде чем полностью ее понял. В любом случае, в результате возникла другая мысль:
- Первый бит Артелиуса, предварительно рассчитать матрицу, в которой AB будет располагаться по центру в начале координат и выровнено по оси X. (2 добавления, 4 муль и 2 добавления)
- сложить все в 1-й квадрант (2 абс)
- масштаб в X & Y, чтобы сделать центральную часть зоны единым квадратом (2 мул)
- проверить, находится ли точка в этом квадрате (2 теста), так что выйти
- проверить заглушку (вернуться к немасштабированным значениям
- перевести в х, чтобы поместить конец в начало координат (1 добавление)
- квадрат и сложение (2 муль, 1 сложение)
- сравните с d ^ 2 (1 cmp)
Я вполне уверен, что это лучше моего решения.
(если ничего лучше не приходит, Артелиус получает «приз»)