
PDE Download: Test01aDeployRadERandom.pde
JAVA Download: Test01aDeployRadERandom.java
Click on anar+ terms to get the documentation.
import processing.opengl.*;
import processing.opengl.*;
import anar.*;
// import geometry.Point3D;
import java.util.*;
import rad.*;
/*
* Example for Anar library by Guillaume LaBelle + Julien Nembrini
* http://anar.ch
*/
Obj myObject;
Param angle = new Param(0.3f);
Param invAngle = new Param( -angle.get());
ArrayList<Element> deploy = new ArrayList<Element>();
Transform[] sides = new Transform[3];
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
void setup(){
// size(screen.width,screen.height,OPENGL);
size(1000,500,OPENGL);
Anar.init(this);
Anar.drawAxis(true);
simThread = new RadEngine(this,10f);
// generate random deployment
// must comply with max delta rule
newDeploy();
// /////////////////////////////////
// /////////////////////////////////
// PREPARE TRANSFORMS
// We limit the set of transforms to three different
// It will produce a limited set of different patterns
// The elementary operation
Translate modulor = new Translate(Anar.PtNull(0,0,3));
// Create 3 subsequent Transform from this one
// I use TransformLinear to combine them as a group
Transform sideA = new Transform();
sideA.add(modulor);
Transform sideB = new Transform();
sideB.add(modulor);
sideB.add(modulor);
Transform sideC = new Transform();
sideC.add(modulor);
sideC.add(modulor);
sideC.add(modulor);
// Then I have three different transforms from the first one
// They have different lengths
// Remark, I ends up with only one parameter
// Combine them in a table (it will be usefull when randomized)
// Here I need to remember that 0 is short, 1 normal and 2 is long
sides[0] = sideA;
sides[1] = sideB;
sides[2] = sideC;
// It's good for sides
myObject = generatorDeploy(deploy);
Face.globalRender = new RenderFaceDoubleSide(new AColor(255,180,180),new AColor(220));
}
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
void draw(){
if(frameCount%2==0)
background(255);
else
background(230);
myObject.draw();
// if(frameCount%1000==750) angle.set(0);
// if(frameCount%1000==999) angle.set(0.3f);
if( !isSimRunning){
myObject = growDeploy(deploy);
simThread.simulate(myObject);
simThread.runNow();
isSimRunning = true;
}
}
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
int A, B;
float energy;
Element(int _A, int _B, float _e){
A = _A;
B = _B;
energy = _e;
}
}
// start wiht two elements
static int nElement = 2;
static int maxDelta = 3;
static int maxModulor = 3;
// create new deployment random
void newDeploy(){
deploy.clear();
// Indeed also to track the difference between both (number of times between
// modulos)
// At the beginning they are both aligns
// -1 means that ptsB is from a distance 1 of modulor less than ptsA
// 2 means that ptsB is from a distance 2 of modulor more than ptsA
int delta = 0;
for (int i = 0; i<nElement; i++){
// Choose one translations from our set.
// (we won't accept delta to be too long as we want to keep the set of
// faces to a small set of cases
int lengthA, lengthB; // Correspond to sides[0,1,2]
do{
lengthA = (int)random(maxModulor);
lengthB = (int)random(maxModulor);
} while (Math.abs(lengthA-lengthB+delta)>maxDelta); // Here I limit the
// maximum sitance
// between paths (both
// ways)
// Update new delta state
delta += lengthA-lengthB;
deploy.add(new Element(lengthA,lengthB,0f));
}
}
Obj growDeploy(ArrayList<Element> d){
// add an element to the deployment
// in order to increase the energy gathered
// first compute delta
int delta = 0;
ListIterator<Element> it = d.listIterator();
while (it.hasNext()){
Element e = it.next();
delta += e.A-e.B;
}
// compute new element according to energy from last element
float energieAA = d.get(nElement-2).energy;
float energieA = d.get(nElement-1).energy;
int lengthA = 0;
int lengthB = 0;
// if energy is growing increase delta trend
if(energieAA<energieA){
if(delta>0&&delta<maxDelta){
lengthA = 2;
lengthB = 1;
}
else
if(delta<0&&delta> -maxDelta){
lengthA = 1;
lengthB = 2;
}
else{
lengthA = 1;
lengthB = 1;
}
}
// if energy decreases inverse delta trend
else{
if(delta>0){
lengthA = 1;
lengthB = 2;
}
else
if(delta<0){
lengthA = 2;
lengthB = 1;
}
else{
lengthA = 1;
lengthB = 1;
}
}
d.add(new Element(lengthA,lengthB,0f));
nElement++;
return generatorDeploy(d);
}
// //////////////////////////////////
// //////////////////////////////////
// //////////////////////////////////
Obj generatorDeploy(ArrayList<Element> d){
// /////////////////////////////////
// /////////////////////////////////
// INIT SOME CONTAINERS
Obj outputFmz = new Obj();
// Now let's create a rotation (let's keep it simple with only one rotation)
// On the chantier, it correspond to uniforms clips between panels
// I need to create a RotateZ as it will be used inside Allingn
// Allign will allign an axis to Z coordinate then apply a transform and
// Come back to initial state
RotateZ myRotation = new RotateZ(0.1f);
RotateZ myRotation2 = new RotateZ(0);
RotateZ myRotation3 = new RotateZ( -0.1f);
// /////////////////////////////////
// /////////////////////////////////
// ASSIGN TRANSFORMS
// I<ll create to lines and combine them later
Pts ptsA = new Pts();
Pts ptsB = new Pts();
// I need two initial points
// This is where I set the side length of the whole thing
Pt originA = Anar.Pt(0,0,0,"originA");
Pt originB = Anar.Pt(0,10,0,"originB");
// Add them to the list
ptsA.add(originA);
ptsB.add(originB);
// (Update) We need those POints to orient the translation
PtDER originAA = Anar.Pt(originA);
PtDER originBB = Anar.Pt(originB);
originAA.apply(sides[0]);
originBB.apply(sides[0]);
// Add them to the list
ptsA.add(originAA);
ptsB.add(originBB);
// As the form is an inerplay between aNewPoint and a previousPt
// I<ll create two fields to track them
// Note, it's not derrived, it is the point itself (Pt previousA =
// Anar.Pt(originA))
Pt previousA = originAA;
Pt previousB = originBB;
Pt previousAA = originA;
Pt previousBB = originB;
for (int i = 0; i<d.size(); i++){
// Create a points from previous (i label them - optional)
PtDER newPtA = Anar.Pt(previousA,"A"+i);
PtDER newPtB = Anar.Pt(previousB,"B"+i);
// Choose one translations from our set.
// Create Rotation from an axis (eachPoint is different
// allign need an axis of rotation (defined here by the two old resulting
// points (previuos)
// axis = previousA,previousB
Transform axisRotateA, axisRotateB;
if(random(2)>1){
axisRotateA = new Transform(previousA,previousB,myRotation);
axisRotateB = new Transform(previousA,previousB,myRotation);
}
else{
axisRotateA = new Transform(previousA,previousB,myRotation3);
axisRotateB = new Transform(previousA,previousB,myRotation3);
}
// Create a Translation alligned with the previous
// Remember that we don't know how is oriented the last face
Transform orientedTranslationA = new Transform(previousAA,previousA,sides[d.get(i).A]);
Transform orientedTranslationB = new Transform(previousBB,previousB,sides[d.get(i).B]);
// Apply to rotation to the translation
Transform comboA = new Transform();
comboA.add(orientedTranslationA);
comboA.add(axisRotateA); // From the beginning
Transform comboB = new Transform();
comboB.add(orientedTranslationB);
comboB.add(axisRotateB); // From the beginning
// Here's where evrything is set together pt with transform
newPtA.apply(comboA);
newPtB.apply(comboB);
// Alternative (if we don't want to apply the rotation
// Use this to see only the translation effect on a plane
// newPtA.set(sides[lengthA]);
// newPtB.set(sides[lengthB]);
// Put all that in that containers
ptsA.add(newPtA);
ptsB.add(newPtB);
// Swap Previuos
previousAA = previousA;
previousBB = previousB;
previousA = newPtA;
previousB = newPtB;
}
// /////////////////////////////////
// /////////////////////////////////
// RETURN EVRYTHING
// cREATE FACES FROM TWO LINES WITH SAME NUMBERS OF POINTS
outputFmz = new SweepTwoPaths(ptsA,ptsB);
// Cosmetik
print(ptsA);
print(ptsB);
// print(outputFmz.primitiveToString( -1));
TextIO.write("test.lsp",outputFmz.toAutocad());
ptsA.color(new AColor(0,0,255));
ptsB.color(new AColor(255,150,150));
return outputFmz;
}
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
// So Rad
boolean isSimRunning = true;
RadEngine simThread;
@Override
void radSimDone() {
isSimRunning = false;
// SwitchRender
// MetaRad.switchToAverageRender(myObject);
// here integrate energy results into deployment
ListIterator<Face> it = myObject.faces.listIterator();
int count = 0;
Face dummy = it.next();
while (it.hasNext()){
deploy.get(count).energy = ((RenderRadSim)it.next().render).energyDensityFront;
count++;
}
// myObject = transformatorDeploy(deploy);
}
void keyPressed(){
switch(key){
case 'q':
simThread.simulate(myObject);
simThread.runNow();
isSimRunning = true;
break;
case ' ':
// myObject = generatorDeploy();
break;
case 'w':
// MetaRad.switchRender(myObject);
break;
case 'e':
// MetaRad.switchToAverageRender(myObject);
break;
case 'p':
Scene.autoSeek = false;
break;
case 'r':
angle.set(0);
invAngle.set( -angle.get());
break;
case 't':
angle.set(0.3f);
invAngle.set( -angle.get());
break;
}
}
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////

|