[C] Calculer la Normale d'un vecteur en C

Calculer la Normale d'un vecteur en C [C] - C - Programmation

Marsh Posté le 11-11-2013 à 00:37:52    

Hello tout le monde !

 

En fait je doit rendre un projet de prog en C pour Mardi, et je suis bloqué, depuis le début (il y a une semaine), sur un sujet :
le rebond d'un tir de tank sur un mur, en 2 dimensions.

 

Le tir doit rebondir une unique fois puis disparaître à la collision suivante à un mur ( ou tank ennemi ).
Codes:
Je vais vous épargner en ne pas vous crachant tout mon code en un instant, de ce fait, voici les parties les plus intéressantes de mon code :

 

• Les déclarations :

 
Code :
  1. typedef struct typePOINT point_new;
  2. struct typePOINT//structure de création de points (coordonnées X et Y)
  3. {
  4. double x;
  5. double y;
  6. double centre_x;
  7. double centre_y;
  8. double relat_x;
  9. double relat_y;
  10. };
  11. typedef struct typeVECTEUR vecteur_new;
  12. struct typeVECTEUR//structure de création de vecteurs (coordonnées X et Y)
  13. {
  14. double x;
  15. double y;
  16. };
  17. typedef struct typeTIR tir_new;
  18. struct typeTIR//structure de création de tirs
  19. {
  20. int exists;//booléen renseignant l'existance du boulet (boulet-un?)
  21. double x;//coord x du tir
  22. double y;//coord y du tir
  23. vecteur_new look;//vecteur look du tir
  24. int nb_rebonds;//nombre de rebonds du tir
  25. creapVector2f vect2f_center;//coords du centre du tir, renseigné par coords x et y
  26. creamShapePtr shape_tir ;//shape du tir (cercle)
  27. };
  
Code :
  1. vecteur_new look_Joueur, look_Joueur_old;//vecteur look_Joueur : direction visée  ;  vecteur old_look_Joueur : ancienne direction (valeur intermédiaire anti_bug)
  2. point_new StartPt={iScreen_Width/4.0,iScreen_Height/4.0};
  3. //NORMALES DES MURS
  4. vecteur_new Normale;//Normale à utiliser pour le rebond des tirs - vaudra un des quatre vecteurs suivants)
  5. vecteur_new Normale_haut;
  6. vecteur_new Normale_gauche;
  7. vecteur_new Normale_bas;
  8. vecteur_new Normale_droite;
  9. point_new form_Joueur_init[9] = // ( coordonnées graphique)
  10. {
  11. {StartPt.x,StartPt.y},{StartPt.x+15,StartPt.y},{StartPt.x+15,StartPt.y-30},{StartPt.x+25,StartPt.y-30},
  12. {StartPt.x+25,StartPt.y},{StartPt.x+40,StartPt.y},{StartPt.x+40,StartPt.y+40},{StartPt.x,StartPt.y+40},{StartPt.x,StartPt.y}
  13. };
  14. point_new form_Joueur_image[9], form_Joueur_relat[9];
  15. point_new ptsCentre_Joueur = {(form_Joueur_init[0].x + form_Joueur_init[5].x)/2 ,(form_Joueur_init[0].y + form_Joueur_init[7].y)/2};
  16. point_new ptsCentre_Joueur_temp;
  17. creamColor white = creamColor_Create(255,255,255,255); //couleur tank : BLANC
  18. creamColor green = creamColor_Create(0,255,0,255); //couleur tank : VERT
  19. creamColor red = creamColor_Create(255,0,0,255); //couleur tank : ROUGE
  20. creamColor Coul_Tank;//variable contenant la couleur du tank courant
  21. tir_new tab_Tirs_Joueur[20]={0};//max autorisé de tirs pour le joueur
  22. tir_new tab_Tirs_Ennemis[20]={0};//max autorisé de tirs pour les ennemis
  

En précisant que je code en C sous CREAM, le moteur de mon école :
- creamShapePtr pour les variable servant de shapes pour relier des points et ainsi créer des formes.
- creapVector2f pour les variables servant de vecteurs (2f pour 2D)
Mes tirs sont sphériques, crée par une fonction de CREAM tout simplement.
Les tirs sont déplacés et la collision gérée par leurs centres respectifs.

 

• Puis l'initialisation :

 
Code :
  1. creamWindow_SetWindowResolution(50,100,8);//ne fonctionne pas ??
  2. Coul_Tank = red;
  3. y_max = creamWindow_GetNativResolution().getY();
  4. look_Joueur.x = look_Joueur.y = 0;
  5. for (i=0; i<9; i++)
  6. {
  7. form_Joueur_image[i] = form_Joueur_init[i]; // affectation : coord courantes = coord initiales (initialisation)
  8. }
  9. for(i=0;i<20;i++)
  10. {
  11. tab_Tirs_Joueur[i].exists=FALSE;
  12. }
  13. iVitesse_Tir=4;
  


