// Ce sketch montre une traduction en terme de SECTEURS de la multiplication des quaternions // et surtout, de savoir construire le secteur qui est associé à la succession de deux secteurs représentants de deux quaternions. // version 0.10 AlcysMultArcQuat du 20/12/2006 float angleX,angleY, phi,psi,theta,bleuNu,bleuMu,rougeMu,rougeNu,rayon,tmod; Quat pp,qq,pq; Arc arcp,arcq,arcpq; Vecteur vecDepart,paxe,qaxe,pqaxe; int tempo,incrtempo,etape; Tetraedre tetra; Tirette barrePhi,barrePsi,barreBleuNu,barreBleuMu,barreDphi,barreDpsi,barreRougeNu,barreRougeMu; PFont gilles,book,ab12; boolean mouvement,montrecercles,montresphere,opposeR,opposeB; Pointeur pointeur1,pointeur2,pointeur3; //******************************************* //******************************************* //******************************************* void setup(){ gilles = loadFont("Arial12.vlw"); book=loadFont("Lucida16.vlw"); ab12=loadFont("AB12.vlw"); rectMode(CORNER); size(800,720,P3D); initier4(); } void draw(){ background(255); pushMatrix(); barrePhi.actualiser(); barrePsi.actualiser(); barreBleuNu.actualiser(); barreBleuMu.actualiser(); barreDphi.actualiser(); barreDpsi.actualiser(); barreRougeNu.actualiser(); barreRougeMu.actualiser(); //les angles de la position if(mousePressed && (mouseX<600)){ angleX-=(mouseY-pmouseY)/50.0f; angleY+=(mouseX-pmouseX)/50.0f; } stroke(255,0,255,100); noFill(); modifierparam(); translate(-3000,0,-10000); lights(); translate(2000,0,00); rotateX(angleX); rotateY(angleY); tetra.afficherLesArcs(); popMatrix(); fill(0); textFont(book); text(tetra.secp.tex,tetra.secp.vscreen.x,tetra.secp.vscreen.y,tetra.secp.vscreen.z); text(tetra.secq.tex,tetra.secq.vscreen.x,tetra.secq.vscreen.y,tetra.secq.vscreen.z); text(tetra.secpq.tex,tetra.secpq.vscreen.x,tetra.secpq.vscreen.y,tetra.secpq.vscreen.z); textFont(gilles); Quat m=tetra.secp.q; Quat n=tetra.secq.q; Quat l=tetra.qverification; Quat o=Quat.mul(n,m); text("quaternion du secteur p = ["+m.w+","+m.x+","+m.y+","+m.z+"]",5,610); text("quaternion du secteur q = ["+n.w+","+n.x+","+n.y+","+n.z+"]",5,640); text("quaternion produit de p et q = ["+o.w+","+o.x+","+o.y+","+o.z+"]",5,670); text("quaternion du secteur pq = ["+l.w+","+l.x+","+l.y+","+l.z+"]",5,700); } //******************************************* //******************************************* //******************************************* void initier4(){ mouvement=false; montrecercles=false; montresphere=true; opposeR=false; rayon=2000.0f; angleX=0.16f; angleY=2.32f; tempo=0; incrtempo=1; etape=0; phi=1.14f; psi=-0.99f; theta=0.0f; tetra=new Tetraedre(); paxe=(new Vecteur(-20,-10,15)).normalize(); qaxe=(new Vecteur(40,-30,20)).normalize(); barreDphi=new Tirette(700,150,60,-6.27,6.27,"angle1 vecteur depart= ",41, 41,gilles); barreDpsi=new Tirette(700,190,60,-6.27,6.27,"angle2 vecteur depart= ",41, 41,gilles); barrePhi=new Tirette(700,340,60,-6.2f,6.2f,"angle rouge= ",41, 41,gilles); barreRougeMu=new Tirette(700,380,60,-6.2f,6.27f,"angle1 axe rouge= ",41, 41,gilles); barreRougeNu=new Tirette(700,420,60,-6.2f,6.27f,"angle2 axe rouge= ",41, 41,gilles); barrePsi=new Tirette(700,570,60,-6.2f,6.2f,"angle bleu= ",41, 41,gilles); barreBleuMu=new Tirette(700,610,60,-6.2f,6.27f,"angle1 axe bleu= ",41, 41,gilles); barreBleuNu=new Tirette(700,650,60,-6.2f,6.27f,"angle2 axe bleu= ",41, 41,gilles); barreDphi.setposition(3.44); barreDpsi.setposition(3.65); barrePhi.setposition(3.3f); barreRougeMu.setposition(2.14); barreRougeNu.setposition(2.15); barrePsi.setposition(-2.19); barreBleuMu.setposition(0.14); barreBleuNu.setposition(3.81); } public void keyPressed(){ if(key=='a')mouvement=!mouvement; if(key=='c')montrecercles=!montrecercles; if(key=='s')montresphere=!montresphere; if(key=='r')opposeR=!opposeR; if(key=='b')opposeB=!opposeB; } //******************************************* //******************************************* //******************************************* void modifierparam(){ phi=barrePhi.getValeur(); psi=barrePsi.getValeur(); if(opposeR){ phi=(phi>=0)?phi-TWO_PI : phi+TWO_PI; opposeR=false; barrePhi.setValeur(phi); }; if(opposeB){ psi=(psi>=0)?psi-TWO_PI : psi+TWO_PI; barrePsi.setValeur(psi); opposeB=false; }; bleuMu=barreBleuMu.getValeur(); bleuNu=barreBleuNu.getValeur(); rougeMu=barreRougeMu.getValeur(); rougeNu=barreRougeNu.getValeur(); float dphi=barreDphi.getValeur(); float dpsi=barreDpsi.getValeur(); tetra.initialiser(rougeNu,rougeMu,phi,bleuNu,bleuMu,psi,dpsi,dphi); } //******************************************* Vecteur symetrique(Vecteur d,Vecteur u, Vecteur v){ Vecteur n=(u.cross(v)).normalize(); Vecteur p=n.mul(n.dot(d)); return d.ajouter(p,-2); } //******************************************* void afficherSphere(){ fill(150,100,250,50); sphere(rayon); } //******************************************* void afficherCercle0(Vecteur n, Vecteur b,int ro,int gr,int bl){ Vecteur centr=n.mul(n.dot(b)); float ray=(n.cross(b)).length(); fill(ro,gr,bl); noStroke(); pushMatrix(); translate(centr.x,centr.y,centr.z); rotateZ(atan2(n.y,n.x)); rotateY(atan2(sqrt(n.x*n.x+n.y*n.y),n.z)); beginShape(QUAD_STRIP); for(int i=0;i<50;i++){ vertex(ray*cos(i*PI/24),ray*sin(i*PI/24),-80); vertex(ray*cos(i*PI/24),ray*sin(i*PI/24),80); } endShape(); popMatrix(); } //******************************************* public void afficherCercle1(Vecteur n, Vecteur b,int ro,int gr,int bl){ float h=n.dot(b); Vecteur centr=n.mul(h); float ray=(n.cross(b)).length(); fill(ro,gr,bl); noStroke(); pushMatrix(); rotateZ(atan2(n.y,n.x)); rotateY(atan2(sqrt(n.x*n.x+n.y*n.y),n.z)); noStroke(); beginShape(QUAD_STRIP); for(int i=0;i<50;i++){ vertex(ray*cos(i*PI/24),ray*sin(i*PI/24),h); vertex(ray*cos(i*PI/24)*1.1,ray*sin(i*PI/24)*1.1,h*1.1); } endShape(); popMatrix(); } //******************************************* void afficherCercle(float nx,float ny,float nz,float r,float cx,float cy,float cz){ pushMatrix(); ellipseMode(CENTER); translate(cx,cy,cz); rotateZ(atan2(ny,nx)); rotateY(atan2(sqrt(nx*nx+ny*ny),nz)); ellipse(0, 0, 2*r, 2*r); popMatrix(); } //**************************************************************** void afficherAxesCentres(){ float rr=2*rayon; stroke(255,0,0); afficheligne(paxe.mul(-rr),paxe.mul(rr)); stroke(0,0,255); afficheligne(qaxe.mul(-rr),qaxe.mul(rr)); stroke(0,255,0); afficheligne(pqaxe.mul(-rr),pqaxe.mul(rr)); } //**************************************************************** void afficherplans(){ fill(255,255,0,150); stroke(255); beginShape(TRIANGLES); vertex(0,0,0); vertex(rayon*paxe.x,rayon*paxe.y,rayon*paxe.z); vertex(rayon*qaxe.x,rayon*qaxe.y,rayon*qaxe.z); fill(255,0,250,150); vertex(0,0,0); vertex(rayon*paxe.x,rayon*paxe.y,rayon*paxe.z); vertex(rayon*pqaxe.x,rayon*pqaxe.y,rayon*pqaxe.z); fill(0,255,255,150); vertex(0,0,0); vertex(rayon*pqaxe.x,rayon*pqaxe.y,rayon*pqaxe.z); vertex(rayon*qaxe.x,rayon*qaxe.y,rayon*qaxe.z); endShape(); afficherAxesCentres(); } //**************************************************************** void afficheligne(Vecteur v1,Vecteur v2){ line(v1.x ,v1.y ,v1.z ,v2.x ,v2.y,v2.z); } //**************************************************************** void modifierVdepart(){ tmod+=0.03; vecDepart.x=cos(tmod)*sin(3*tmod); vecDepart.y=sin(tmod); vecDepart.z=sin(2*tmod)+cos(tmod); vecDepart.normalize(rayon); } //**************************************************************** void affichercone(Vecteur axe,Vecteur v,int r,int g,int b){ v.normalize(5000); Vecteur vaxe=axe.mul(v.dot(axe)); Vecteur vx=v.ajouter(vaxe,-1); Vecteur ygrec=axe.cross(v); stroke(r,g,b,50); //noFill(); fill(r,g,b,30); beginShape(TRIANGLE_STRIP); Vecteur res=v; for(float j=1;j<=31;j++){ float i=j*TWO_PI/30; Vecteur res1= vaxe.ajouter(Vecteur.comb((float)Math.cos(i),vx,(float)Math.sin(i),ygrec),1); vertex(0,0,0); vertex(res.x,res.y,res.z); vertex(res1.x,res1.y,res1.z); res=res1; } endShape(); } //**************************************************************** //------------------------------------------------------- public Vecteur coorabs(Vecteur v){ float xa=screenX(v.x,v.y,v.z); float ya=screenY(v.x,v.y,v.z); float za=0.0f; //println(v.x+" "+v.y+" "+ v.z+"---> "+xa+" "+ya+" "+za); return new Vecteur(xa,ya,za); }