calcul de la distance entre un point et une boîte rectangulaire (le point le plus proche)
est là une formule simple pour calculer cela? j'ai travaillé sur certains des maths mais je ne peux que trouver une façon de calculer la distance dirigé vers le centre de la zone, qui n'est pas dirigé vers le point le plus proche.. sont là quelques ressources sur ce problème?
- Est la zone de l'axe aligné? les références à des solutions pour l'AABB et OBB sont ici
Vous devez vous connecter pour publier un commentaire.
Ici est une formule unique qui permet d'éviter tous les cas de la logique. (J'arrive de travailler en JS, donc voici un JS de mise en œuvre). Laissez
rect = {max:{x:_, y:_}, min:{x:_, y:_}}
etp={x:_, y:_}
Explication:
Cette décompose le problème dans le calcul de la distance x
dx
et y la distancedy
. Il utilise ensuite la formule de la distance.Pour le calcul de
dx
, voici comment cela fonctionne. (dy
est analogue)Regarder le tuple fourni à la fonction max:
(min-p, 0, p-max)
. Nous allons désigner ce n-uplet(a,b,c)
.Si p est à gauche de min, puis nous avons du p < mn < max, ce qui signifie que le tuple permettra d'évaluer à
(+,0,-)
, et donc la fonction max renvoie correctementa = min - p
.Si p est compris entre min et max, puis nous avons min < p < max, ce qui signifie que le tuple permettra d'évaluer à
(-,0,-)
. Encore une fois, la fonction max renvoie correctementb = 0
.Enfin, si p est à la droite de max, puis nous avons, min < max < p et le n-uplet évalue à
(-,0,+)
. Une fois de plus, les Maths.max retourne correctementc = p - max
.Ainsi, il s'avère tous les cas, la logique est pris en charge par les Mathématiques.max, ce qui conduit à une belle 3-ligne, de flux de contrôle-fonction libre.
Math.max
. Je crois même généralise à la 3D par le simple ajout d'un analoguedz
composant.Je pense que vous avez besoin d'analyser des cas; il n'y a pas de formule unique. Il est plus facile d'illustrer en deux dimensions:
Les bords de la boîte (étendu) de diviser l'extérieur dans 9 régions. La région de 0 (à l'intérieur de la boîte) est résolu par le calcul de la distance de chaque bord et de prendre le minimum. Chaque point dans la région 1 est la plus proche du vertex de gauche, et de même pour les régions 3, 6, et 8. Pour les régions 2, 4, 5, et 7, vous devez trouver la distance du point le plus proche du bord, ce qui est assez simple problème. Vous pouvez déterminer la région d'un point est dans en le classifiant à l'égard de chaque bord. (Il est plus facile de voir comment faire cela en dirigeant les bords dire, dans le sens antihoraire.) Cela permettra également de vous dire si le point est à l'intérieur de la boîte.
En 3D, la logique est exactement la même sauf que vous classer à l'égard des six faces et vous avez plus de cas.
Le problème est plus simple si les bords de la boîte sont parallèles aux axes de coordonnées.
Disons que le point est nommé
P
etABCD
est notre rectangle. Ensuite, le problème peut être décomposé en un ensemble de sous-problèmes:(1) Développer une fonction
dist(P, AB)
qui calcule la distance entre un pointP
et arbitraire segmentAB
.(2) Calculer les quatre distances entre votre point de
P
et de chaque côté du rectangle (de chaque côté est un segment) et de prendre le plus court des quatreC'est votre réponse.
Maintenant, nous avons besoin de savoir comment calculer la distance entre le point
P
et l'arbitraire d'un segmentAB
, c'est à dire comment calculerdist(P, AB)
. Cela se fait comme suit(1) Effectuer une projection du point
P
à la ligneAB
. Vous obtenez le nouveau pointP'
surAB
.(2) Si
P'
se situe entreA
etB
, puisdist(P, AB)
est la distance entreP
etP'
.(3) Sinon,
dist(P, AB)
est la distance entreP
et soitA
ouB
, selon la période la plus courte.Que c'est. Il y a bien des façons d'optimiser la procédure, mais même si sa mise en œuvre littéralement, il fonctionne très bien déjà.
P. S. bien sûr, on peut se demander comment effectuer une projection d'un point à la ligne. Je le laisse en exercice au lecteur 🙂
Kikito la réponse n'est pas correcte, en fait, si P est dans les régions 2, 4, 5 ou 7 de Ted Hopp du régime, il retourne la distance minimum entre les sommets, ce qui est différent (plus grand) de la distance minimale à partir des bords.
Je voudrais corriger kikito de la fonction distance_aux en renvoyant 0 au lieu de min(p - bas, haut - p), et tout fonctionne à part le 0 de la région où P est à l'intérieur de la boîte.
À mon avis, que la région doit être géré séparément, en fonction de ce que vous voulez atteindre, si la distance de la zone ou de la distance à partir du périmètre de la zone.
Si vous souhaitez obtenir la distance de la zone de la boîte, je dirais qu'elle est égale à zéro lorsque le point est à l'intérieur de la boîte.
Légèrement optimisé C# alternative (bien qu'il devrait probablement avoir une certaine tolérance lorsque l'on compare les doubles contre 0). Je recommande également la création d'une sorte de Rect ou Point des méthodes d'extension pour ces.
Pour AABBs:
Peut-être pas le meilleur, mais certainement la méthode la plus simple:
p = votre point de
c = centre du cube
s = la moitié de la taille du cube
r = le point nous sommes à la recherche pour
J'ai été la recherche de ce et je pense avoir une solution, pour le cas où la case est axis-aligned (un cas habituel)
Je crois que dans ce cas, vous pouvez calculer la distance comme ceci:
Cela peut être étendu à z, bien sûr.
C'est facile à réaliser avec point des produits. En fait, il a été répondu en 3d déjà pour le non de l'axe aligné cas.
https://stackoverflow.com/a/44824522/158285
Mais en 2D, vous pouvez atteindre le même
La fonction de renvoyer le point le plus proche de
Est-ce une boîte 3D ou 2D rectangle?
de toute façon, vous êtes probablement mieux de se la point de ligne de (pour la 2D) ou point-plan (3D) de la distance de chaque côté, puis en sélectionnant au minimum.Edit: il y a une bien meilleure façon décrite ici (dernier post). Il s'agit de transformer vos coordonnées d'un point dans l'espace, puis "saturer" les coordonnées avec la taille de la boîte pour trouver le point sur la boîte la plus proche du point. Je n'ai pas essayé, mais il regarde à droite pour moi.