2010-05-01 12 views
2

Disons que j'ai un cercle qui rebondit dans une zone rectangulaire. À un certain point, ce cercle va entrer en collision avec l'une des surfaces du rectangle et refléter. La façon habituelle de faire cela serait de laisser le cercle chevaucher cette limite et ensuite refléter le vecteur vitesse. Le fait que le cercle recouvre réellement la frontière n'est généralement pas un problème, ni vraiment perceptible à faible vitesse. À grande vitesse, il devient évident que le cercle fait quelque chose qu'il ne devrait pas faire.Calcul d'une collision pour un cercle mobile, sans chevauchement des limites

Ce que je voudrais faire est de prendre en compte la réflexion par programme et de placer le cercle à sa position appropriée avant de l'afficher sur l'écran. Cela signifie que je dois calculer le point où il atteint la limite entre sa position actuelle et sa position future - plutôt que de calculer sa nouvelle position et ensuite vérifier si elle a atteint la limite.

Ceci est un peu plus compliqué que le problème de collision cercle/rectangle habituel. J'ai une vague idée de la façon dont je devrais le faire - créer essentiellement un rectangle englobant entre la position actuelle et la nouvelle position, ce qui soulève une série de problèmes de sa part (Puisque le rectangle est tourné en fonction de la direction du cercle rapidité). Cependant, je pense que c'est un problème commun, et qu'une solution commune existe déjà.

Existe-t-il une solution commune à ce genre de problème? Peut-être quelques théories de base que je devrais examiner?

Répondre

5

Puisque vous avez juste un cercle et un rectangle, c'est en fait assez simple. Un cercle de rayon r qui rebondit à l'intérieur d'un rectangle de dimensions w, h peut être traité comme un point p au centre du cercle, à l'intérieur d'un rectangle (w-r), (h-r).

Maintenant, la mise à jour de position devient simple. Compte tenu de votre point à la position x, y et une vitesse par image de dx, dy, la position mise à jour est x+dx, y+dy - sauf lorsque vous traversez une limite. Si, par exemple, vous vous retrouvez avec x+dx > W (en laissant W = w-r), vous effectuez les opérations suivantes:

crossover = (x+dx) - W // this is how far "past" the edge your ball went 
x = W - crossover // so you bring it back the same amount on the correct side 
dx = -dx // and flip the velocity to the opposite direction 

Et même pour y. Vous devrez configurer un contrôle similaire (reflété) pour les limites opposées dans chaque dimension.

+0

Wow, je pensais vraiment à ça. –

0

À chaque étape, vous pouvez calculer la position prévue/prévue du cercle pour la trame suivante. Si cela se trouve en dehors du rectangle, vous pouvez alors utiliser la distance entre l'ancienne position du cercle et le bord du rectangle et le dépassement du bord du rectangle auquel la position suivante est située (interpénétration) pour interpoler linéairement et déterminer l'heure exacte à laquelle le cercle "frappe" le bord du rectangle. Par exemple, si le cercle est à 10 pixels du bord du rectangle, alors il est prévu qu'il passe à 5 pixels au-delà, vous savez que pour les 2/3 du pas de temps (10/15ème) il se déplace sur son origine chemin, puis se reflète et continue sur son nouveau chemin pour le tiers restant du temps (5/15s). En calculant ces deux parties du mouvement et en "ajoutant" les traductions ensemble, vous pouvez trouver la nouvelle position correcte.

(Bien sûr, cela devient plus compliqué si vous frappez près d'un angle, car il peut y avoir plusieurs collisions pendant le pas de temps, sur des bords différents et si vous avez plus d'un cercle, les choses deviennent beaucoup plus complexes. Mais c'est là que vous pouvez commencer pour le cas que vous avez demandé à propos de)

0

La réflexion sur une limite rectangulaire est incroyablement simple. Prenez juste la quantité que l'objet a passé la limite et soustrayez-la de la position de limite. Si la position sans réflexion serait (-0,8, -0,2) par exemple et le coin supérieur gauche est à (0,0), la position réfléchie serait (0,8,0.2).