CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Problème Math 3D

hs_dino
hs_dino
Niveau 9
18 septembre 2003 à 17:12:00

J´ai un plan P définit par sa normale N.
Mon point V1 est sur le plan P.

Je pars de V1 et je glisse sur le plan P de 10 unités sur l´axe X et de 10 unités sur l´axe Z. Le point d´arrivé s´appele V2. Les axes sur repere sont définit de la manière suivante:
X à droite.
Y = N ( Normale du plan)
Z en haut.

Comment calculer V2?

i_am_the_law
i_am_the_law
Niveau 6
18 septembre 2003 à 18:35:32

Je comprends pas trop ou ca te pose probleme. Tu connais les vecteurs X et Z?
Si tu les connais c´est tout simple.
V2=V1+10*X+10*Z ( equation en vecteur)
avec X et Z normalises.

Si tu les connait pas, c´est un peu plus complique. En effet, il existe une infinite de vecteurs orthogonaux dans le plan P, qui sont tous les 2 orthogonaux a N. ( une fois que tu as en 2, tu fais une rotation autour de l´axe N)

Soit tu en prends 2 au hasard ( 1 vect orthogonal a N et le produit vect des 2) Si tu sais pas prendre un vect orthogonal, dis moi je te dirai comment trouver.
Soit tu prends la correspondance des axes globaux x et z dans ce repere local avec N qui s identifie a y.
Je pense que c´est plutot cette methode qui t´interesse, mais je prefere que tu confirmes avant que j´me lance dans les explications ; )

i_am_the_law
i_am_the_law
Niveau 6
18 septembre 2003 à 18:38:16

J´ai oublie un truc, il faut bien entendu, translater le repere local en v1, puisque un plan est defini par une normale, et une distance a l´origine. Donc il faut connaitre un point pour se trouver sur le plan. Sinon ton repere local se ´balade" le long du vecteur N.

hs_dino
hs_dino
Niveau 9
18 septembre 2003 à 20:01:09

Tout d´abord merci à toi pour ton aide. :)

J´essaye effectivement tant bien que mal à creer un repere local ayant Y qui s´identifie à N. Bien sur, il existe une infinité de repere dans ce cas précis, puisque tout les reperes tournant autour de N sont valable.

Seulement, je souhaite un axe X horizontal. Je travaille en main droite avec X à droite, Y devant et Z en haut. Quand je dis axe X horizontal, je veux dire parallele au sol.

Bon éclaircir le tout, je vais expliquer pouquoi je veux faire çà.

Il me faut dessiner une impacte de balle sur un mur. J´ai donc en ma possession les éléments suivant :
- La point d´impact.
- La normale du mur.

Pour dessigner mon impacte, j´affiche un quad ( 2 triangles) dont la taille arbitraire est de 20 par 20. Donc, a partir du point d´impact je dois me déplacer de 10 dans les directions X & Z de mon repere local d´impact pour trouver mes 4 vertex.

X et Z sont donc orthogonaux à Y tel que je l´ai décrit. Pour les trouvé j´ai utilisé le CrossProduct de la maniere suivante:

AxeX = CrossProduct( N, Vector( 0, 0, 1 ) )
AxeY = N
AxeZ = CrossProduct( AxeX, AxeY )

Seulement ca ne marche pas si N est parallele à Vector( 0, 0, 1 ) .

Donc je cherche depuis une hier une solution efficace. J´ai étudié toute la journée les quaternions mais je n´ai toujours pas de bonnes solutions. :(

Lightness1024
Lightness1024
Niveau 10
18 septembre 2003 à 20:39:49

pistes:

force le produit scalaire de ta normale par ton dexieme vecteur de triedre a 0.
( en exprimant les vecteurs par leur composantes)
fixe la composante Y de ce dernier a 0.
ca te fera une equation a 2 inconnues.
ca veut dire kil y a un ensemble de solution pour chacune des 2 variables en fonction de l´autre.

sinon si tu as un systeme ki marche deja mais dans pas 100% des cas, detecte le cas qui marche pas et fait un if ou tu gereras d´une autre maniere le cas foireux.

hs_dino
hs_dino
Niveau 9
18 septembre 2003 à 21:01:28

:d) sinon si tu as un systeme ki marche deja mais dans pas 100% des cas, detecte le cas qui marche pas et fait un if ou tu gereras d´une autre maniere le cas foireux.

