//Alcys_Distortion 26/10/04 Vecteur z, fz, souris, centre; BImage a; BImage[][] carre; float xc, yc, zc, dx, dy; Quat reference; float tempo, angl; int wa,ha,had,wad,nbpetal,incnb; void setup() { xc= 10f; yc= -10; zc= -20000;nbpetal=24;incnb=2; a= loadImage("gre-rouge1.jpg"); wa=a.width;ha=a.height;had=ha/10;wad=wa/10; noStroke(); size(500, 400); background(50,100,170); carre= new BImage[10][10]; for (int i= 0; i < 10; i++) { for (int j= 0; j < 10; j++) { carre[i][j]= new BImage(wad, had); for (int ii= 0; ii < wad; ii++) { for (int jj= 0; jj < had; jj++) { carre[i][j].pixels[ii + wad * jj]= a.pixels[ii + wad * i + wa * (had * j + jj)]; } } } } } void loop() { clear(); push(); dx= 80+0.15f * (height / 2 - mouseY); dy=100+ 0.25f * (width / 2 - mouseX); translate(xc, yc, zc); rotateY(0.01f * (mouseX - 85)); tempo += 0.01f; angl= 0.8f * cos(tempo) + 1.5f * sin(3 * tempo); conformer(); pop(); } void mouseReleased(){ nbpetal+=incnb;println(nbpetal); if(nbpetal<3||nbpetal>22){incnb*=-1;nbpetal+=2*incnb;} } void conformer() { float cc=0.014f; float dd=0.012f; int x, y; reference= new Quat(cos(0.4f*tempo), -2.5f*cos(2*tempo), 2.5f*sin(tempo), 0.2f*cos(2*tempo)); reference.normalize(); for (y= 0; y < 10; y++) { for (x= 0; x < 10; x++) { Vecteur z0= calculer((wad * x - dx)*cc, (had * y - dy)*dd); Vecteur z1= calculer( (wad * x - dx + wad)*cc, (had * y - dy)*dd); Vecteur z2= calculer( (wad * x - dx + wad)*cc, (had * y + had - dy)*dd); Vecteur z3= calculer( (wad * x - dx)*cc, (had * y + had - dy)*dd); noStroke(); for (int i= 0; i < nbpetal; i++) { push(); rotateZ(i * TWO_PI / nbpetal); beginShape(QUADS); texture(carre[x][y]); vertex(z0.x, z0.y, z0.z, 0, 0); vertex(z1.x, z1.y, z1.z, wad, 0); vertex(z2.x, z2.y, z2.z, wad, had); vertex(z3.x, z3.y, z3.z, 0, had); endShape(); pop(); } } } } Vecteur calculer(float px, float py) { Quat q= new Quat(4.3f+0.4f*cos(angl), px*cos(2*tempo)-py*sin(tempo), px*sin(tempo)+py*cos(2*tempo) , -1.1f*angl); Quat fq= Quat.comb(q.muldroite(q), 8f, q, 8.0f); Quat iq= (fq.conjugue().muldroite(reference)).muldroite(fq); Vecteur v= iq.axe(); Vecteur vcorrige= (v.mul(0.10f)); return vcorrige; } //------------------------------------------------------------ // Quat class //------------------------------------------------------------ static class Quat { float w, x, y, z; public Quat() { reset(); } public Quat(float w, float x, float y, float z) { this.w = w; this.x = x; this.y = y; this.z = z; } public Quat(float w, Vecteur v) { this.w = w; this.x =v. x; this.y = v.y; this.z = v.z; } public Quat(Quat q) { set(q); } public void reset() { w = 1.0f; x = 0.0f; y = 0.0f; z = 0.0f; } public void set(float w, Vecteur v) { this.w = w; x = v.x; y = v.y; z = v.z; } public void set(Quat q) { w = q.w; x = q.x; y = q.y; z = q.z; } public void setz(float f) { z = f; } public void setx(float f) { x = f; } public void sety(float f) { y = f; } public void setxyz(float f0,float f1,float f2) { x=f0; y = f1;z=f2; } public float norme(){ return (float)Math.sqrt(x * x + y * y + z * z + w * w); } public 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; } public 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; } public Quat muldroite(Quat q2){ return mul(this,q2); } public Quat mulgauche(Quat q2){ return mul(q2,this); } public 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; } public 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; } public Quat conjugue(){ return new Quat(w,-x,-y,-z); } public Quat oppose(){ return new Quat(-w,-x,-y,-z); } public Quat copie(){ return new Quat(w,x,y,z); } public Quat copieNorme(){ Quat res=new Quat(w,x,y,z); res.normalize(); return res; } public 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); } public 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; } public 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; } public Vecteur axe(){ return new Vecteur(x,y,z); } public void appliqueQuat(BApplet ba){ float[] ro=getValue(); ba.rotate(ro[0],ro[1],ro[2],ro[3]); } } //------------------------------------------------------- //------------------------------------------------------- public static class Vecteur { public float x, y, z; public Vecteur() { } public Vecteur(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } public Vecteur(float x, float y, float z,float lon) { float no=(float) Math.sqrt(x * x + y * y + z * z); no=lon/no; this.x = x*no; this.y = y*no; this.z = z*no; } public void place(float xx, float yy, float zz) { this.x = xx; this.y = yy; this.z = zz; } public Vecteur normalize() { float length = length(); x /= length; y /= length; z /= length; return this; } public Vecteur normalize(float k) { float length = length(); x=x/ length*k; y =y/ length*k; z =z/ length*k; return this; } public float length() { return (float) Math.sqrt(x * x + y * y + z * z); } public 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; } public static float dot(Vecteur v1, Vecteur v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; } public float dot(Vecteur v1) { return v1.x * x + v1.y *y + v1.z *z; } public Vecteur mul( float d) { Vecteur res = new Vecteur(); res.x =x * d; res.y = y * d; res.z = z * d; return res; } public 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); } public Vecteur ajouter(Vecteur v,float m){ Vecteur res=new Vecteur(x+v.x*m, y+v.y*m,z+v.z*m); return res; } public Vecteur ajouter(float ax,float ay,float az){ Vecteur res=new Vecteur(x+ax, y+ay,z+az); return res; } public void afficher(String tex,BApplet ba){ ba.println(tex+"x= "+x+" y= "+y+" z= "+z); } public Vecteur projete(Vecteur laxe){ laxe.normalize(); Vecteur res=laxe.mul(this.dot(laxe)); return res; } public Vecteur projeteSurAxe(Vecteur laxe){ laxe.normalize(); Vecteur res=laxe.mul(this.dot(laxe)); return res; } public Vecteur projeteSurPlan(Vecteur laxe){ laxe.normalize(); Vecteur res=projeteSurAxe(laxe); res=this.ajouter(res,-1); return res; } public Vecteur symetrique(Vecteur laxe){ laxe.normalize(); Vecteur res=projeteSurAxe(laxe); res=this.ajouter(res,-2); return res; } /*projection sur le plan vectoriel de normale "laxe" public Vecteur projeteSurPlan(Vecteur laxe,Vecteur unpoint){ laxe.normalize(); Vecteur res=projeteSurPlan(laxe); return res.ajouter(unpoint.projeteSurAxe(res),1); }*/ public float donneAngle(Vecteur vc){ return (float) Math.acos(this.dot(vc)/(length()*vc.length())); } public Vecteur tourner(Vecteur axe,float angle){//axe est normé et orthogonal à this Vecteur vaxe=axe.mul(this.dot(axe)); Vecteur vx=this.ajouter(vaxe,-1); Vecteur ygrec=axe.cross(this); return vaxe.ajouter(Vecteur.comb((float)Math.cos(angle),this,(float)Math.sin(angle),ygrec),1); } public Vecteur cloner() { Vecteur res = new Vecteur(); res.x =x ; res.y = y ; res.z = z ; return res; } public Vecteur tourner(float a,Vecteur ax){ Quat qv=new Quat(0.0f,x,y,z); Quat q0=new Quat((float)Math.cos(a/2),ax.mul((float)Math.sin(a/2))); Quat qc=q0.conjugue(); Quat q1=Quat.mul(qv,qc); Quat q= Quat.mul(q0,q1); return new Vecteur(q.x,q.y,q.z); } public Vecteur coorabs(BApplet ba) { float xa = ba.objectX(x,y,z); float ya = ba.objectY(x,y,z); float za = ba.objectZ(x,y,z); return new Vecteur(xa, ya, za); } // ******************************************* // ******************************************* // ******************************************* public static void afficherRepere(BApplet ba){ ba.stroke(255,0,0); ba.line(0,0,0,500,0,0); ba.stroke(0,255,0); ba.line(0,0,0,0,500,0); ba.stroke(0,0,255); ba.line(0,0,0,0,0,500); } // ******************************************* // ******************************************* // ******************************************* public void afficherLigne(float k,BApplet ba){ ba.line(x*k,y*k,z*k,-x*k,-y*k,-z*k); } }