boolean premierefois,sourisrelachee,auto; int centreX,centreY,frame; float angleX,angleY,bangleX,bangleY,tempo,incrtempo,phi,psi; Vecteur a ,b,c,aXc, bXc,aPb,uPv, aPbXc,coora,coorb,coorc,cooraPb, cooraXc,coorbXc,cooruPv,test,coorm,coorsm,coorssm,coorhssm; Quat qslerp,qbleu,qvert; Vecteur[] tamponArc,tamponArc1; Tirette barreU,barreV,barreS; Bouton button; String texte; BFont futura; //******************************************* //******************************************* //******************************************* public void setup(){ futura = loadFont("GillSans.vlw.gz"); size(700,500); background(255); initier(); } public void loop(){ clear(); push(); modifierparam(); figurer(); pop(); figurertexte(); fill(0); this.rect(550,0,200,450); barreU.actualiser(); c.x=barreU.getValeur(); barreV.actualiser(); c.y=barreV.getValeur(); barreS.actualiser(); c.z=barreS.getValeur(); frame=button.actualiser(sourisrelachee); sourisrelachee=false; textFont(futura,24); fill(0); text(texte,20,480); } void mouseReleased(){ sourisrelachee=true; } public void keyPressed() { if (key == 'a') { auto = !auto; }; if (!auto) { if (key == UP) { c.x += 0.1; }; if (key == DOWN) { c.x -= 0.1; }; if (key == RIGHT) { c.z += 0.1; }; if (key == LEFT) { c.z -= 0.1; }; } } //******************************************* //******************************************* //******************************************* void initier(){ angleX=0; angleY=0; tempo=0; incrtempo=1.0f/40; a=new Vecteur(0.7f,0.9f,0.3f); b=new Vecteur(0.9f,0,-0.8f); c=new Vecteur(-0.1f,0.33f,1.3f); test=new Vecteur(450,-350,-1400); premierefois =true; sourisrelachee=false; auto=true; frame=1; centreX=width/2; centreY=height/2; barreU=new Tirette(630,250,60,-1.2f,0.2f,"cx = ",235, 20,futura,this); barreV=new Tirette(630,300,60,-1.2f,0.2f,"cy = ",235, 20,futura,this); barreS=new Tirette(630,350,60,0.5f,1.5f,"cz = ",235, 20,futura,this); button=new Bouton(550,400,40,20," next",this); texte=" "; } //******************************************* //******************************************* //******************************************* void modifierparam(){ if(tempo>6||tempo<0)incrtempo*=-1; tempo+=incrtempo; if(mousePressed && mouseX<500){ if(premierefois){centreX=mouseX;centreY=mouseY;} premierefois=false; bangleX=(-mouseY-170+centreX)/50.0f; bangleY=(-mouseX+centreY)/50.0f; angleX+=(bangleX-angleX)/10.0f; angleY+=(bangleY-angleY)/10.0f; } else { premierefois=true; } translate(-150,30,-4000); rotateX(2+angleX); rotateY(-3+angleY); } //******************************************* //******************************************* //******************************************* void figurer(){ //calculs preliminaires aXc=a.cross(c); bXc=b.cross(c); uPv=(aXc.ajouter(bXc,1)); aPb=a.ajouter(b,1); aPbXc=aPb.cross(c); coora=coorabs(a.mul(1550f)); coorb=coorabs(b.mul(1550f)); coorc=coorabs(c.mul(1550f)); cooraPb=coorabs(a.ajouter(b,1).mul(1550f)); cooraXc=coorabs(aXc.mul(1550f)); coorbXc=coorabs(bXc.mul(1550f)); cooruPv=coorabs(uPv.mul(1550f)); coorm=coorabs(test.mul(1.03f)); //etat 0: le quaternion q1 if(frame>0){ stroke(0); line(0,0,0,1500f*c.x,1500f*c.y,1500f*c.z); line(0,0,0,1500f*a.x,1500f*a.y,1500f*a.z); line(0,0,0,1500f*aXc.x,1500f*aXc.y,1500f*aXc.z); afficherPlan(a,aXc,0xFF0000); afficherPlan(c,aXc,0xFF0088);} //etat 1 le quaternion q2 if(frame>1){ stroke(0); line(0,0,0,1500f*b.x,1500f*b.y,1500f*b.z); line(0,0,0,1500f*bXc.x,1500f*bXc.y,1500f*bXc.z); afficherPlan(b,bXc,0x8800FF); afficherPlan(c,bXc,0x0000FF);} //etat 2 le plan a b a+b if(frame>2){ afficherPlan(a,b,0xFFFF00); stroke(0); line(0,0,0,1500f*aPb.x,1500f*aPb.y,1500f*aPb.z);} //etat 3 le plan aXc bXc if(frame>3){ afficherPlan(aXc,bXc,0x00FFFF); stroke(0); line(0,0,0,1500f*uPv.x,1500f*uPv.y,1500f*uPv.z);} // etat 4 if(frame>4){ afficherPlan(aPbXc,c,0xFFFFFF); afficherPlan(aPb,aPbXc,0xFFFFFF); stroke(0); line(0,0,0,1500f*aPbXc.x,1500f*aPbXc.y,1500f*aPbXc.z);} //etat 5 le test if(frame>5){ stroke(255,0,0); line(test.x,test.y,test.z,0,0,0); Vecteur p=Vecteur.symetric(aPb,uPv,test); coorsm=coorabs(p.mul(1.03f)); line(0,0,0,p.x,p.y,p.z); Vecteur res= Vecteur.symetric(uPv,c,p); coorssm=coorabs(res.mul(1.03f)); line(0,0,0,res.x,res.y,res.z); line(p.x,p.y,p.z,test.x,test.y,test.z); line(res.x,res.y,res.z,p.x,p.y,p.z); beginShape(TRIANGLES); fill(0,200,40); vertex(test.x,test.y,test.z); vertex(0,0,0); vertex(p.x,p.y,p.z); fill(150,255,0); vertex(0,0,0); vertex(p.x,p.y,p.z); vertex(res.x,res.y,res.z); endShape(); Quat quq=new Quat(c.dot(aPb),aPbXc); Vecteur tr0=res.mul(quq.norme()); coorhssm=coorabs(tr0.mul(1.030f)); stroke(0,255,0); line(0,0,0,tr0.x,tr0.y,tr0.z); /* Quat qv=new Quat(0,test); Quat trq= Quat.mul(quq,Quat.mul(qv,quq.conjugue())); trq.scale(1/quq.norme()); stroke(0,0,255);line(0,0,0,trq.x/2,trq.y/2,trq.z/2); println(tr0.length()+" "+(trq.axe()).length());*/ } } // ******************************************* // ******************************************* // ******************************************* void afficherTriangle(Vecteur v,Vecteur w,int couleur){ int r,g,b; fill(couleur>>16,(couleur&0xFF00)>>8,couleur&0xFF,150); r=couleur>>16;g=(couleur&0xFF00)>>8;b=couleur&0xFF; beginShape(TRIANGLES); fill(r/6,g/6,b/6,220); vertex(0,0,0); fill(r,g,b,220); vertex(v.x,v.y,v.z); vertex(w.x,w.y,w.z); endShape(); } //******************************************* //******************************************* //******************************************* void afficherPlan(Vecteur v1,Vecteur w1,int couleur){ int r,g,b; Vecteur v=v1.mul(1000); Vecteur w=w1.mul(1000); r=couleur>>16;g=(couleur&0xFF00)>>8;b=couleur&0xFF; noStroke(); beginShape(QUADS); fill(r,g,b,220); vertex(v.x,v.y,v.z); vertex(v.x+w.x,v.y+w.y,v.z+w.z); fill(r/2,g/2,b/2,220); vertex(w.x,w.y,w.z); fill(r/6,g/6,b/6,220); vertex(0,0,0); endShape(); } //******************************************* //******************************************* //******************************************* void afficherSphere(){ 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,2500.0f,0.0f,0.0f,0.0f); afficherCercle(0.0f,1.0f,0.0f,2500.0f*si,0.0f,2500.0f*co,0.0f); } } void afficherCercle(float nx,float ny,float nz,float r,float cx,float cy,float cz){ push(); noFill(); 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(); } //******************************************* //******************************************* //******************************************* Vecteur coorabs(Vecteur v) { float xa = objectX(v.x, v.y, v.z); float ya = objectY(v.x, v.y, v.z); float za = objectZ(v.x, v.y, v.z); return new Vecteur(xa, ya, za); } //******************************************* //******************************************* //******************************************* void afficherObjet(Quat q,Vecteur v){ push(); //appliquer le Quaternion q et dessiner v dans le nouveau repere; float[] a=q.getValue(); rotate(a[0] ,a[1] ,a[2],a[3]); translate(v.x,v.y,v.z); afficherRepere(); //fill(255,0,0,150); //box(500); pop(); } //******************************************* //******************************************* //******************************************* void figurertexte(){ if(frame>0 ){ afficherF("a" ,coora); afficherF("U=a^c",cooraXc); afficherF("c" ,coorc); texte="le quaternion p est defini par le produit scalaire a*c et le produit vectoriel U=a^c ..."; } if(frame>1 ){ afficherF("b" ,coorb); afficherF("V=b^c",coorbXc); texte="le quaternion q est defini par le produit scalaire b*c et le produit vectoriel V=b^c ..."; } if(frame>2 ){ afficherF("a+b",cooraPb); texte="le vecteur somme de a et b, a+b ... "; } if(frame>3 ){ afficherF("U+V",cooruPv); texte="et le vecteur somme de U et V, U+V definissent le quaternion p+q car.... " ; } if(frame>4 ){ texte=" p+q=[a*c,a^c]+[b*c,b^c]=[a*c+b*c,a^c+b^c]=[(a+b)*c,(a+b)^c] . Donc p+q..."; } if(frame>5 ){ texte=" a pour axe : (a+b)^c = a^c + b^c = U+V . L'image de m par la similitude associee a p+q est : ..."; afficherF("m" ,coorm); if(frame>6 ){ afficherF("s1(m)" ,coorsm); afficherF("s2(s1(m))" ,coorssm); afficherF("h(s2(s1(m)))" ,coorhssm); texte="h(s2(s1(m))) s1, s2, h sont les reflexions et homothetie detaillees ci-dessous"; } } } //******************************************* //******************************************* //******************************************* void afficherRepere(){ stroke(255,0,0); line(0,0,0,2000,0,0); stroke(0,255,0); line(0,0,0,0,2000,0); stroke(0,0,255); line(0,0,0,0,0,2000); } //******************************************* //******************************************* //******************************************* void afficherArc(){ noStroke(); int limite=(int)(tempo/abs(incrtempo)); beginShape(BApplet.QUADS);fill(0,0,255); for(int i=1;i 0.0f) ? (1.0f / (float) Math.sqrt(square)) : 1.0f; x *= dist; y *= dist; z *= dist; w *= dist; } void scale(float dist) { 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() { // le quaternion doit etre norme; rend l'angle de la rotation et l'axe float[] res = new float[4]; res[0] = (float) Math.acos(w) * 2.0f; float nV= (float) Math.sqrt(x*x+y*y+z*z); if ( nV< 0.00001f) { 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 inverse(){ float d=w*w+x*x+y*y+z*z; return new Quat(w/d,-x/d,-y/d,-z/d); } 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); } } //--------------------------------------------------------------------------------------------------------------------- public class Bouton { int x,y,l,h,noFrame; String texte; BApplet gra; boolean sur; public Bouton(int x,int y, int l,int h,String texte,BApplet gra){ this.x=x; this.y=y; this.l=l; this.h=h; this.texte=texte; this.gra=gra; this.sur=false; this.noFrame=1; } int actualiser(boolean etatsouris){ sur=((gra.mouseX>x)&&(gra.mouseYy)&&(gra.mouseY7) noFrame=1; }else{ if(sur ){dessin(255f,200f,200f); }else{ dessin(255f,255f,255f);} } return noFrame; } void dessin(float rr,float gg,float bb){ gra.fill(gg,gg,bb); gra.rect(x,y,3*l,h); gra.fill(rr,0,0); gra.beginShape(BApplet.TRIANGLES); gra.vertex(x,y); gra.vertex(l*0.4f+x,y+h/2); gra.vertex(x,y+h); gra.endShape(); gra.text(texte,x+l,y+h/2+5); } } //-------------------------------------------------------------------------------------------------- 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