//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public class Solide9 { // les quantités constantes float deltaT=0.005f; float w=100f; float h=280f; float ressort=90f; float masse=3*w*w*h/3000; float rho=12f; Matrice33 inertie; Matrice33 inertieInv; Vecteur origineR0,coin ; // les variables d'état Vecteur centreG, ocoin; Vecteur graviteR0; Quat qRot; //les dérivées Vecteur vitesse, omega; //les forces; Vecteur force, couple; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public Solide9(Vecteur centreG, Vecteur vitesse){ this.centreG=centreG; this.vitesse=vitesse; coin=new Vecteur(-h/2,5*h/6+w/3,-5*w/6-h/6); qRot=(new Quat(1.7f,0,5f,7.2f)).normalize(); omega=new Vecteur(0,0.5f,0.1f); float aa= (3*w*w+h*h)/12f*rho; float wh2=(w+h)*(w+h)*rho; float wh1=(w-h)*(w-h)*rho; inertie=new Matrice33( aa+wh2/3, 0, 0, 0, aa+wh2/4 +wh1/2, 0, 0, 0, aa+wh2/6 +wh1/2); inertieInv=inertie.invert(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void evoluer(Vecteur graviteR){ Quat qRotc=qRot.conjugue(); Vecteur centreG1=qRotc.tourner(centreG.mul(-1.0f)); //coordonnées de l'origine de R0 dans R1 Vecteur coinCentre=centreG1.ajouter(coin,-1); //de coin à centre de R0 ,dans le repere R1 force=coinCentre.mul(ressort); //force dans R1 couple=coin.cross( force); //couple dans R1 // calcul du vecteur de rotation omega Vecteur v3=inertie.applyVecteur(omega); //dans R0 par dérivation du moment //cinétique dans R1 suivi de la correction Vecteur v1=Vecteur.comb(1, couple, -1, omega.cross(v3));//Voir formule de dérivation d'un vecteur omega=omega.ajouter(inertieInv.applyVecteur(v1),deltaT);//dans un repère en mouvement omega=omega.mul(0.998f); //amorti pour éviter la divergence // println( omega.length()); Vecteur omegaR0=qRot.tourner(omega); //omega dans R0 //println(" omegaR0 "+omegaR0.length()); //println(); float angl=deltaT*omegaR0.length()/2; float cost=(float)Math.cos(angl); //calcul du quaternion qRot float sint=(float)Math.sin(angl); Vecteur omegan=omegaR0.normalize(); Quat qomegat=new Quat(cost,sint*omegan.x,sint*omegan.y,sint*omegan.z); qRot=Quat.mul(qomegat, qRot); qRot.normalize(); // la translation //calcul de la position du centre de gravité force=qRot.tourner(force); vitesse=vitesse.ajouter(force.ajouter(graviteR,masse),deltaT); centreG=centreG.ajouter(vitesse.mul(0.8f), deltaT); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void afficher(){ //dessiner le ressort Vecteur coin0=qRot.tourner(coin); //coordonnées du coin dans R0 ocoin=centreG.ajouter(coin0,1); //dans R0 helix.dessiner(ocoin); noStroke(); pushMatrix(); //conserver R0 translate(centreG.x, centreG.y,centreG.z); //translation en centreG R1 float[] ro=qRot.getValue(); rotate(ro[0],ro[1],ro[2],ro[3]); //se placer dans R1 fill(255,255,0); translate(w/2-h/2,w/3+h/3,-w/6-h/6); box(w,h,w); // dessiner la boite translate(-w/2+h/2,-w/2-h/2,0); box(h,w,w); translate(-w/2+h/2,0,w/2+h/2); box(w,w,h); popMatrix(); // revenir dans R0 } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }