Tengo 3 puntos (A, B y X) y una distancia (d). Necesito hacer una función que pruebe si el punto X está más cerca que la distancia d a cualquier punto en el segmento de línea AB.predicado proximidad geométrica rápida
La pregunta es, en primer lugar, si mi solución es correcta y luego encontrar una solución mejor (más rápida).
Mi primer paso es el siguiente
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
Este código va a terminar siendo el funcionamiento para una amplia serie de P y un gran conjunto de/B/trillizos D A con la intención de encontrar que pase de P para al menos un A/B/d, así que sospecho que hay una manera de reducir el costo total basado en eso, pero aún no lo he investigado.
(Por cierto:. Soy consciente de que algunos reordenamiento, algunos valores temporales y algunas identidades algebraicas podría disminuir el costo de los anteriores sólo les omitido para mayor claridad.)
EDIT: se trata de una Problema 2D (pero la solución que se generaliza a 3D sería genial
Editar: En una reflexión más profunda, espero que la tasa de aciertos sea de alrededor del 50%. El punto X se puede formar en una jerarquía anidada, así que espero poder para podar los grandes subárboles como todo pasa y todo falla. El A/B/d que limita a los trillizos será más de un tr ick.
Edición: d está en el mismo orden de magnitud que AB.
editar: Artelius ha publicado una buena solución. No estoy seguro de entender exactamente a qué se está enfrentando ya que me bajé en una tangente antes de entenderlo por completo. De todos modos, otro pensamiento vino a mi mente como resultado:
- Primera pieza de Artelius, precablea una matriz que colocará AB centrada en el origen y alineada con el eje X. (2 añade, 4 mul y 2 añade)
- veces todo en la primera cuadrante (2 abs)
- escala en X & Y para hacer que la porción central de la zona en un cuadrado de la unidad (2 mul)
- prueba si el punto está en que cuadrada (2 test) está así que deja de
- prueba de la tapa del extremo (volver a los valores sin escala
- traducen en x para colocar el extremo en el origen (1 add)
- cuadrado y agregar (2 mul, 1 agregar)
- comparan con d^2 (1 cmp)
Estoy bastante seguro de que esto es mucho mejor que mi solución.
(si nada mejor viene sone Artelius recibe el "premio" :)
FWIW el lenguaje de implementación es D :) (tu/eres/ese bengi smith ¿no?) – BCS