float angleX,angleY,bangleX,bangleY, phi,psi,theta,rapport1,rapport2,rayon,tmod; Quat pp,qq,pq; Arc arcp,arcq,arcpq; Vecteur bleu,vert,rouge,paxe,qaxe,pqaxe; int tempo,incrtempo,etape; Tirette barrePhi,barrePsi,barreR1,barreR2; BFont gillesans; boolean mouvement,montrecercles,montresphere; //******************************************* //******************************************* //******************************************* void setup(){ gillesans = loadFont("GillSans.vlw.gz"); rectMode(CORNER); size(700,500); background(255); initier(); } void loop(){ clear(); push(); modifierparam(); afficherArc(arcp,50,255,0,0); afficherArc(arcq,50,0,0,255); afficherArc(arcpq,50,0,255,0); 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(); pop(); fill(120,120,140,130); rect(550,300,150,200); barrePhi.actualiser(); phi=barrePhi.getValeur(); barrePsi.actualiser(); psi=barrePsi.getValeur(); barreR1.actualiser(); rapport1=barreR1.getValeur(); barreR2.actualiser(); rapport2=barreR2.getValeur(); /*text(" quaternion rouge= ["+pp.w+","+pp.x+","+pp.y+","+pp.z+"]",50,410); text(" quaternion bleu = ["+qq.w+","+qq.x+","+qq.y+","+qq.z+"]",50,440); text("quaternion produit vert = ["+pq.w+","+pq.x+","+pq.y+","+pq.z+"]",50,470); text("touches actives : 'a' 'c' 's'",370,50); text("un clic pour le focus,s'il vous plait, puis clic et drague",370,25);*/ textFont(gillesans, 20);fill(185); text("Les quaternions sont des classes de chips decoupes sur des cones....",20,40); text("Rouge ,bleu a la queue leuleu....alors le vert ! C'est comme ca que les chips se multiplent",20,60); text("Quand vous dechirer un lambeau de l'emballage de votre cornet de glace, gardez le precieusement, ",20,80); text(" C'est un quaternion! On peut en faire l'elevage....",20,100); } //******************************************* //******************************************* //******************************************* void initier(){ mouvement=true; montrecercles=false; montresphere=true; rayon=2000.0f; angleX=0; angleY=0; tempo=0; incrtempo=1; etape=0; phi=PI-1.9f; psi=-0.99f; theta=0.0f; rapport1=1.3f; rapport2=1.4f; paxe=(new Vecteur(-20,-10,15)).normalize(); qaxe=(new Vecteur(40,-30,20)).normalize(); bleu=Vecteur.comb(1.5f,paxe,1.2f,qaxe); bleu.normalize(rayon); vert=(new Vecteur(60,-30,50)).normalize(rayon); rouge=(new Vecteur(100,30,-50)).normalize(rayon); barrePhi=new Tirette(630,430,60,-6.2f,6.27f,"angle rouge= ",235, 20,gillesans,this); barrePsi=new Tirette(630,470,60,-6.2f,6.27f,"angle bleu= ",235, 20,gillesans,this); barreR1=new Tirette(630,390,60,0.10f,3.0f,"module rouge= ",235, 20,gillesans,this); barreR2=new Tirette(630,350,60,0.10f,3.0f,"module bleu= ",235, 20,gillesans,this); barrePhi.setposition(5f); barrePsi.setposition(4f); barreR1.setposition(2.1f); barreR2.setposition(1.3f); } public void keyPressed(){ if(key=='a')mouvement=!mouvement; if(key=='c')montrecercles=!montrecercles; if(key=='s')montresphere=!montresphere; } //******************************************* //******************************************* //******************************************* void modifierparam(){ //les angles de la position if(mousePressed && (mouseX<550||mouseY<300)){ bangleX=(-mouseY+width/2.0f)/100.0f; bangleY=(mouseX-width/2.0f)/100.0f; angleX+=(bangleX-angleX)/10.0f; angleY+=(bangleY-angleY)/10.0f;} translate(200,300,-8000); rotateX(angleX); rotateY(angleY); stroke(255,0,255,100);noFill(); //les objets déformables pp=new Quat(cos(phi/2)*rapport1,paxe.mul(sin(phi/2)*rapport1)); qq=new Quat(cos(psi/2)*rapport2,qaxe.mul(sin(psi/2)*rapport2)); pq=Quat.mul(qq,pp); arcp=pp.donneArc(bleu) ; Vecteur dernier=arcp.points[50]; arcq=qq.donneArc(dernier.mul(arcp.rapport)); arcpq=pq.donneArc(bleu); float[] tabl=pq.getValue(); pqaxe=new Vecteur(tabl[1],tabl[2],tabl[3]); theta=tabl[0]; if(montrecercles){ fill(255,55,0,100); afficherCercle(paxe.x,paxe.y,paxe.z,rayon,0,0,0); fill(55,55,255,100); afficherCercle(qaxe.x,qaxe.y,qaxe.z,rayon,0,0,0); fill(255,255,255,100); afficherCercle(pqaxe.x,pqaxe.y,pqaxe.z,rayon,0,0,0); } } //******************************************* //******************************************* //******************************************* void afficherSphere(){noFill();stroke(150,50); for(int i=0;i<8;i++){ float co=(float)Math.cos(PI/8*i); float si=(float)Math.sin(PI/8*i); afficherCercle(co,0,si,rayon,0.0f,0.0f,0.0f); afficherCercle(0.0f,1.0f,0.0f,rayon*si,0.0f,rayon*co,0.0f); } } //******************************************* //******************************************* //******************************************* void afficherCercle(float nx,float ny,float nz,float r,float cx,float cy,float cz){ push(); ellipseMode(CENTER_DIAMETER); translate(cx,cy,cz); rotateZ(atan2(ny,nx)); rotateY(atan2(sqrt(nx*nx+ny*ny),nz)); ellipse(0, 0, 2*r, 2*r); pop(); } //**************************************************************** void afficherArc(Arc arc0,int n,int r,int g,int b){ float cst=arc0.rapport; float c,cc; float rap=rayon/arc0.points[0].length(); noStroke(); beginShape(BApplet.QUADS); for(int i=0;i 0.0f) ? (1.0f / (float) Math.sqrt(square)) : 1.0f; x *= dist; y *= dist; z *= dist; w *= dist; } static Quat mul(Quat q1, Quat q2) { Quat res = new Quat(); res.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z; res.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y; res.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z; res.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x; return res; } static Quat comb(Quat q1,float r1, Quat q2,float r2) { Quat res = new Quat(); res.w = q1.w *r1 + q2.w*r2; res.x = q1.x * r1+ q2.x * r2; res.y = q1.y * r1+ q2.y * r2; res.z = q1.z * r1+ q2.z * r2; return res; } float[] getValue() { float[] res = new float[4]; float nq=norme(); res[0] = (float) Math.acos(w/nq)* 2.0f; float nV= (float) Math.sqrt(x*x+y*y+z*z); if ( nV< 0.00001f*nq) { res[1] = x ; res[2] = y; res[3] = z ; }else{ res[1] = x /nV; res[2] = y/nV ; res[3] = z/nV; } return res; } Quat conjugue(){ return new Quat(w,-x,-y,-z); } Quat oppose(){ return new Quat(-w,-x,-y,-z); } Quat copie(){ return new Quat(w,x,y,z); } Quat copieNorme(){ Quat res=new Quat(w,x,y,z); res.normalize(); return res; } Vecteur tourner(Vecteur v){ Quat qv=new Quat(0.0f,v.x,v.y,v.z); Quat qc=this.conjugue(); Quat q1=Quat.mul(qv,qc); Quat q= Quat.mul(this,q1); return new Vecteur(q.x,q.y,q.z); } static Quat slerp(Quat d, Quat a,float t){ d.normalize(); a.normalize(); float angle=(float)Math.acos(d.x*a.x+d.y*a.y+d.z*a.z); float sina=(float)Math.sin(angle); float rd=(float)Math.sin(angle*(1-t))/sina; float ra=(float)Math.sin(angle*t)/sina; Quat res= Quat.comb(d,rd,a,ra); return res; } static Quat slerp1(Quat d, Quat a,float tt){ d.normalize(); a.normalize(); float t=(tt-1)*(tt-1)*(tt-1)+1; float angle=(float)Math.acos(d.x*a.x+d.y*a.y+d.z*a.z); float sina=(float)Math.sin(angle); float rd=(float)Math.sin(angle*(1-t))/sina; float ra=(float)Math.sin(angle*t)/sina; Quat res= Quat.comb(d,rd,a,ra); return res; } Vecteur axe(){ return new Vecteur(x,y,z); } Arc donneArc(Vecteur vd){ float[] c=getValue(); Vecteur vn=new Vecteur(c[1],c[2],c[3]); vn.normalize(); Arc res=new Arc(vn,c[0],this.norme()); res.calculerPoints(vd); return res; } } /////////////////////////////////////////////////////////////////////////////////////////// TIRETTE /////////////////////////////////////////////////////////// public class Tirette { int x,y,xpos,xbut,longueur,couleur1,couleur2; float valmin,valmax,coef,valeur; String titre; boolean survol,drag; BFont lafonte; BApplet apple; //********************************************************** public Tirette(int x,int y,int longueur,float valmin ,float valmax,String titre,int couleur1,int couleur2,BFont lafont,BApplet apple){ this.x=x; this.y=y; this.xpos=x; this.xbut=x; this.survol=false; this.drag=false; this.longueur=longueur; this.valmin=valmin; this.valmax=valmax; this.coef=(valmax-valmin)/(2*longueur); this.titre=titre; this.valeur=(valmin+valmax)/2; this.couleur1=couleur1; this.couleur2=couleur2; this.lafonte=lafont; this.apple=apple; } //****************************************************** public void actualiser(){ if(!apple.mousePressed && drag) drag=false; survol= (apple.mouseX>xpos-10)&&(apple.mouseXy-10)&&(apple.mouseY