Annonces Google
Serveur IRC
Serveur : irc.portlane.se
Canal : #AmigaNG
Activité du Site

Pages vues depuis 25/07/2007 : 25 261 713

  • Nb. de membres 187
  • Nb. d'articles 1 270
  • Nb. de forums 19
  • Nb. de sujets 20
  • Nb. de critiques 24

Top 10  Statistiques

Index du forum »»  Création-Développement »» Question math 3D

Question math 3D#1651

7Contributeur(s)
thellierscriptjesterAmiDARKFabK-LElwoodsinisrus
3 Modérateur(s)
K-LElwoodcorto
thellier thelliericon_post
Salut

Je bute sur un calcul en 3D je sèche, ce doit pas être compliqué,mais j'ai les neurones fatigués...

Voilà :
Soit 2 points dans l'espace A et B formant un segment de droite
définis ainsi A.x A.y A.z B.x B.y B.z
(dans une position quelconque pas comme sur mon schéma)
Soit un point V à une position quelconque par rapport au segment
Trouver x qui est la position de la projection orthogonale de V sur la droite AB
Trouver d la distance de la droite à V

...............V
...............|
..............d
-------A-x-|-----B---->

Evidemment d est une valeur positive
Mais x peut être négatif si il se trouve "devant" A

MERCI DE VOTRE AIDE :-)

Vous me direz "A quoi ça sert ?"
Pour animer un bonhomme 3D : Si A-B definit un "bone" et V un des point d'un "mesh" alors ce point est dans ce bone si x est dans AB et que d est inférieur à l'épaisseur du "bone"
Genre: point est dans bras si point entre épaule et coude et distance point à l'os < 10cm


Alain















Message édité par : thellier / 04-09-2013 16:27
Message édité par : thellier / 04-09-2013 16:32
scriptjester scriptjestericon_post
4e lien avec google :

Pas besoin de lite les 5 pages mais juste le 2) :

draymath.unblog.fr/files/2008/04/distances1.pdf

avec ça tu devrais pouvoir t'en sortir !








Message édité par : scriptjester / 04-09-2013 17:52
AmiDARK AmiDARKicon_post
ScriptJester : ça me sera utile à moi aussi :)
Les années "écoles" sont tellement loin derrière que je ne me souviens plus trop des formules mathématiques :p

Merci :)

@+

Message édité par : AmiDARK / 04-09-2013 21:07
thellier thelliericon_post
@scriptjester
MERCI j'aurai préféré plus simple

Voilà ce que j'en comprends en reprenant son nommage:


ux * ax + uy * ay + uz * az + d = 0

-(ux * ax + uy * ay + uz * az ) = d

ux*(ux*k+bx) + uy(uy*k+by) + uz(uz*k+bz)+d=0

ux*ux*k+ux*bx + uy*uy*k+uy*by + uz*uz*k+uz*bz + d=0

k * (ux*ux + uy*uy + uz*uz) = - ( ux*bx + uy*by + uz*bz + d)

k= - ( ux*bx + uy*by + uz*bz + d) / (ux*ux + uy*uy + uz*uz)

hx=ux*k+bx
hy=uy*k+by
hz=uz*k+bz

=====================================================
En le remettant en langage C dans mon problème avec A-B le segment et V le point à tester:

/* calcul du vecteur directeur u */

U.x = B.x -A.x;
U.y = B.y -A.y;
U.z = B.z -A.z;
size=sqrt(U.x*U.x+U.y*U.y+U.z*U.z);
U.x = U.x/size;
U.y = U.y/size;
U.z = U.z/size;

/* d selon sa formule */
d= -(U.x * V.x + U.y * V.y + U.z * V.z ) ;

/* k selon sa formule */
k= - ( U.x*A.x + U.y*A.y + U.z*A.z + d) / (U.x*U.x + U.y*U.y + U.z*U.z) ;

/* point intersection H */
H.x=U.x*k + A.x;
H.y=U.y*k + A.y;
H.z=U.z*k + A.z;

