Trouvez le point le plus proche le long d'un rectangle, étant donné un autre point et une autre direction

8

Étant donné un rectangle et un point avec une direction vectorielle vers le rectangle. Comment puis-je trouver le point le plus proche à l'extérieur de ce rectangle du point en question?

Rectangle orienté vers un point

onedayitwillmake
la source
Pouvez-vous expliquer davantage ce que vous demandez? Je ne comprends vraiment pas.
Disons que j'ai un personnage face à un objet (un rectangle), et je trace une ligne imaginaire de ce personnage au rectangle. Je voudrais savoir comment je peux dire quel point le long de l'extérieur de l'objet rectangulaire la ligne touche.
onedayitwillmake
1
Le mot-clé à rechercher dans Google est "AABB" (zone de délimitation alignée sur l'axe). Si votre "boîte" (rectangle) n'est pas encore alignée sur l'axe, une simple matrice de transformation - utilisée sur tous les éléments qui vous intéressent, évidemment - peut être utilisée en premier pour la transformer en une seule.
Martin Sojka

Réponses:

6

Une technique que vous pourriez utiliser est appelée "lancer de rayon". Il est couramment utilisé pour le rendu de graphiques, mais a d'autres applications telles que la visibilité directe (comme vous voulez le faire) et la recherche de chemin. En général, cela fonctionne en trouvant l'intersection d'un rayon et d'un objet. Dans votre exemple, le rayon est le vecteur de la direction du personnage.

Une référence utile pour les intersections rayon / objet (et accessoirement d'autres intersections objet / objet) est www.realtimerendering.com/intersections.html (regardez sous les références pour ray / aabb et ray / obb).

Luke Van In
la source
9

Le rectangle a quatre côtés. Chaque côté est un segment de ligne.

Testez chacun des quatre côtés pour l'intersection avec le rayon. Suivez le coup le plus proche.

Voici un code pour savoir où sur le segment le rayon frappe:

bool intersect(const ray& ray, const segment& segment,point& hit) {
    // where do we intersect this line?
    float t = ((ray.direction.x * ray.origin.y + ray.direction.y *
        (segment[0].x - ray.origin.x)) -
        (ray.direction.x * segment[1].y)) /
        (ray.direction.y * (segment[0].x + segment[1].x) -
        ray.direction.x * (segment[0].y + segment[1].y));
    if(t >= 0.0 && t<=1.0) { // in the segment
        hit = segment[0] + (segment[1]-segment[0]*t);  // lerp
        return true;
    }
    return false; // no hit
}
Volonté
la source
1

Si votre boîte est alignée sur l'axe, il vous suffit de fixer chaque axe de coordonnées à la boîte si le point est en dehors de la boîte.

De RTCD pg 130:

// Do this for all 3 axes
if( point.x < min.x )  point.x = min.x ;
else if( point.x > max.x )  point.x = max.x ;

Si vous faites cela pour les axes x, y, z, alors le pointsera claqué sur le mur le plus proche de la boîte, s'il est en dehors de la boîte pour commencer. s'il est déjà à l'intérieur de la boîte, il sera laissé seul (où il se trouve).

bobobobo
la source
0

Eh bien, vous pouvez utiliser uniquement l'algèbre linéaire (géométrie analytique, pour être plus précis) pour résoudre ce problème. Cela dépend de la façon dont vous avez modélisé le rectangle.

Voici un cas général: http://paulbourke.net/geometry/lineline2d/


la source