
PDE Download: OOG1zSquareArrayFeedback.pde
JAVA Download: OOG1zSquareArrayFeedback.java
Click on anar+ terms to get the documentation.
import processing.opengl.*;
import anar.*;
Anar myScene;
Obj myObj;
Sliders mySliders;
int n = 10;
Param[] myArray;
Pt sun;
boolean[] clockwise;
float[] distance;
Obj faces;
void setup(){
size(1000,600,OPENGL);
Anar.init(this);
initForm();
initSun();
}
void initSun(){
// initialise distance array
distance = new float[myArray.length];
for (int i = 0; i<distance.length; i++)
distance[i] = 0;
// initialize turn direction array
clockwise = new boolean[myArray.length];
for (int i = 0; i<clockwise.length; i++)
clockwise[i] = true;
// create "sun"
sun = Anar.Pt(50,10,50);
myObj.add(sun);
// add "sun" parameters to sliders
mySliders = new Sliders();
mySliders.add(sun);
}
void initForm(){
// Create a new Object to store our shape
myObj = new Obj();
// Create another object to store faces htat will be oriented toward the
// "sun"
faces = new Obj();
// Create a vertical translation defining the height of tower floors
Transform tZ = new Translate(0,0,10);
Transform tX = new Translate(10,0,0);
// Create parameter array to store individual rotations values
// use linear array instead of 2-dimensional
myArray = new Param[n*n];
for (int i = 0; i<myArray.length/n; i++){
for (int j = 0; j<myArray.length/n; j++){
// transform 2 dimension i and j into linear index
int index = j+n*i;
// Create individual rotations randomly
myArray[index] = new Param(random(1.4f));
// Define position translation
Transform pos = new Transform();
for (int k = 0; k<j; k++){
pos.apply(tX);
}
for (int k = 0; k<i; k++){
pos.apply(tZ);
}
// Add module according to position and rotation parameter
myObj.add(createModule(pos,myArray[index]));
}
}
myObj.pts.render = new RenderPtsAll();
// Center on the object
Anar.camTarget(myObj);
}
void draw(){
background(150);
mySliders.draw();
myObj.draw();
updateParameters();
}
void keyPressed(){
// reset shape
if(key==' '){
initForm();
initSun();
}
}
Obj createModule(Transform t, Param p){
int edge = 10;
int h = 1;
// Create the base points (here a square)
// Create a new Face
Face mySquare = new Face();
mySquare.add(Anar.Pt( -edge/2,0, -edge/2));
mySquare.add(Anar.Pt(edge/2,0, -edge/2));
mySquare.add(Anar.Pt(edge/2,0,edge/2));
mySquare.add(Anar.Pt( -edge/2,0,edge/2));
Obj cube = new Extrude(mySquare,Anar.Pt(0,h,0));
Transform tt = new Transform();
tt.rotateZ(p);
tt.add(t);
cube.apply(tt);
// store face of the cube to compute distance to "sun"
// see update tab
faces.add(cube.face(5));
return cube;
}
void updateParameters(){
float hStep = 0;
// distance of measure point to surface
int h = 5;
// new object for displaying measure points
Obj points = new Obj();
for (int i = 0; i<faces.numOfFaces(); i++){
Face f = faces.face(i);
// find center of the face
float[] w = new float[f.numOfPts()];
for (int j = 0; j<w.length; j++)
w[j] = 1;
PtBary centre = new PtBary(f,w).normalizeWeight();
// create a point normal to the face at the center
PtNormal n = new PtNormal(f.pt(0),centre,f.pt(1),h);
// add normal to object for visualization
points.add(n);
// compute the distance to the "sun"
float dist = (float)n.length(sun);
float l = (float)centre.length(sun);
// compute step according to cosine theorem
// this approximation is planar so no variation in Z
hStep = acos( (sq(h)+sq(l)-sq(dist))/ (2*h*l));
// reduce amplitude to smooth movement
hStep /= 50;
// update parameters according to step
// either clockwise
if(clockwise[i]){
if(distance[i]>dist)
myArray[i].set(myArray[i].get()+hStep);
else{
myArray[i].set(myArray[i].get()-hStep);
clockwise[i] = false;
}
}
// or anti clockwise
else{
if(distance[i]>dist)
myArray[i].set(myArray[i].get()-hStep);
else{
myArray[i].set(myArray[i].get()+hStep);
clockwise[i] = true;
}
}
// store previous distance
distance[i] = dist;
}
points.draw();
}

|