//Jacques Maire : tondeuse
//mardi 27 avril 2012
import remixlab.proscene.*;
Scene scene;
Ruban ruban0, ruban1;
Balle[] balles;
PVector origine=new PVector(0, 0, 0);
float angl, cycl;
int nbb,nlignes,ncolonnes;
float[][] hauteurs;
void setup() {
size(890, 800, P3D);
scene= new Scene(this);
nbb=2;nlignes=80; ncolonnes=100;
hauteurs=new float[ncolonnes][nlignes];
for(int i=0;i<ncolonnes;i++){for(int j=0;j<nlignes;j++){ hauteurs[i][j]=700;}}
balles=new Balle[nbb];
for (int i=0;i<nbb;i++) {
balles[i]=new Balle(random(0, 1), random(0, 1), random(0.002, 0.006), random(0.002, 0.006));
}
InteractiveFrame reper0=new InteractiveFrame(scene);
reper0.setPosition(new PVector( 4500, 5000, 6000));
InteractiveFrame reper1=new InteractiveFrame(scene);
reper1.setPosition(new PVector( -8000, 7000, 0 ));
ruban0=new Ruban(reper0, reper1, 0);
InteractiveFrame reper2=new InteractiveFrame(scene);
reper2.setPosition(new PVector(6000, -9000, -5000));
InteractiveFrame reper3=new InteractiveFrame(scene);
reper3.setPosition(new PVector( -8500, -10000, -7000));
ruban1=new Ruban(reper2, reper3, 1);
scene.setGridIsDrawn(false);
scene.setAxisIsDrawn(false);
scene.camera().setPosition(new PVector(0, 0, 20000));
cycl=1.8;
frameRate(36);
}
void draw() {
background(230);
angl=millis()/20000.0;
directionalLight(255, 255, 255, -1, 1, -1);
//directionalLight(255, 155, 255, -1, -1, 1);
ruban0.repere0.rotate(new Quaternion(new PVector(1+2*cos(angl), 3*sin(angl), 0.2*cos(angl)), 0.05));
ruban0.repere1.rotate(new Quaternion(new PVector(0.2*sin(angl), 0.3*cos(angl*0.5), 0.3*cos(angl)), 0.05));
ruban1.repere0.rotate(new Quaternion(new PVector(1+2.1*cos(angl), 0.4*sin(angl), 1.3*cos(2*angl)), 0.1));
ruban1.repere1.rotate(new Quaternion(new PVector(1+2*sin(angl), 0.3*cos(angl*0.5), 2.1*cos(3*angl)), 0.12));
ruban0.draw();
ruban1.draw();
positionsIntermediaires();
for (int i=0;i<nbb;i++) {
balles[i].draw();
}
}
void ligne(PVector u, PVector v) {
line(u.x, u.y, u.z, v.x, v.y, v.z);
}
void positionsIntermediaires() {
strokeWeight(3);
PVector v0, w0, wj,pwj, v1, w1;
w0=ruban0.posTrajectoire(0.002);
w1=ruban1.posTrajectoire(0.002);
for (int i=1;i<ncolonnes;i++) {
v0=ruban0.posTrajectoire((float)i/ncolonnes);
v1=ruban1.posTrajectoire((float)i/ncolonnes);
for(int j=0;j<nlignes;j++){
float jj=(float)j/nlignes;
wj=comb(jj,v0,1-jj,v1);
pwj=comb(jj,w0,1-jj,w1);
PVector orth=PVector.sub(wj,pwj).cross(PVector.sub(v0,v1));
orth.normalize();
stroke(30,30,90);
ligne(comb(1,wj,hauteurs[i][j],orth),comb(1,wj,-hauteurs[i][j],orth));
}
noStroke();
beginShape(TRIANGLES);
fill(240, 240, 250);
vertex(v1.x, v1.y, v1.z);
vertex(w1.x, w1.y, w1.z);
vertex(v0.x, v0.y, v0.z);
vertex(w1.x, w1.y, w1.z);
vertex(v0.x, v0.y,v0.z);
vertex(w0.x, w0.y, w0.z);
endShape(CLOSE);
w1=v1.get();
w0=v0.get();
}
}
PVector comb(float t1, PVector v1, float t2, PVector v2) {
PVector res=PVector.add(PVector.mult(v1, t1), PVector.mult(v2, t2));
return res;
}
void mousePressed() {
cycl+=0.5;
if (cycl>4) cycl=0;
}
class Balle{
InteractiveFrame repere;
float incx,incy,parax,paray,rayon;
PVector pw,pwp;
int couleur;
Balle(float px,float py,float ix,float iy){
repere=new InteractiveFrame(scene);
incx=ix;
incy=iy;
parax=px;
paray=py;
pwp=new PVector();
couleur=color(random(100,255), random(100,255),random(100,255));
rayon=random(500,1000);
}
void draw(){
PVector pv0=ruban0.posTrajectoire(parax);
PVector pv1=ruban1.posTrajectoire(parax);
pw=comb(paray,pv0,1-paray,pv1);
repere.setPosition(pw);
PVector orth=PVector.sub(pw,pwp).cross(PVector.sub(pv0,pv1));
orth.normalize();
stroke(couleur);strokeWeight(10);
ligne(comb(1,pw,-1500-rayon,orth),comb(1,pw,1500+rayon,orth));
pwp=pw.get();
pushMatrix();
repere.applyTransformation();
fill(couleur);
noStroke();
sphere(rayon);
popMatrix();
for(int u=-2;u<3;u++){ for(int v=-2;v<3;v++){
int nx=floor(parax*ncolonnes+u);
int ny=floor(paray*nlignes+v);
hauteurs[constrain(nx,0,ncolonnes-1)][constrain(ny,0,nlignes-1)]=20;}}
parax+=incx;
paray+=incy;
if((parax>1)||(parax<0)){incx*=-1;parax+=2*incx;}
if((paray>1)||(paray<0)){incy*=-1;paray+=2*incy;}
}
}
class Ruban{
int numero;
InteractiveFrame repere0,repere1;
Ruban(InteractiveFrame r0,InteractiveFrame r1,int n){
repere0=r0;
repere1=r1;
numero=n;
}
void draw() {
pushMatrix();
stroke(0);
repere0.applyTransformation();
//println(" 0 "+repere0.position());
noStroke();
fill(255,0,0);
sphere(100);
popMatrix();
pushMatrix();
repere1.applyTransformation();
// println(" 1 "+repere1.position()+" ***");
sphere(100);
popMatrix();
}
PVector posTrajectoire(float i) {
PVector u, v;
float ku, kv;
float cy0=TWO_PI*i*(cycl-2*numero);
float cy1=TWO_PI*i*(cycl-2*numero+1);
ku=5400.0*i+20;
kv=-4200*(1-i)+20;
u=new PVector(ku*cos(cy0), ku*sin(cy0), 0);
v=new PVector(kv*cos(cy1), kv*sin(cy1), 0);
u=repere0.inverseCoordinatesOf(u);
v=repere1.inverseCoordinatesOf(v);
return comb((1-i), u, i, v);
}
}
Click on the image to change the winding
right click and drag the red spheres
built with proscene