Soucis de précision sur des vecteurs

Soucis de précision sur des vecteurs - C++ - Programmation

Marsh Posté le 16-02-2012 à 13:53:17    

Bonjour !
 
Voilà, j'ai une fonction qui me permet de vérifier une intersection entre un rayon et un plan, elle renvoit -1.0 si y'a pas d'intersection, sinon la distance entre le point d'origine et le point d'intersection.
 
Pour ça, j'utilise une structure que j'ai nommé "vec3f" :  
 

Code :
  1. struct vec3f
  2. {
  3.   float x,y,z;
  4. }


 
La fonction pour récupérer la distance :
 

Code :
  1. float testIntersectionPlane(const plane&p,const vec3f&from,const vec3f&dir,vec3f * out_normal)
  2. {
  3.     float dotP = vec_dot(dir,p.normal);
  4.     double length=0.0f;
  5.     if (dotP<ZERO && dotP>-ZERO)
  6.     return -1.0f;
  7.     length = vec_dot(p.normal,from-p.pos) / dotP;
  8.     if (length<-ZERO)
  9.     return -1.0f;
  10.     if (out_normal!=NULL)
  11.         *out_normal = p.normal;
  12.     return length;
  13. }


 
ZERO est définie comme la valeur 1.0e-8
 
La fonction vec dot :  
 

Code :
  1. float vec_dot(const vec3f&a,const vec3f&b)
  2. {
  3.     return (a.x*b.x + a.y*b.y + a.z*b.z);
  4. }


 
Et plane, qui est une structure :  

Code :
  1. struct plane
  2.  {
  3.   vec3f vertices[4];
  4.   vec3f normal;
  5.   vec3f pos;
  6.   void compute_normal();
  7.   void compute_pos();
  8.  };


 
La fonction marche, sauf que ben elle renvoi un truc du style "21.68 , 23.9481" en boucle, alors que le point de départ / la direction sont inchangés..
 
Du coups je penchais pour une perte de précision, je dois absolument travailler en double ? :sweat:  
 
Merci de votre aide et bonne journée :D


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 16-02-2012 à 13:53:17   

Reply

Marsh Posté le 23-02-2012 à 12:27:20    

Dégage ton mic mac avec out_normal qui est implicitement p.normal si tu n'est pas dans un cas dégénéré.

 

Le seul truc que tu dois tester c'est dotP pour pas avoir une division par 0 (cas rayon/plan coplanaire).

 

Après moi, je retournerai un bool pour savoir si tu as un cas foireux, et passerai la distance au plan en float &length.

 

ça donnerai un truc style:

 

float length;
if( testIntersectionPlane( plane, ray_pos, ray_dir, length ) && length >= 0) // ça touche dans le sens du rayon (pas derrière)
{
    vec3f intersection = ray_pos+ length * ray_dir;  
    prout( intersection, plane.normal);
}

 

Tes vecteurs n'ont pas forcément besoin d'être en double, par contre tu peux toujours stocker des intermédiaires en double.

 

Dans ton cas le mieux c'est de debugger en steppant dans le code.

 

Faut templatiser tout le bordel, etc...

 

Et n'oublie pas que tu dois normaliser la normale du plan sinon ça va chier.


Message édité par bjone le 23-02-2012 à 12:32:14
Reply

Marsh Posté le 23-02-2012 à 13:14:16    

C'est ce que j'ai fait, par contre je laisse le out_normal et j'ai ajouté un out_pos, j'en ai besoin pour faire un test de collisions sur des objets composé de plusieurs planes :)
 
Ceci dit, j'ai dû laisser le cas où la longueur était négative, sinon ça marchait pas bien :/
 
Le bug venait du fait que je forçait la position y de mon objet à être à la longueur de l'intersection, alors qu'il fallait le recalculer par ray_pos + length*ray_dir :D
 
Merci quand même :jap:


---------------
Perhaps you don't deserve to breathe
Reply

Sujets relatifs:

Leave a Replay

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