C´est effectivement le cas.

Mais je trouve çà bete car on pourrait s´en passer. En fait, mon repere local n´est que mon repere monde auquel j´ai ajouté un déplacement ( Position de l´impact) et une rotation ( Normale du mur). Donc, il s´agit juste d´une bete transformation à appliquer. Seulement je n´ai pas la solution pour trouver cette transformation, donc j´utilise une magouille pour reconstituer un repere local.

Ensuite c´est une question de politique, certains ne vont pas se prendre la tete et poser des algos bancales avec des " if" dans tout les cas particuliers en se trainant en plus des EPSILON pour tenter de recoller l´imprecision du " float" quand ils veulent faire test d´égalité.
Et donc perso, je préfère chercher mieux avant de passer directement à çà :)

i_am_the_law
i_am_the_law
Niveau 6
18 septembre 2003 à 21:03:56

je comprends pas bien comment sont tes axes mais c´est pas grave :)
Tu dis y est devant ( l´axe qui sort de l´ecran?) Pcq a ce moment la, pour que ton repere soit direct, il faut que z pointe vers le bas. Enfin il faudrait un dessin, ca serait plus pratique
pour comprendre.
Dans tous les cas, il suffit de changer le signe des angles pour que ca marche correctement avec ton repere.

Mon repere pour les calculs :

|----> X
|
|
\/ Z

et Y qui vient vers nous. ( Il est direct)

Ton repere comme je l´ai compris
/\Z
|
|
|----> X

Et Y qui vient vers nous. ( il est main gauche)

Enfin bref, tu devrais arriver a remettre comme il faut en fonction du sens de tes axes :)

Y´a 2 facons de faire, soit tu calcule les coordonnes du quad a la main, soit tu fais en utilisant des glrotate et translate.

en utilisant les fct d´opengl ce que tu fais :

glMatrixMode ( GL_MODELVIEW);
glPushMatrix();
glTranslatef(Impacte);
glRotatef(anglez,Z´);
glRotatef(angley,0,1,0);
glBegin(GL_QUADS);
glVertex3f(-10,0,-10);
glVertex3f(10,0,-10);
glVertex3f(10,0,10);
glVertex3f(-10,0,10);
glEnd();
glPopMatrix();

pour les angle :
au debut tu fais tourner le repere local autour de l´axe y, pour ramener dans le plan Y/X
Pour cela tu projete la normale dans le plan z/x ( coordonnes N.x, N.z) et tu vois que tu peux trouver l´angle forme entre le vecteur X(1,0,0) et la projection de N dans le plan X/Z. Cet angle vaut -atan(N.z/N.x). Selon comment tu as nomme tes axes, ca sera p-e l´inverse, ou sans le - devant. Y reste donc identique, mais tu as X´ et Z´

Apres cette rotation l´axe X est egale a la projection de N dans X/Z
Apres, il faut effectuer une rotation autour du nouvel axe Z´, pour amener Y en Yn. Pour calculer Z´, c´est pas complique Z´.x=-cos(angley) et Z´.z=sin(angley) a peu de choses pres ( verifie les signes).

Apres, pour l´angle autour de Z´ c´est pareil : il faut ramener Y sur N. Donc il faut tourner de l´angle formé entre le vecteur Y et N ( dans le plan Y/X) donc pareil ca se fait avec un atan.
angley=-atan(N.x/N.y)

Petite verification :
Avec les axes X vers la droite, Y qui sort de l´ecran, et Z vers le bas. ( Pour moi, ca c est un repere main droite direct...)

N=(0,0,1)
Nz/Nx -> Nx=0 -> angle=-90
Z´=-X et X´=Z

