// Ce sketch montre une traduction en terme d'arcs de la multiplication des quaternions // et surtout, de savoir construire l'arc qui est associé à la succession de deux arcs représentants de deux quaternions. //Il s'agit donc de choisir l'un des deux arcs sur le cercle composé. // version 0.04 AlcysMultArcQuat du 12/03/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; Tirette barrePhi,barrePsi,barreBleuNu,barreBleuMu,barreDphi,barreDpsi,barreRougeNu,barreRougeMu; PFont gillesans,book; boolean mouvement,montrecercles,montresphere,opposeR,opposeB; Pointeur pointeur1,pointeur2,pointeur3; //******************************************* //******************************************* //******************************************* void setup(){ gillesans = loadFont("Arial12.vlw"); book=loadFont("Lucida16.vlw"); rectMode(CORNER); size(800,720,P3D); initier(); } void draw(){ background(200,200,0); beginShape(QUADS); float ll=13000; fill(250,220,0); vertex(-ll,-ll,-19000); vertex(ll,-ll,-19000); fill(80,90,240); vertex(ll,ll,-19000); vertex(-ll,ll,-19000); endShape(); 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(); afficherArc(arcp,50,255,100,100); afficherArc(arcq,50,100,100,255); afficherArc(arcpq,50,100,255,100); if(montresphere) { afficherSphere(); } else{ affichercone(arcp.axe,arcp.points[0],200,0,0); affichercone(arcq.axe,arcq.points[0],0,0,200); affichercone(arcpq.axe,arcpq.points[0],0,200,0); } if(mouvement) modifierVdepart(); } //******************************************* //******************************************* //******************************************* void initier(){ mouvement=false; montrecercles=true; montresphere=true; opposeR=false; rayon=2000.0f; angleX=0; angleY=0; tempo=0; incrtempo=1; etape=0; phi=PI-1.9f; psi=-0.99f; theta=0.0f; paxe=(new Vecteur(-20,-10,15)).normalize(); qaxe=(new Vecteur(40,-30,20)).normalize(); barreDphi=new Tirette(700,150,60,0,6.27,"angle1 vecteur depart= ",41, 41,gillesans); barreDpsi=new Tirette(700,190,60,0,6.27,"angle2 vecteur depart= ",41, 41,gillesans); barrePhi=new Tirette(700,340,60,-6.2f,6.27f,"angle rouge= ",41, 41,gillesans); barreRougeMu=new Tirette(700,380,60,0f,6.27f,"angle1 axe rouge= ",41, 41,gillesans); barreRougeNu=new Tirette(700,420,60,0f,6.27f,"angle2 axe rouge= ",41, 41,gillesans); barrePsi=new Tirette(700,570,60,-6.2f,6.27f,"angle bleu= ",41, 41,gillesans); barreBleuMu=new Tirette(700,610,60,0f,6.27f,"angle1 axe bleu= ",41, 41,gillesans); barreBleuNu=new Tirette(700,650,60,0f,6.27f,"angle2 axe bleu= ",41, 41,gillesans); barreDphi.setposition(5.17); barreDpsi.setposition(0.99); barrePhi.setposition(-3.19f); barreRougeMu.setposition(2.14); barreRougeNu.setposition(2.56); barrePsi.setposition(-2.15); barreBleuMu.setposition(0.21); barreBleuNu.setposition(3.81); pointeur1=new Pointeur("depart",255,200,200); pointeur2=new Pointeur("intersection",255,255,0); pointeur3=new Pointeur("arrivee",200,200,255); } 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(); bleuMu=barreBleuMu.getValeur(); bleuNu=barreBleuNu.getValeur(); rougeMu=barreRougeMu.getValeur(); rougeNu=barreRougeNu.getValeur(); float dphi=barreDphi.getValeur(); float dpsi=barreDpsi.getValeur(); paxe= new Vecteur(sin(rougeNu)*cos(rougeMu),sin(rougeNu)*sin(rougeMu),cos(rougeNu)); qaxe= new Vecteur(sin(bleuNu)*cos(bleuMu),sin(bleuNu)*sin(bleuMu),cos(bleuNu)); vecDepart=new Vecteur(sin(dpsi)*cos(dphi),sin(dpsi)*sin(dphi),cos(dpsi)); vecDepart.normalize(rayon); //les objets déformables if(opposeR){ phi=phi-TWO_PI; }; if(opposeB){ psi=psi-TWO_PI; }; pp=new Quat(cos(phi/2),paxe.mul(sin(phi/2))); qq=new Quat(cos(psi/2),qaxe.mul(sin(psi/2))); pq=Quat.mul(qq,pp); arcp=pp.donneArc(vecDepart) ; Vecteur dernier=arcp.points[50].cloner(); arcq=qq.donneArc(dernier.mul(arcp.rapport)); arcpq=pq.donneArc(vecDepart); Vecteur vecArrivee=arcq.points[50].cloner(); float[] tabl=pq.getValue(); pqaxe=new Vecteur(tabl[1],tabl[2],tabl[3]); theta=tabl[0]; fill(255); text("quaternion rouge = ["+pp.w+","+pp.x+","+pp.y+","+pp.z+"]",50,610); text("quaternion bleu = ["+qq.w+","+qq.x+","+qq.y+","+qq.z+"]",50,640); text("quaternion produit vert = ["+pq.w+","+pq.x+","+pq.y+","+pq.z+"]",50,670); textFont(book);fill(250); text("soit I le point commun aux trois cercles trajectoires,(pointeur en jaune)",100,30); text("Soit aucun arc passe par I soit deux arcs exactement passent par ce point ",100,70); translate(-3000,0,-8000); lights(); translate(2000,0,00); rotateX(angleX); rotateY(angleY); if(montrecercles){ afficherCercle1(paxe,vecDepart,255,245,245); afficherCercle1(qaxe,dernier,240,240,255); afficherCercle1(pqaxe,vecDepart,240,255,240); afficherAxesCentres(); } pointeur1.dessiner(vecDepart); pointeur3.dessiner(vecArrivee); Vecteur pointI=symetrique(vecDepart,paxe,pqaxe); pointeur2.dessiner(pointI); } //******************************************* 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,100); 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(); } //******************************************* 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 afficherArc(Arc arc0,int n,int r,int g,int b){ float c=1.3; float rap=rayon/arc0.points[0].length()*1.1; noStroke(); beginShape(QUADS); for(int i=0;i