Jackyzgood
Messages postés26Date d'inscriptionmercredi 17 septembre 2008StatutMembreDernière intervention 6 mars 2010
-
25 oct. 2009 à 13:22
Jackyzgood
Messages postés26Date d'inscriptionmercredi 17 septembre 2008StatutMembreDernière intervention 6 mars 2010
-
6 nov. 2009 à 12:14
Bonjour à tous !
J'essaye actuellement de créer une fonction qui me gère des trajectoires simple dans un champ de pesanteur avec rebond. Mon problème ne vient pas de la physique, j'ai déjà fait une trajectoire en pré-calculé, aucun soucis.
while(continuer)
{
Objet.temps = SDL_GetTicks();
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
gestion_des_evenements (&event, &Evenements, &continuer);
SDL_BlitSurface(marqueur, NULL, ecran, &(Objet.position_affichage));
SDL_Flip(ecran);
//limitation du nombre de boucle dans le temps
if(SDL_GetTicks() - Objet.temps < 20)
{SDL_Delay(20 -(SDL_GetTicks() - Objet.temps));}
//comme le nombre de boucle est limite on est sur que delta_T ne sera pas nul
Objet.delta_T = SDL_GetTicks() - Objet.temps;
//Par definition a = dV/dt <=> a * dt = dV
Objet.delta_vitesse.y = Objet.acceleration.y * Objet.delta_T;
//la vitesse sera la somme des variations de vitesse
Objet.vitesse.y += Objet.delta_vitesse.y;
/*par definition V = dOM/dt, ou OM est la position de l'objet M par rapport a l'origine O.
on en deduit : dOM = v * dt */
Objet.delta_position.y = Objet.vitesse.y * Objet.delta_T;
//la position sera la somme des variations de position
Objet.position_affichage.y += Objet.delta_position.y;
/*gestion d'une collision elastique avec le bas de l'ecran :
si l'objet sort de l'ecran (par le bas) alors on lui
donne une vitesse oppose ce qui genere le rebond.*/
if(Objet.position_affichage.y > ecran->h -50)
{Objet.vitesse.y = -Objet.vitesse.y;}
}
Voila ma boucle principale, le soucis avec cette boucle c'est que l'objet rebondit plus haut qu'il ne devrait... et je ne vois pas d'où ça peut venir. Si quelqu'un vois ou est mon erreur.
cs_daddou24
Messages postés1Date d'inscriptionsamedi 17 octobre 2009StatutMembreDernière intervention25 octobre 2009 25 oct. 2009 à 18:47
Bonjour,
Essaye une méthode d'intégration plus précise comme l'algorithme de verlet (voir wikipedia), et puis mettre un petit coef (genre 0.9) qui réduit la vitesse de ton mobile aprés un choc.
Bon courage,
Damien.
Jackyzgood
Messages postés26Date d'inscriptionmercredi 17 septembre 2008StatutMembreDernière intervention 6 mars 2010 25 oct. 2009 à 22:57
Merci à toi pour ta réponse. J'ai cherché l'algorithme de Verlet et il y à quelques passage que j'ai pas compris, notamment sur l'ajout des termes de degrés 2.
Comme vous pouvez le voir sur cette vidéo, quelques rares points arrivent à traverser lignes avec lesquelles ils rentrent en collision.
Pour gérer les collisions, je chronomètre la boucle principale, je calcule la position suivante et crée 2 vecteurs, avec les 2 points et une extrémité d'une droite. Ensuite je regarde les angles entre la droite et le vecteur position, puis avec le vecteur position suivante. S'il y a changement de signe c'est que le point va traverser la droite, c'est à ce moment là que je déclenche la collision.
Voila la fonction qui gère les collision, je ne vois pas ou j'ai pu commettre une erreur et pourquoi certain point arrive a se faufiler entre les conditions.
#include "structures.h"
int fonction_collision(struct structure_objet_physique *Objet, struct Structure_geometrique_ligne Ligne)
{
//creation du vecteur représantant la ligne
struct Structure_geometrie_vecteur Vecteur_ligne;
Vecteur_ligne.x = 0;
Vecteur_ligne.y = 0;
fonction_coordonnees_vecteur(&Vecteur_ligne, Ligne.x[0], Ligne.y[0], Ligne.x[1], Ligne.y[1]);
//création du vecteur position par rapport a la ligne
struct Structure_geometrie_vecteur Vecteur_position_relative;
Vecteur_position_relative.x = 0;
Vecteur_position_relative.y = 0;
fonction_coordonnees_vecteur(&Vecteur_position_relative, Ligne.x[0], Ligne.y[0], (*Objet).Vecteur_position.x, (*Objet).Vecteur_position.y);
//calcul de la position suivante
struct Structure_geometrie_vecteur Vecteur_position_relative_suivante;
Vecteur_position_relative_suivante.x = 0;
Vecteur_position_relative_suivante.y = 0;
fonction_coordonnees_vecteur(&Vecteur_position_relative_suivante, Ligne.x[0], Ligne.y[0], (*Objet).Vecteur_position_suivante.x, (*Objet).Vecteur_position_suivante.y);
//calcul de la difference de position
struct Structure_geometrie_vecteur Vecteur_delta_position;
Vecteur_delta_position.x = 0;
Vecteur_delta_position.y = 0;
fonction_coordonnees_vecteur(&Vecteur_delta_position, (*Objet).Vecteur_position.x, (*Objet).Vecteur_position.y, (*Objet).Vecteur_position_suivante.x, (*Objet).Vecteur_position_suivante.y);
//calcul de l'angle entre les vecteurs
double angle_initial = fonction_angle_entre_vecteur(&Vecteur_ligne, &Vecteur_position_relative),
angle_final = fonction_angle_entre_vecteur(&Vecteur_ligne, &Vecteur_position_relative_suivante),
angle_delta_position = fonction_angle_entre_vecteur(&Vecteur_ligne, &Vecteur_delta_position);
if( ((angle_initial > 0 && angle_final < 0) || (angle_initial < 0 && angle_final > 0))
&& fonction_produit_scalaire(&Vecteur_ligne, &Vecteur_position_relative) > 0
&& fonction_produit_scalaire(&Vecteur_ligne, &Vecteur_position_relative) < fonction_norme_vecteur(&Vecteur_ligne) * fonction_norme_vecteur(&Vecteur_ligne))
{
(*Objet).Vecteur_position_initiale.x = (*Objet).Vecteur_position.x;
(*Objet).Vecteur_position_initiale.y = (*Objet).Vecteur_position.y;
(*Objet).Vecteur_vitesse_initiale.x = 0.7*(*Objet).Vecteur_vitesse.x;
(*Objet).Vecteur_vitesse_initiale.y = 0.7*(*Objet).Vecteur_vitesse.y;
fonction_rotation_vecteur(&((*Objet).Vecteur_vitesse_initiale), (-2*angle_delta_position));
(*Objet).temps_initial = SDL_GetTicks();
return 1;
}
else {return 0;}
}