Nx/Ny -> Ny=0 et Nx=0 -> anglez=-90
On tourne de 90° autour de Z´ ( =-X) -> Y´=Z et X=-Y
et on obtient bien Y´=Z=(0,0,1)=N ce qui marchait pas chez toi. X=-Y ( enfonce ds ecran), et Z´=-X ( vers la gauche)
Ce qui selon moi, est ce que tu devrais trouver avec une normale qui tombe vers le bas.

Voila, il faut aussi verifier avant le atan, que le denominateur est different de 0, sinon ca vaut -90°
J´ai donne un peu d´explications, j´espere que ca sera bon avec ton systeme d´axe et que tu pourras retrouver la formule.

Pour la methode a la main c´est pareil mais tu dois te taper les eq de rotations et translation tout seul ; )

J´ai surement fait des erreurs a ecrire ca directement, alors si ca marche pas, j´essairai de regarder ou j´me suis trompe.

Il faut aussi que tes axes N et Z´ soient normalises.

hs_dino
hs_dino
Niveau 9
18 septembre 2003 à 22:18:39

Merci vraiment pour ton boulot I_am_the_law :ok:

Je vais reprendre çà demain matin en suivant ton principe.

Pour mon repere, il est main droite :

/\Z
|...../Y
|../
|----> X

Avec Y qui pars devant, donc pas vers nous :)

Tiens pendant qu´on y est. J´ai choisis ce repere car c´est celui que je trouve le plus logique. Quand pensez-vous? Car il ne fait pas l´hunanimité apparement...

i_am_the_law
i_am_the_law
Niveau 6
18 septembre 2003 à 22:31:00

Erf ok j´ai mal compris le sens de " devant" :)

Les anglo-saxons utilisent plutot cette methode

. .Y
. .|
. .|
. ..-----x
. ./
. /
Z

Alors que nous, on a plutot tendance a utiliser l´autre.

Ca change pas grand chose l´une ou l´autre methode. En fait ce qui change c´est quand tu veux charger des modeles. Il faut prendre la facon utilisee par les modeles, ca evite d´avoir a faire des rotations :)

Personnellement je prefere comme les anglais, mais c´est une question d´habitude. Et je trouve ca plus facile a dessiner sur papier qd il faut faire les axes, il y a plus d´espace dans chaque plan quand faut faire des projections. Et enfin, l´axe Z dans ce systeme represente la profondeur, donc ca correspond plus au nom Z buffer.

Si y´en a qui preferent l´autre methode, j´aimerais bien aussi savoir pourquoi :)

Lightness1024
Lightness1024
Niveau 10
19 septembre 2003 à 08:00:12

oui moi j´ai un systeme main gauche avec Z partant vers la profondeur.

pourquoi ? :
premierement la position du triedre la plus logique c´est de partir d´une base de R² donc X vers la droite et Y vers le haut. ensuite pour passer dans R3 il faut Z en plus, dans le sens direct, ca le fait venir vers nous, mais comme je n´ai pas trouvé logique que les coordonnées plus profonde dans l´écran soit négatives, j´utilise un repère indirect ( systeme main gauche).

et il y a une derniere raison a ajouter DirectX travaille par defaut comme ca, et ca ma plu alors g pas changé :-)))

hs_dino
hs_dino
Niveau 9
19 septembre 2003 à 10:53:59

Ceci fonctionne à condition d´etre en CULLMODE OFF:
. ...float....AngleX;
. ...float....AngleZ;
. ...
. ...if( ( m_Normal.y > -0.001f ) && ( m_Normal.y < 0.001f ) )
. .......AngleX = PI / 2.0f;
. ...else
. .......AngleX = atanf( m_Normal.z / m_Normal.y ) ;
. ...
. ...if( ( m_Normal.x > -0.001f ) && ( m_Normal.x < 0.001f ) )
. .......AngleZ = PI;
. ...else
. .......AngleZ = atanf( m_Normal.x / m_Normal.y ) ;

. ...KMatrix........m;

. ...m.LoadIdentity();
. ...m.RotZ( AngleZ ) ;
. ...m.RotX( AngleX ) ;

