2010-11-12 3 views
2

J'ai travaillé sur un programme simple en C# dans lequel un Ball [X, Y] cordons est incrémenté périodiquement.2D Game Physics Vectors issue

J'ai réussi à implémenter une méthode de détection de collision, mais j'essaie de déterminer comment réfléchir la balle selon un angle oposé rebondissant le long du même chemin linéaire.

dx = -dx //This bounces the ball back along the same linear path 
dy = -dy 

Solution trigonométrie

theta = range between 0<theta<=360 depending on where it bounced 
x = cos(theta)*time 
y= sin(theta)*time 

Répondre

9

Le point entier de la physique newtonienne est qu'il est pas au hasard, il est déterministe. Si vous lancez la même balle contre le même mur au même angle et avec la même vélocité et le même essorage, il va au même endroit à chaque fois.

Ce genre de programme est une très bonne opportunité d'apprentissage pour la programmation et la physique. Ce que je vous encourage à faire est d'écrire d'abord un programme qui simule des rebonds très simples.Comme vous le constatez, lorsqu'un objet se déplace directement vers le bas et frappe une surface horizontale, vous pouvez modéliser le rebond en inversant simplement la composante de vélocité verticale. Juste ce qu'il faut; pas de gravité, pas de rien. C'est un bon début.

Ensuite, essayez d'ajouter rebondir sur les murs horizontaux, de la même manière.

Ensuite, essayez d'ajouter rebondir sur les murs qui sont pas aligné avec les directions horizontales ou verticales. C'est là que vous allez devoir apprendre comment fonctionnent les vecteurs et la trigonométrie, car vous devrez déterminer quel composant de la vélocité de la balle est modifié en frappant le mur obliquement.

Ajouter ensuite la gravité. Ensuite, ajoutez la friction de l'air. Puis ajoutez le fait que la balle peut tourner. Ajouter l'élasticité, de sorte que vous pouvez modéliser la déformation de la balle. Une fois arrivé à ce point, si vous voulez introduire un caractère aléatoire, vous serez capable de comprendre comment le faire. Par exemple, vous pouvez introduire un caractère aléatoire en disant "bien, quand la balle frappe le mur et se déforme, je vais introduire un élément aléatoire qui change sa déformation de 0-10%". Cela va alors changer la façon dont la simulation rebondit la balle. Vous pouvez expérimenter différents types d'aléas: ajouter des courants d'air aléatoires, par exemple.

2

Tant que c'est une boule parfaite avec une surface parfaite, il ne sera pas rebondir au hasard. Ni les vecteurs ni la trigonométrie ne vous donneront un caractère aléatoire.

+1

Non! La physique de base n'est tout simplement pas aléatoire. Vous avez besoin de la physique quantique pour cela. Ou simplement multiplier vos paramètres (angle de refelction) avec un coefficient aléatoire. ;) – AndreKR

+2

Bien que vrai, cela ne répond pas à la question. –

3

Vous devrez vous ajouter au hasard. Pour reformuler votre question: "Deterministically, il rebondit à l'angle theta Comment puis-je le faire rebondir à l'angle theta + epsilon, où epsilon est une valeur aléatoire?"

Pour faire pivoter un vecteur, voir this. Vous allez simplement spécifier thêta.

pseudocode:

RotateVector(vec): 
    bounce_vec = [-vec.x vec.y]; //deterministic answer is negative x, normal y 
    bounce_angle = acos(dot(vec,bounce_vec)/(norm(vec)*norm(bounce_vec))); 
    modified_angle = bounce_angle + random_number(); 
    ca = cos(modified_angle); 
    sa = sin(modified_angle); 
    rotation_matrix = [ca -sa; sa ca]; 
    return rotation_matrix * vec; 

Ligne 3 utilise le law of cosines pour déterminer l'angle. Dans la ligne 4, cet angle est modifié aléatoirement. Le reste de la fonction fait pivoter le vecteur d'origine par votre nouvel angle.

0

"au hasard, bien qu'appliquant aux lois fondamentales de la physique" semble être un oxymore. Mais ...

Si vous le voulez rebondir dans une direction aléatoire , tout en maintenant sa vitesse actuelle , vous pourriez faire quelque chose comme ça (pseudo-code):

  • premier, rebondir la chemin canonique (dx = -dx ou dy = -dy selon la collision)
  • puis convertir le dx et dy en coordonnées polaires (thêta et r)
  • thêta jitter par une petite quantité (+ ou - quelques degrés , selon votre goût)
  • assurez-vous que thêta ne se dirige pas dans un mur que vous venez de rebondissaient
  • convertir thêta et r Retour à dx et dy

Ce serait la conservation dynamique scalaire.

+2

P.S. Au lieu de convertir en coordonnées polaires, vous pouvez utiliser une matrice de rotation, comme l'a dit @Xodarap. Moins intuitif mais plus efficace. – LarsH