Dans l'un de mes projets, j'ai une zone de jeu en forme de cercle. À l'intérieur de ce cercle, un autre petit cercle se déplace. Ce que je veux faire, c'est empêcher le petit cercle de sortir du plus grand. Ci-dessous, vous pouvez voir que dans le cadre 2, le petit cercle est partiellement à l'extérieur, j'ai besoin d'un moyen de le ramener juste avant qu'il ne se déplace vers l'extérieur. Comment cela peut-il être fait?
De plus, j'ai besoin du point de collision le long de l'arc du grand cercle pour pouvoir mettre à jour la vitesse du petit cercle. Comment procéder pour calculer ce point?
Ce que je voudrais faire, c'est avant de déplacer le petit cercle, je prédis sa position suivante et s'il est à l'extérieur je trouve le temps de collision entre t = 0 et t = 1 (t = 1 pas à temps plein). Si j'ai le temps de collision t, je déplace simplement le petit cercle pendant t au lieu d'un pas à temps plein. Mais encore une fois, le problème est que je ne sais pas comment détecter à ce moment-là la collision se produit quand il s'agit de deux cercles et l'un à l'intérieur de l'autre.
ÉDITER:
Exemple de point de collision (vert) que je veux trouver. Peut-être que l'image est un peu décalée mais vous avez l'idée.
la source
B
, etk=0
. Maintenant, si c'est la résolution de collision que vous voulez, je n'ai pas couvert cela dans ma réponse car cela nécessiterait des connaissances sur les propriétés physiques des objets. Que doit-il arriver? Le cercle intérieur doit-il rebondir à l'intérieur? Ou rouler? Balayage?V
, faites avancer le cercle intérieur leV*t
long de la circonférence duR-r
cercle. Cela signifie une rotation desV*t/(R-r)
radians angulaires autour du pointA
. Et le vecteur vitesse peut être tourné de la même manière. Pas besoin de connaître la normale (qui est toujours orientée vers le centre du cercle de toute façon) ou de mettre à jour la vitesse d'une autre manière.Disons que le grand cercle est le cercle A et le petit cercle est le cercle B.
Vérifiez si B est à l'intérieur de A:
Si dans l'image
n-1
B était à l'intérieur de A et dans l'imagen
B est à l'extérieur de A et le temps entre les images n'était pas trop grand (aka B ne se déplaçait pas trop vite), nous pouvons approximer le point de collision en trouvant simplement les coordonnées cartésiennes de B par rapport à A:Nous pouvons ensuite convertir ces points en un angle:
Si vous voulez savoir plus exactement à quoi
t
B se trouve en dehors de A pour la première fois, vous pouvez faire une intersection cercle-rayon à chaque image, puis comparer si la distance entre B et le point de collision est plus grande que la distance que B peut parcourir étant donné que c'est vitesse actuelle. Si c'est le cas, vous pouvez calculer l'heure exacte de la collision.la source
Soit (Xa, Ya) la position du grand cercle et son rayon R, et (Xb, Yb) la position du petit cercle et son rayon r.
Vous pouvez vérifier si ces deux cercles entrent en collision si
Pour connaître la position de la collision, recherchez le moment exact où les cercles entrent en collision, en utilisant une recherche binaire mais avec un nombre fixe d'étapes. Selon la façon dont votre jeu est fait, vous pouvez optimiser cette partie du code (j'ai fourni cette solution pour être indépendante du comportement de la petite balle. Si elle a une accélération constante ou une vitesse constante, cette partie du code peut être optimisée et remplacé par une formule simple).
Une fois que vous connaissez le temps de collision, calculez les positions des deux cercles au moment final et le point de collision final est
la source
J'ai implémenté une démo d'une balle rebondissant dans un cercle sur jsfiddle en utilisant l'algorithme décrit par Sam Hocevar :
http://jsfiddle.net/klenwell/3ZdXf/
Voici le javascript qui identifie le point de contact:
la source