/* enfin d et x mes inconnues */
d=DistanceV(&H,&V);
x=DistanceV(&H,&A);

Mais y reste toujours un problème x n'a plus de signe alors que x peut être négatif si il se trouve "devant" A
Evidemment on peut calculer les distance AH et BH et AB et comparer et déterminer si il se trouve "devant" A ... mais que de calculs.... Y doit y avoir plus simple
Personne connais un prof de math ??? ;-P

Alain
Fab Fabicon_post
Citation : thellier?

Mais y reste toujours un problème x n'a plus de signe alors que x peut être négatif si il se trouve "devant" A
Evidemment on peut calculer les distance AH et BH et AB et comparer et déterminer si il se trouve "devant" A ... mais que de calculs.... Y doit y avoir plus simple
Personne connais un prof de math ??? ;-P

Alain
?


Cette façon de calculer la distance du point par rapport à A est un peu longue, mais elle a le mérite de la démontrer (simplement).

En fait, en utilisant le produit vectoriel, on arrive à un résultat plus rapidement utilisable : soit la droite d passant par A et B, et V un point quelconque de l'espace, alors la distance h de V à la droite d est h = norme(AV ^ AB)?/ norme(AB). (on passera sur la représentation vectorielle difficile à faire passer sur un forum :)).
Après, pour avoir ce fameux x en valeur absolue que tu cherches, il suffit d'utiliser pythagore, soit |x| = sqrt( norme(AV)? - h?)

Après que ce soit avec ce résultat ou celui du document précédemment cité, il va de soi qu'il n'a pas de signe puisque c'est une distance. Alors pour savoir si le signe de x est positif ou négatif, il suffit de calculer le produit scalaire AV . AB : si le produit scalaire est positif, AV et AB sont dans le même sens, ce qui signifie que H est entre A et B (ou plus loin que B, éventuellement); si il est négatif, alors AV et AB sont de sens contraire, et donc A est situé entre B et H.

Pour rappel :
produit scalaire de deux vecteurs u(u1, u2, u3) et v(v1, v2, v3) : u.v = u1*v1 + u2*v2 + u3*v3
produit vectoriel de deux vecteurs u(u1, u2, u3) et v(v1, v2, v3) : u^v = (u2*v3 - u3*v2, u3*v1 - u1*v3, u1*v2 - u2*v1)
norme du vecteur AB avec A(x, y, z) et B(x',y',z') = sqrt( (x'-x)? + (y'-y)? + (z'-z)? )

Donc en pratique, et pour essayer d'économiser quelques opérations inutiles (on peut sans doute faire mieux de côté), ça devrait donner :

AV = (V.x - A.x, V.y - A.y, V.z - A.z), qu'on remplacera par AV de coordonnées (u1, u2, u3)
AB = (B.x - A.x, B.y - A.y, B.z - A.z), qu'on remplacera par AB de coordonnées (v1, v2, v3)

AV ^ AB = (u2*v3 - u3*v2, u3*v1 - u1*v3, u1*v2 - u2*v1) = (p1, p2, p3)

D'après la formule de la distance d'un point à une droite, on a donc h? = || AV ^ AB || ? / ||?AB || ? = (p1? + p2? + p3?) / (v1? + v2? + v3?)

Soit |x| = sqrt( u1?+ u2? + u3? - h?)
et signe(x) = signe ( u1*v1 + u2*v2 + u3*v3 )

Voilà (en espérant ne pas m'être planté dans les calculs (mais sur le principe c'est bon)... :)

Message édité par : Fab / 05-09-2013 13:14
Message édité par : Fab / 05-09-2013 13:30
thellier thelliericon_post
GRANDS MERCIS
J'avais vu qque chose de similaire sur wikipedia mais là c'est bien mieux fait :-)

OK on remets tout en C et ça devrais donner ça :
==================================

