Je fais une partie dans laquelle les balles rebondissent autour des à l'intérieur em> d'un cercle beaucoup plus grand. Le plus grand cercle ne bouge pas. Voici le code que je suis actuellement en train d'utiliser pour ces collisions: p> Il est basé sur le merveilleux tutoriel de Peter Collingridge < a href = "http://www.petercollingridge.co.uk/pygame-physics-simulation/collisions" rel = "noreferrer"> ici . p> Les objets du cercle et de la balle sont Les deux classes, avec (x, y), rayon, angle et vitesse. p> J'ai deux problèmes avec cette méthode, cependant: P> Ayant examiné des solutions possibles déjà ici, notamment "Détection de collision de cercle rapide" [Lien supprimé en raison de la limite de liaison de spam], qui, bien que, bien que dans Java utilise la même méthode, ils traitent tous des collisions externes , alors que je cherche à rebondir une balle autour de l'intérieur d'un cercle. P> Voici aussi les définitions de la classe de la balle () et du cercle (): p> Merci d'avance, Nathan P> P>
3 Réponses :
La plupart des packages graphiques utilisent en haut à gauche comme Démarrer pour le code de dessin. Vous voulez très probablement 2 ensembles de coordonnées, celui qui vous collisez / bouge / etc. avec et celui pour dessiner (X-rayon, Y-rayon). P>
En outre, sans avoir réfléchi à cela trop, la vérification de l'intersection soit-elle Distance + Ball.Size> = Cercle.Size code>? La distance des balles du centre plus son rayon devrait être inférieure au rayon du cercle, si j'ai bien compris la configuration correctement. P>
Sans répondre à votre question, j'aimerais commenter votre stratégie de mise en œuvre et recommander une nouvelle approche. Vous représentez la vitesse de la balle en forme de coordonnée polaire, comme Je pense que cela va être généralement gênant pour vous. Par exemple, dans votre code de collision, vous finissez par appeler Je recommande également de changer votre approche de physique d'un statique em> one ("est un objet un élément en collision actuellement avec l'objet B?") à un dynamique em> un ("obtiendra un entrer en collision avec l'objet B lors de son prochain mouvement de mouvement? "). Dans un système de physique statique, vous vous retrouvez souvent avec des objets se croisant à la fin d'une étape de mouvement, puis vous devez comprendre le meilleur moyen de les amener à se séparer à nouveau, ce qui est difficile à obtenir. P>
Si vous faites les deux, il est simple de rebondir le ballon sans aucune trigonométrie. P>
Étape 1. Transformez la collision de cercle / de cercle en collision Point / Circle en utilisant Minkowski Addition : p>
p>
Étape 2. Considérez un segment de temps dans lequel la balle commence à Étape 3. Trouvez le point de collision p>
Voir cette réponse pour savoir comment calculer le nouveau chemin de la balle basée sur des coefficients de frottement et de restitution. p>
Étape 4. N'oubliez pas que la balle peut encore avoir une certaine distance pour se déplacer le long du nouveau vecteur ball.ange.angle code> et
ball.speed code>. P>.
ATAN2 code> pour activer le vecteur (
dx code>,
dy code>) dans un angle, puis vous appelez.
sin code> et
cos code> pour retourner l'angle dans un vecteur à nouveau. (En outre, si vous essayez jamais de généraliser votre code à trois dimensions, vous vous retrouverez dans un monde de douleur.) Donc, à moins que vous n'ayez des exigences particulières nécessitant des coordonnées polaires, je vous recommande de faire ce que tout le monde fait, à savoir représentant La vitesse de la balle dans les coordonnées cartésiennes comme vecteur (
vx code>,
vy code>). p>
Bien que ce n'était pas ce que je cherchais, merci des tas! J'y regarde.
Je suis content que vous ayez aimé mon tutoriel. J'aime votre variation, il devrait réellement être plus simple.
Premièrement, je pense que vous avez besoin de modifier le test de collision vers: p> parce que la taille de la balle plus grande, le La distance entre son centre et le centre du cercle peut être plus petite. Cela devrait faire rebondir les balles au bon endroit (à l'intérieur du cercle). P> Puis je pense que vous devez simplement échanger les signes des x et y et tout devrait fonctionner. P> overlap = math.hypot(dx, dy) - (circle.size - ball.size)
if overlap >= 0:
tangent = math.atan2(dy, dx)
ball.angle = 2 * tangent - ball.angle
ball.speed *= elasticity
angle = 0.5 * math.pi + tangent
ball.x += math.sin(angle)*overlap
ball.y -= math.cos(angle)*overlap
L'axe X ne serait-il pas défini par le cosinus de l'angle et de l'axe des Y par le sinus? Ou j'ai appris faux? :X
Je pense que vous avez raison que c'est la façon standard de définir des choses, mais aussi longtemps que vous êtes cohérent, cela ne fait aucune différence. Clairement, si vous faites pivoter tout de 90 degrés, cela ne devrait pas affecter comment les choses rebondissent (en supposant que la gravité change également).
@Petercollingridge, vos articles sont incroyable i>! Solutions élégantes, style pythonique, félicitations .. et merci!
@Petercollingridge: Au fait, je pense avoir repéré une erreur de physique dans votre article: Si une balle se heurte à une stationnaire (pas de gravité, de glisser et d'élasticité = 1), votre simulation finira toujours par kiking l'autre balle et faire de la première balle stationnaire. Dans la physique correcte qui ne se produira que si c'est une collision sur i> la collision (vélocité et la normale de contact sont parallèles)