. ...m_DirX.x = m._11;
. ...m_DirX.y = m._12;
. ...m_DirX.z = m._13;

. ...m_DirZ.x = m._31;
. ...m_DirZ.y = m._32;
. ...m_DirZ.z = m._33;

Il doit donc y avoir encore un probleme de d´angle quelque part pour l´histoire du CULL. Par exemple quand on tire par terre ca on ne voit pas l´impact, par contre ca marche au plafond.

i_am_the_law
i_am_the_law
Niveau 6
19 septembre 2003 à 14:31:41

Je sais pas pk ca marche pas, tu as pas fait les rotations autours des axes que je te disais.
P-e que je me complique la vie a faire la 2eme rotation autour de l´axe transforme, mais ca avait l´air de marcher.

Je me base sur opengl, et il compte positif la rotation ds le sens trigo. SI tu fais du directx, je sais pas.

Si on fait comme j´avais dit :

repere initial :
/\Z
|...../Y
|../
|----> X

N=(0,0,1)
Nx=0 -> angleY = -pi/2 ( pour moi c´est -pi/2..).

nouveau repere temporaire :
. ....X.....Y
. ..../\.../\
. ....|..../
. ....|.../
Z<---|./

Y a pas bouge

Maintenant on fait la rotation autour de Z´ qui est egal a -X

angle Z = Nx/Ny
Ny=0 -> angle = - pi/2

Et on a comme repere final :
. ..../\ Y
. ....|
. ....|
Z<---|
. ....\
. .....\
. ......\X

Tu as bien l´axe Y qui pointe vers le haut, dc qd tu tires au sol, ca devrait marcher si le quad que tu dessines a sa normale dans le sens de Y.

Je sais pas si j´suis assez clair, en gros ton quad que tu centres en 0,0,0 ( si tu fais comme je t´ai dit), doit avoir sa normale qui pointe dans le sens Y. La encore je sais pas ce que t´utilises donc arrange toi pour donner les sommets dans l´ordre qu´il faut pour que la normal soit dans le sens Y.

En gros, l´axe Y apres la transformation, va s identifer a la normale de ton plan. IL faut donc que la normale du quad avant transformation, soit selon l´axe Y.

Sinon j´ai une petite question, tu plaques un quad sur ton mur, ou bien tu le decolles un peu? Pcq j´avais voulu faire qqc de similaire sur un terrain, mais de poser 1 nouveau quad avec une texture a la meme profondeur qu´un autre, ca faisait des clignotements, on voyait un coups le sol, un coups ce que je voulais poser. Donc plutot que de donner une profondeur legerement superieure, j´avais fait autrement, alors j´aimerais savoir comment tu fais.

hs_dino
hs_dino
Niveau 9
19 septembre 2003 à 17:50:23

Bon en fait, il doit s´agir d´un bug d´ordre de rotation, mais j´ai pas eu le temps d´y retouché depuis ce matin, je regarderai çà ce soir.

Sinon, je ne suis ni OpenGL, ni Direct3D, j´ai mon propre système de coordonnée dans mon moteur.

Pour ta question sur les triangles coplanaires il y a 2 solutions :
- Tu décales légèrement ton quad selon la normale du mur. ( Suffisament près pour pas qu´on le voye et suffisament loin pour que le ZBuffer soit capable de faire la nuiance entre tes 2 triangles.)
- Tu utilises le ZBias.

hs_dino
hs_dino
Niveau 9
20 septembre 2003 à 10:21:30

Le probleme du CULL vient du fait que nous avons une précision à PI près et non 2PI, donc quand on cherche Y en faisant un atan( N.z / N.y ) quand on tire sur le sol ou le plafond nous avons respectivement N(0,0,1) et N(0,0,-1) ce qui dans les deux cas un résultat de PI/2, ce qui est vrai pour le plafond mais par pour le sol qui lui devrait valloir -PI/2.

Sous forums
  • Aide à l'achat Mac
  • Steam Deck
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Macintosh
  • Hardware
La vidéo du moment