Vertex3D A,B,V;
Vertex3D AV,AB,P;
float h2,h,x;

AV.x =V.x - A.x;
AV.y =V.y - A.y;
AV.z =V.z - A.z;

AB.x =B.x - A.x;
AB.y =B.y - A.y;
AB.z =B.z - A.z;

P.x=AV.y*AB.z - AV.z*AB.y;
P.y=AV.z*AB.x - AV.x*AB.z;
P.z=AV.x*AB.y - AV.y*AB.x;

h2 =( P.x*P.x + P.y*P.y + P.z*P.z) / (AB.x*AB.x + AB.y*AB.y +AB.z*AB.z);
h = sqrt(h2);

x = sqrt( AV.x*AV.x + AV.y*AV.y + AV.z*AV.z - h2)
if( ( AV.x*AB.x + AV.y*AB.y + AV.z*AB.z ) <0)
x=-x;

=====================================
C'est moi ? ou alors le language C parais plus clair que celui des maths ? ;-P

A noter que AB est constant puisque c'est la longueur de l'os (bone) au repos (et on fait la "skin" sur le bonhomme au repos) donc on peut le précalculer (valable pour tout les Vs) et que dès que h2 est connu on peut savoir si le point V n'appartient pas à ce bone car trop éloigné de l'os
x ne sert en fait qu'à calculer la "force" à appliquer à ce point V


Ca devrait marcher

Alain



Message édité par : thellier / 05-09-2013 15:14
Message édité par : thellier / 05-09-2013 15:15
thellier thelliericon_post
Avec des macros pour éviter les (mes) fautes de frappe et faire plus joli:
==============================================
Vertex3D A,B,V;
Vertex3D AV,AB,P;
float h2,h,x;

#define DIST2(V) (V.x*V.x + V.y*V.y + V.z*V.z)
#define PSCAL(A,B) (A.x*B.x + A.y*B.y + A.z*B.z)

AV.x =V.x - A.x;
AV.y =V.y - A.y;
AV.z =V.z - A.z;

AB.x =B.x - A.x;
AB.y =B.y - A.y;
AB.z =B.z - A.z;

P.x=AV.y*AB.z - AV.z*AB.y;
P.y=AV.z*AB.x - AV.x*AB.z;
P.z=AV.x*AB.y - AV.y*AB.x;

h2 = DIST2(P) / DIST2(AB);
h = sqrt(h2);

x = sqrt( DIST2(AV) - h2)
if( PSCAL(AV,AB ) <0)
x=-x;
K-L K-Licon_post
Je m'immisce rapidement mais.... vous êtes vraiments des killers les gars, franchement. Chapeau !

(J'ai fait bac L donc je ne comprends pas un broque de ce que vous écrivez, d'où mon côté impressionné). :=! :=!
--
AmigaONE X1000/1,8 Ghz (A-Eon), Radeon RX560, 2 Go de Ram et OS4.1 FE
thellier thelliericon_post
Merci K-L

Mais on s'auto-felicitera vraiment quand ça marchera dans microbe3D :

Pour l'instant , en faisant juste un bras gauche sur partygirl.obj, la technique de Fab semble bien "accrocher" les bons points au bras,avant-bras,main
par contre les axes de ces membres ("bones") sont faux si bien que la pauvre partygirl est affreusement déformée : on dirait un zombie qui perd un bras ;-) y doit y avoir une coquille dans mon code

Moi j'avais fait un bac D que j'avais pas eu et au final j'ai un bac H "Technique informatique " et le BTS idem

Alain
Elwood Elwoodicon_post
@KL

J'ai fait un bac D (math + bio) et je suis impressionné aussi :-)
--
Philippe Ferrucci
Avec une Sam460 et AmigaOS 4.1, je suis eco-responsable. Cool !
Petites Annonces

0 annonce(s) publiée(s)

Consulter

AmigaOS 4.1

Laissez-vous tenter par
AmigaOS 4.1
AmiTheme

AmiTheme