float angleX,angleY,bangleX,bangleY,tempo,eloignement; Disque disque1,disque2,disque3,disque4,disque5; Vector trajet0,trajet1; boolean binitier; void setup(){ size(750,550); noStroke(); trajet0=new Vector(); trajet1=new Vector(); ellipseMode(CENTER_DIAMETER); initier(); } void loop(){ tempo+=0.01f; clear(); // background(225+15.0f*cos(tempo),225,245+10.0f*sin(tempo)); background(245+10.0f*cos(tempo*3),230,240+15.0f*sin(tempo*3)); dessinerTout(); } // ++++++++++++++++++++++++++++++++++++++++ void initier(){ float angle1,angle2,angle3,angle4,vitess2,vitess3; float erayon1,srayon1,erayon2,srayon2,erayon3,srayon3,erayon4,srayon4; binitier=false; eloignement=-18000; trajet0.removeAllElements(); trajet1.removeAllElements(); erayon1=random(1000,1600); srayon1=erayon1; erayon2=random(1500,2000); srayon2=random(1000,1900); erayon3=random(1000,2000); srayon3=100; erayon4=1000; srayon4=1000; angle1=random(-1.5f,-1f); angle2=random(1.2f,1.6f); angle3=random(-2f,-1f); angle4=random(0.5f,1f); vitess2=random(0.01f,0.04f); vitess3=random(0.01f,0.04f); disque1=new Disque(erayon1,srayon1,1000,angle1,angle1,-1000,0); disque2=new Disque(erayon2,srayon2,-3500,angle2,angle1,srayon1,vitess2); disque3=new Disque(erayon3,srayon3,2500,angle3,angle2,srayon2,vitess3); disque4=new Disque(erayon4,srayon4,1000,angle1,angle4,srayon3,0.07f); disque5=new Disque(); tempo=0; } // ++++++++++++++++++++++++++++++++++++++++ void modifierparam(){ bangleX=(height/2-mouseY)/100.0f; bangleY=-(width/2-mouseX)/100.0f;// angleX+=(bangleX-angleX)/10.0f; angleY+=(bangleY-angleY)/10.0f; } void mousePressed(){ initier(); } // ++++++++++++++++++++++++++++++++++++++++ void dessinerTout(){ modifierparam(); push();//dans le repere absolu repere1(); disque1.dessiner(disque2,false); disque2.dessiner(disque3,false); disque3.dessiner(disque4,true); Vecteur w=coorabs(1500,0,0); Vecteur w1=coorabs(-1000,0,0); pop();//retour dans le repere absolu trajetAdd( w,w1); repere1(); afficherTrajet(); } // +++++++++++++++++++++++++++++++++++ void repere1(){ translate(200,0,eloignement); rotateX(angleX); rotateY(angleY); } // ******************************************* void trajetAdd(Vecteur w,Vecteur w1){ push(); rotateY(-angleY); rotateX(-angleX); translate(-200,0,-eloignement); w=coorabs(w.x,w.y,w.z); w1=coorabs(w1.x,w1.y,w1.z); pop(); trajet0.addElement(w); trajet1.addElement(w1); if(trajet0.size()>300){ trajet0.removeElementAt(0); trajet1.removeElementAt(0);} } // ++++++++++++++++++++++++++++++++++++++++ // +++++++++++++++++++++++++++++++++++ void afficherTrajet(){ Vecteur v0,v1,v,vp,vv,ww,no,coul; float cot=cos(tempo*2); float sit=sin(tempo*2); noStroke(); beginShape(QUAD_STRIP); for(int i=trajet0.size()-1;i>0;i--){ v0=(Vecteur)trajet0.elementAt(i-1); v=(Vecteur)trajet0.elementAt(i); vp=(Vecteur)trajet1.elementAt(i); vv=vp.ajouter(v,-1); ww=v.ajouter(v0,-1); no=(vv.cross(ww)).normalize(); coul=(new Vecteur(0.5f*cot,4*sit*cot,0.5f+2*cot*sit)).normalize(); float scal=255-255*(abs(Vecteur.dot(no,coul))); float transparent=(i<100)? 160.0f*(i/100.0f):160; fill(190+0.3f*scal,185+0.3f*scal,180+0.3f*scal,transparent); if(i%2==0){ vertex(v.x,v.y,v.z); vertex(vp.x,vp.y,vp.z);} else{ vertex(vp.x,vp.y,vp.z); vertex(v.x,v.y,v.z); } } endShape(); beginShape(QUAD_STRIP); for(int i=trajet0.size()-1;i>0;i--){ v0=(Vecteur)trajet0.elementAt(i-1); v=(Vecteur)trajet0.elementAt(i); vp=(Vecteur)trajet1.elementAt(i); vv=vp.ajouter(v,-1); ww=v.ajouter(v0,-1); no=(vv.cross(ww)).normalize(1.7f); coul=(new Vecteur(cot,4*sit*cot,3+2*cot*sit)).normalize(); float scal=255-255*(abs(Vecteur.dot(no,coul))); float transparent=(i>100)? 140: 140.0f*i/100.0f; fill(0.4f*scal+130,0.4f*scal+130,0.6f*scal+190,transparent); no=no.normalize(500); if(i%2==0){ vertex(v.x,v.y,v.z); vertex(v.x+no.x,v.y+no.y,v.z+no.z);} else{ vertex(v.x+no.x,v.y+no.y,v.z+no.z); vertex(v.x,v.y,v.z); } } endShape(); } // ++++++++++++++++++++++++++++++++++++++++ Vecteur coorabs(float x,float y,float z) { float xa = objectX(x, y, z); float ya = objectY(x, y, z); float za = objectZ(x, y, z); return new Vecteur(xa, ya, za); } // ++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++ class Disque{ float x,y,rentree,rsortie,longaxe,phi,iphi,diedre,anglentraineur,rent; public Disque(float rentree,float rsortie,float longaxe,float a,float anglentraineur,float rent,float iphi){ this.rentree=rentree; this.rsortie=rsortie; this.diedre=a; this.phi=0; this.iphi=iphi; this.longaxe=longaxe; this.anglentraineur=anglentraineur; this.rent= rent; } public Disque(){ } void dessiner(Disque disqueSuivant,boolean extreme){ phi+=iphi; fill(155); rotateZ(phi); noStroke(); dessinerCone(rentree,anglentraineur);//cone entrée dessinerAxe(); if(rsortie!=rentree && !extreme){ translate(0,0,longaxe); fill(155); dessinerCone(rsortie,diedre);//le cone sortie } //on met en place le train suivant if(!extreme){ rotateZ(disqueSuivant.phi*disqueSuivant.rentree/rsortie); translate(rsortie,0,0); rotateY(diedre); translate(disqueSuivant.rentree,0,0);} else{ translate(1500,0,2.8f*longaxe-100); box(3000,200,200); } } void dessinerAxe(){ fill(130,30,120); float laxe=longaxe*2.8f; float al=laxe+rentree/tan(anglentraineur)+rent/sin(anglentraineur); push(); translate(0,0,laxe-al/2); box(200,200,-al); pop(); } void dessinerCone(float rr,float angdiedre){ float rs=rr-1500*cos((PI-angdiedre)/2); float h=-1500*sin((PI-angdiedre)/2); float inctheta=100*PI/rr; beginShape(QUAD_STRIP); for(float i=0;i<6.41f; i=i+inctheta){ float i1=i+0.05f; float cosi=cos(i); float sini=sin(i); fill(210+30*cosi,215+35*cosi,210+40*cosi); vertex(rr*cosi,rr*sini,0); vertex(rs*cosi,rs*sini,h); fill(100+30*sini,97+30*sini,100+30*sini); vertex(rs*cos(i1),rs*sin(i1),h); vertex(rr*cos(i1),rr*sin(i1),0); } endShape(); beginShape(QUADS); for(float i=0;i<6.41f; i=i+inctheta*4){ float i1=i+0.2f; float cosi=cos(i); float sini=sin(i); fill(230+20*cosi,210+15*cosi,230+20*cosi); vertex(rr*cosi,rr*sini,0); vertex(rs*cosi,rs*sini,h); fill(50+20*sini,30+15*sini,50+10*sini); vertex(0,0,h); vertex(0,0,0); } endShape(); } } //------------------------------------------------------- //------------------------------------------------------- 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 void set(Vecteur v) { this.x = v.x; this.y =v.y; this.z = v.z; } 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 static Vecteur barycentre(float a,Vecteur v1,float b, Vecteur v2) { Vecteur res=comb(a,v1,b,v2); res=res.mul(1/(a+b)); return res; } 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.0f); return res; } public float distancePointDroite(Vecteur d, Vecteur v){ v.normalize(); Vecteur pd=d.ajouter(this,-1); Vecteur hd=v.mul(v.dot(pd)); Vecteur ph=pd.ajouter(hd,-1); return ph.length(); } 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 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,float lon){ ba.stroke(255,0,0); ba.line(0,0,0,lon,0,0); ba.stroke(0,255,0); ba.line(0,0,0,0,lon,0); ba.stroke(0,0,255); ba.line(0,0,0,0,0,lon); } 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); } }