float angleY,angleX,rx,ry,phi,psi,temps; Vecteur uu,vv,ww,inter1,inter2,ww1; BFont metaBold; BFont futura; Quat q_u,q_v,q_uv,q_qi; boolean auto; Vector trajet0,trajet2,trajet3; //------------------------------------------------------- void setup(){ auto=true; trajet0=new Vector(); trajet2=new Vector(); trajet3=new Vector(); metaBold = loadFont("Meta-Bold.vlw.gz"); futura=loadFont("Futura-Light.vlw.gz"); size(600,500); background(0);//197,197,175 angleX=0;rx=0; angleY=0;ry=0; phi=PI/2.95;//mesure en rd du1/2angle de la premiere rotation psi=PI/2;//mesure en rd du 1/2angle de la deuxieme rotation uu=new Vecteur(-3,2,5.5);uu.normalize(); vv=new Vecteur(2,2,2.75);vv.normalize(); q_u=new Quat(cos(phi),uu.mul(sin(phi))); } //----------------------------------------------------- void deplacervv(){ vv.normalize(); q_v=new Quat(cos(psi),vv.mul(sin(psi))); ww=uu.cross(vv).normalize();//normale au plan (u,v) q_uv=Quat.mul(q_u,q_v); inter1=new Vecteur(q_uv.x,q_uv.y,q_uv.z); q_qi=Quat.mul(q_uv,q_u.conjugue()); ww1=uu.cross(inter1).normalize();//normale au plan (u,inter1) inter2=new Vecteur(q_qi.x,q_qi.y,q_qi.z); } //------------------------------------------------------- void keyPressed() { if(key=='a') { auto=!auto;}; if(!auto){ if(key==UP){ vv.x+=0.01;}; if(key==DOWN){ vv.x-=0.01;}; if(key==RIGHT){vv.z+=0.01;}; if(key==LEFT){ vv.z-=0.01;}; } } void loop(){ angleY=(mouseX-width*0.5f)/150.0f; angleX=-(mouseY-height*0.5f)/150.0f; if(auto){ temps+=0.02; if(temps>TWO_PI) temps=0; vv.y=1.5+2*cos(3*temps)*cos(temps); vv.z=1+2*cos(3*temps)*sin(temps); vv.x=1-1.3*cos(3*temps); } deplacervv(); clear(); push(); afficherplans(); pop(); } //------------------------------------------------------- void afficherL(String s,Vecteur v){ textFont(metaBold, 600); fill(100,100,255); push(); translate(v.x,v.y,v.z); text(s, 0,0); pop(); } void afficherF(String s,Vecteur v){ textFont(futura, 400); fill(255); push(); translate(v.x,v.y,v.z); text(s, 0,0); pop(); } //------------------------------------------------------- void afficherplans(){ push(); translate(0,700,-9800); ry+=(angleY-ry)/10; rx+=(angleX-rx)/10; rotateY(ry+PI/5); rotateX(rx+PI/5); stroke(255,0,0); afficherPlan(uu,vv,200,85,100);// afficherPlan(uu,inter1,100,100,190);// afficherPlan(vv,inter1,150,200,60); afficherPlan(uu,inter2,250,50,60); afficherPlan(inter1,inter2,50,250,60); Vecteur origine=coorabs( new Vecteur(0,0,-400)); Vecteur uuu=coorabs(uu.mul(5000)); Vecteur vvv=coorabs(vv.mul(5000)); Vecteur inter1abs=coorabs(inter1.mul(5000)); Vecteur inter2abs=coorabs(inter2.mul(5000)); Vecteur centre=uu.mul(uu.dot(vv)*5000 ); Vecteur centreabs=coorabs(centre); Vecteur s1=coorabs(Vecteur.comb(2500,uu,2500,vv)); Vecteur s2=coorabs(Vecteur.comb(2500,uu,2500,inter1)); Vecteur s3=coorabs(Vecteur.comb(2500,vv,2500,inter1)); Vecteur s4=coorabs(Vecteur.comb(2500,inter1,2500,inter2)); Vecteur s5=coorabs(Vecteur.comb(2500,inter2,2500,uu)); afficherCercle(centre,(uu.cross(vv).length())*5000); pop(); afficherL("V",vvv); afficherL("U",uuu); afficherL("V' ",inter2abs); afficherL("M",inter1abs); afficherL("O",origine); afficherL("C",centreabs); afficherF("S1",s1); afficherF("S2",s2); afficherF("S3",s3); afficherF("S4",s4); afficherF("S5",s5); } //------------------------------------------------------- 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 afficherAxe(Vecteur v,float d){ v.normalize(); line(0,0,0,v.x*d,v.y*d,v.z*d);} //------------------------------------------------------- void afficherPlan(Vecteur a,Vecteur b,float coul1,float coul2,float coul3){ float d=5000; a.normalize(); b.normalize();noStroke(); beginShape(TRIANGLES); fill(coul1,coul2,coul3); vertex(b.x*d,b.y*d,b.z*d); vertex(a.x*d,a.y*d,a.z*d); fill(coul1/2.7,coul2/2.7,coul3/2.7); vertex(0,0,0); endShape(); } Vecteur afficherSym(Vecteur m,Vecteur w1,Vecteur u,int coul1,int coul2){ Vecteur p=w1.mul(w1.dot(m)); Vecteur pu=u.mul(u.dot(m)); Vecteur sym=new Vecteur(m.x-p.x*2 ,m.y-p.y*2 ,m.z-p.z*2); fill(coul1,coul2,coul1/2+coul2/2); noStroke(); beginShape(TRIANGLES); vertex(sym.x ,sym.y,sym.z); vertex(m.x,m.y,m.z); fill(coul1/3,coul2/3,40); vertex(pu.x,pu.y,pu.z); endShape(); return sym; } //------------------------------------------------------- void afficherCercle(Vecteur c,float r){ push(); stroke(255,255,255,100);fill(255,255,0,100); ellipseMode(CENTER_DIAMETER); translate(c.x,c.y,c.z); rotateZ(atan2(c.y,c.x)); rotateY(atan2(sqrt(c.x*c.x+c.y*c.y),c.z)); ellipse(0, 0, 2*r, 2*r); pop(); line(c.x,c.y,c.z,5000*vv.x,5000*vv.y,5000*vv.z); line(c.x,c.y,c.z,5000*inter2.x,5000*inter2.y,5000*inter2.z); line(0,0,0,-uu.x*5000,-uu.y*5000,-uu.z*5000); } //------------------------------------------------------- //------------------------------------------------------- //------------------------------------------------------- //------------------------------------------------------- static class Vecteur { float x, y, z; Vecteur() { } Vecteur(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } void place(float xx, float yy, float zz) { this.x = xx; this.y = yy; this.z = zz; } Vecteur normalize() { float length = length(); x /= length; y /= length; z /= length; return this; } float length() { return (float) Math.sqrt(x * x + y * y + z * z); } Vecteur cross(Vecteur v2) { Vecteur res = new Vecteur(); res.x = y * v2.z - z * v2.y; res.y =z * v2.x - x * v2.z; res.z = x * v2.y - y * v2.x; return res; } static float dot(Vecteur v1, Vecteur v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; } float dot(Vecteur v1) { return v1.x * x + v1.y *y + v1.z *z; } Vecteur mul( float d) { Vecteur res = new Vecteur(); res.x =x * d; res.y = y * d; res.z = z * d; return res; } static Vecteur comb(float a,Vecteur v1,float b, Vecteur v2) { float rx =a* v1.x + b*v2.x; float ry =a* v1.y + b*v2.y; float rz =a* v1.z + b*v2.z; return new Vecteur(rx,ry,rz); } Vecteur ajouter(Vecteur v,float m){ Vecteur res=new Vecteur(x+v.x*m, y+v.y*m,z+v.z*m); return res; } } //------------------------------------------------------------ // Quat class //------------------------------------------------------------ static class Quat { float w, x, y, z; Quat() { reset(); } Quat(float w, float x, float y, float z) { this.w = w; this.x = x; this.y = y; this.z = z; } Quat(float w, Vecteur v) { this.w = w; this.x =v. x; this.y = v.y; this.z = v.z; } Quat(Quat q) { set(q); } void reset() { w = 1.0f; x = 0.0f; y = 0.0f; z = 0.0f; } void set(float w, Vecteur v) { this.w = w; x = v.x; y = v.y; z = v.z; } void set(Quat q) { w = q.w; x = q.x; y = q.y; z = q.z; } void normalize() { float square = x * x + y * y + z * z + w * w; float dist = (square > 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; } float[] getValue() { // transforming this quat into an angle and an axis vector... float[] res = new float[4]; float sa = (float) Math.sqrt(1.0f - w * w); if (sa < EPSILON) { sa = 1.0f; } res[0] = (float) Math.acos(w) * 2.0f; res[1] = x / sa; res[2] = y / sa; res[3] = z / sa; return res; } Quat conjugue(){ return new Quat(w,-x,-y,-z); } }