• Enfin le code-cible (où je calcule les rebonds)

 
Code :
  1. //TRANSLATION DES TIRS JOUEUR (avec COLLISIONS, REBONDS)
  2. for(i=0;i<20;i++)
  3. {
  4. if(tab_Tirs_Joueur[i].exists==TRUE)//uniquement pour les boulets existants
  5. {
  6. if (!((tab_Tirs_Joueur[i].x + iVitesse_Tir*tab_Tirs_Joueur[i].look.x < iScreen_Width) && (tab_Tirs_Joueur[i].x + iVitesse_Tir*tab_Tirs_Joueur[i].look.x > 0)
  7. && (tab_Tirs_Joueur[i].y + iVitesse_Tir*tab_Tirs_Joueur[i].look.y < iScreen_Height) && (tab_Tirs_Joueur[i].y + iVitesse_Tir*tab_Tirs_Joueur[i].look.y > 0)))
  8. {//si tir sort de la map
  9. if(tab_Tirs_Joueur[i].nb_rebonds==0)//si pas encore de rebond
  10. {
  11. //CALCUL DES NORMALES
  12. Normale_haut.x=tab_Tirs_Joueur[i].x;
  13. Normale_haut.y=tab_Tirs_Joueur[i].y-iVitesse_Tir;
  14. Normale_bas.x=tab_Tirs_Joueur[i].x;
  15. Normale_bas.y=tab_Tirs_Joueur[i].y-iVitesse_Tir;
  16. Normale_gauche.x=tab_Tirs_Joueur[i].x+iVitesse_Tir;
  17. Normale_gauche.y=tab_Tirs_Joueur[i].y;
  18. Normale_droite.x=tab_Tirs_Joueur[i].x-iVitesse_Tir;
  19. Normale_droite.y=tab_Tirs_Joueur[i].y;
  20. //CALCUL DU MUR TOUCHE PAR LE TIR
  21. if(tab_Tirs_Joueur[i].y<0)//mur haut dépassé
  22. {
  23. Normale=Normale_haut;
  24. }
  25. else if(tab_Tirs_Joueur[i].y>iScreen_Height)//mur bas dépassé
  26. {
  27. Normale=Normale_bas;
  28. }
  29. else if(tab_Tirs_Joueur[i].x<0)//mur gauche dépassé
  30. {
  31. Normale=Normale_gauche;
  32. }
  33. else if(tab_Tirs_Joueur[i].x<iScreen_Width)//mur droite dépassé
  34. {
  35. Normale=Normale_droite;
  36. }
  37. //-------------------------------
  38. tab_Tirs_Joueur[i].nb_rebonds++;
  39. tab_Tirs_Joueur[i].look.x=Normale.x+tab_Tirs_Joueur[i].look.x;//la normale est la perpendiculaire au mur touché
  40. tab_Tirs_Joueur[i].look.y=Normale.y+tab_Tirs_Joueur[i].look.y;//la normale est la perpendiculaire au mur touché
  41. }
  42. else//sinon si déjà eu rebond, destruction du tir
  43. {
  44. tab_Tirs_Joueur[i].nb_rebonds=0;
  45. tab_Tirs_Joueur[i].exists=FALSE;//le tir n'existe plus
  46. }
  47. }
  48. tab_Tirs_Joueur[i].x = tab_Tirs_Joueur[i].x + iVitesse_Tir * tab_Tirs_Joueur[i].look.x;//translation en x
  49. tab_Tirs_Joueur[i].y = tab_Tirs_Joueur[i].y + iVitesse_Tir * tab_Tirs_Joueur[i].look.y;//translation en y
  50. tab_Tirs_Joueur[i].vect2f_center = creapVector2f_Create(tab_Tirs_Joueur[i].x,tab_Tirs_Joueur[i].y);//vecteur centre du tir
  51. }
  52. }
 


Normalement, je dois utiliser une formule se trouvant dans l'énoncé, en voici l'extrait :

Spoiler :


On pourra réaliser le rebond à l'aide de la méthode suivante :
– n est le vecteur perpendiculaire (normal) au mur, orienté vers l'extérieur du mur ;
– look est le vecteur indiquant le sens d'avancement du tank,
– dans ce cas, le nouveau vecteur look après rebond est donné par : look = 2n + look

Pour les boulets, il faudra utiliser une struct comportant les données suivantes : position x, position
y, vecteur look, le nombre de rebonds effectués. Tous les boulets avancent à la même vitesse. On
pourra stocker les boulets dans deux tableau de 20 cases (ce qui limite à 40 le nombre de boulets
simultanément en jeu). Un tableau pour enregistrer les boulets ennemis et un tableau distinct pour
les boulets du joueur.

 

Important :
Je n'ai pas l'autorisation d'utiliser ni pointeurs, ni autres fonctions du moteur, ni le multifichiers.
Manquait plus que l'interdiction d'utiliser les variables et c'était bon !

  

En bref, ma demande :
Appliquer un rebond à un tir en utilisant la Normale d'un mur en collision avec le tir.
Il y a plusieurs murs, notamment des obstacles, donc autres que les délimitations de la map de jeu.

 

L'utilisation de CREAM n'est pas obligatoire pour résoudre ce problème.
Toutes les pistes sont les bienvenues, en vous remerciant par avance d'avoir répondu, ou même simplement lu.

 

Sefiria30


Message édité par Sefiria30 le 11-11-2013 à 00:42:40
Reply

Marsh Posté le 11-11-2013 à 00:37:52   

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed