This browser does not have a Java Plug-in.
Get the latest Java Plug-in here.

anar+

by   LaBelle + Nembrini
©2008

built with ( )
   examples index
Rotate: middle click or key[1]
Zoom in|out: wheel button or key[2]
AutoRotate: key[5]
(First Click inside the applet to enable keys)

This applet use OpenGL, you might have to install extra jogl libraries once to view this applet. You may have a look at image capture and video at the bottom of this page. You might accept security security permenently to remove the security prompts on each pages.



sourcecode


   PDE Download:   Test01aDeployRadHGlobalB.pde
   JAVA Download:   Test01aDeployRadHGlobalB.java


Click on anar+ terms to get the documentation.

import processing.opengl.*;
import processing.opengl.*;
import anar.*;
 
// import geometry.Point3D;
 
 
 
import java.util.ArrayList;
 
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());
 
 
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
 
void setup(){
 
    // size(screen.width,screen.height,OPENGL);
    size(1000,500,OPENGL);
  Anar.init(this);
  Anar.drawAxis(true);
 
  simThread = new RadEngine(this,10f);
 
  generatorTranslationLimitedSet();
  generatorRotationLimitedSet();
  generatorInit();
 
  generatorAddOneFace();
 
  Face.globalRender = new RenderFaceDoubleSide(new AColor(255,180,180),new AColor(220));
}
 
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
 
 
void draw(){
  if(frameCount%2==0)
    background(255);
  else
    background(254);
 
  myObject.draw();
  if(isAddingFace&& !isSimRunning)
    generatorAddOneFace();
 
  // angle.set(angle.get()+0.01f);
  // invAngle.set( -angle.get());
}
 
 
boolean isAddingFace = false;
 
 
void keyPressed(){
 
  switch(key){
    case 'q':
        simThread.simulate(myObject);
        simThread.runNow();
      isSimRunning = true;
    break;
    case ' ':
      generatorAddOneFace();
    break;
    case 'w':
//        MetaRad.switchRender(myObject);
    break;
    case 'm':
//        Iterator<Face> i = myObject.faces.iterator();
//        while (i.hasNext())
//          ((MetaRad)i.next().meta).switchToMeshRender();
    break;
    case 'n':
//        Iterator<Face> j = myObject.faces.iterator();
//        while (j.hasNext())
//          ((MetaRad)j.next().meta).switchToMeshRenderWithValues();
    break;
    case 'e':
//        MetaRad.switchToAverageRender(myObject);
    break;
    case 'p':
      Scene.autoSeek = false;
    break;
    case 'o':
      isAddingFace = (isAddingFace) ? false:true;
    break;
    case 'r':
      angle.set(0);
      invAngle.set( -angle.get());
    break;
    case 't':
      angle.set(0.3f);
      invAngle.set( -angle.get());
    break;
    case 'a':
      TextIO.write( ((Object)this).getClass().getName()+".lsp",myObject.toAutocad());
    break;
    case 'i':
      ((Architronik)myBots.get((int)random(myBots.size()))).randomChange();
    break;
    case 'u':
      ((Architronik)myBots.get((int)random(myBots.size()-1)+1)).transformFormEnergy();
    break;
 
  }
 
}
 
 
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
Transform[] sides;
 
void generatorTranslationLimitedSet(){
  // 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,5));
 
 
  // Create 3 subsequent Transform from this one
  // I use TransformLinear to combine them as a group
  Transform side0 = new Transform();
  side0.add(modulor);
 
  Transform side1 = new Transform();
  side1.add(modulor);
  side1.add(modulor);
 
  Transform side2 = new Transform();
  side2.add(modulor);
  side2.add(modulor);
  side2.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 = new Transform[3];
  sides[0] = side0;
  sides[1] = side1;
  sides[2] = side2;
}
 
 
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
 
Transform[] rotations;
 
void generatorRotationLimitedSet(){
  // It's good for sides
  // 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(angle);
  RotateZ myInvRotation = new RotateZ(invAngle);
 
  Transform rotation_2 = new Transform();
  rotation_2.add(myInvRotation);
  rotation_2.add(myInvRotation);
 
  Transform rotation_1 = new Transform();
  rotation_1.add(myInvRotation);
 
  Transform rotation0 = new Transform();
 
  Transform rotation1 = new Transform();
  rotation1.add(myRotation);
 
  Transform rotation2 = new Transform();
  rotation2.add(myRotation);
  rotation2.add(myRotation);
 
  rotations = new Transform[5];
  rotations[0] = rotation_2;
  rotations[1] = rotation_1;
  rotations[2] = rotation0;
  rotations[3] = rotation1;
  rotations[4] = rotation2;
}
 
 
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
 
 
Pts   ptsA         = new Pts();
Pts   ptsB         = new Pts();
 
PtABS totalOriginA = Anar.Pt(0,0,0,"originA");
 
void generatorInit(){
  myObject = new Obj();
 
  ptsA = new Pts();
  ptsB = new Pts();
 
  ptsA.color(new AColor(0,0,255));
  ptsB.color(new AColor(255,150,150));
 
  // I need two initial points
  // This is where I set the side length of the whole thing
  Pt originA = totalOriginA;
  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))
  previousA = originAA;
  previousB = originBB;
 
  previousAA = originA;
  previousBB = originB;
 
}
 
 
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
 
Pt          previousA;
Pt          previousB;
Pt          previousAA;
Pt          previousBB;
 
int         delta     = 0;
int         faceCount = 0;
 
float       energieA  = 0;
float       energieAA = 0;
 
Architronik lastAddedFace;
 
void generatorAddOneFace(){
 
 
  energieAA = energieA;
  if(myObject.faces.size()>1){
    Face lastFace = myObject.faces.get(myObject.faces.size()-1);
    energieA = ((RenderRadSim)lastFace.render).energyDensityFront;
  }
 
  PtDER newPtA = Anar.Pt(previousA,"A"+faceCount);
  PtDER newPtB = Anar.Pt(previousB,"B"+faceCount++);
 
  // 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(sides.length);
  // lengthB = (int)random(sides.length);
  // } while (Math.abs(lengthA-lengthB+delta)>3); //Here I limit the maximum
  // sitance between paths (both ways)
  // if energy is growing increase delta trend
 
  println(">>"+energieA+" - "+energieAA+" - "+delta);
 
  int maxDelta = 3;
 
  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{
        if((float)Math.random()>0.5f){
          lengthA = 2;
          lengthB = 1;
        }
        else{
          lengthA = 1;
          lengthB = 2;
        }
 
      }
  }
  println(">>"+lengthA+" - "+lengthB);
 
  // Update new delta state
  delta += lengthA-lengthB;
 
 
  // 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 rotmp = rotations[3];
 
  Transform axisRotateA = new Transform(previousA,previousB,rotmp);
  Transform axisRotateB = new Transform(previousA,previousB,rotmp);
 
 
  // 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[lengthA]);
  Transform orientedTranslationB = new Transform(previousBB,previousB,sides[lengthB]);
 
 
  // 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);
 
  // Put all that in that containers
  ptsA.add(newPtA);
  ptsB.add(newPtB);
 
  // Swap Previuos
  previousAA = previousA;
  previousBB = previousB;
 
  previousA = newPtA;
  previousB = newPtB;
 
  // myObject = null;
  myObject = new SweepTwoPaths(ptsA,ptsB);
 
  // http://www.javaworld.com/javaworld/javaqa/1999-08/04-qa-leaks.html
  // http://www.ibm.com/developerworks/java/library/j-leaks/
  // Java HeapSpace May Come from this...
  // Runtime r = Runtime.getRuntime();
  // long freeMem = r.freeMemory();
  // Anar.println("FreeHeapMem: " + freeMem);
  // Anar.println("-------------------");
 
  simThread.simulate(myObject);
  simThread.runNow();
  isSimRunning = true;
 
 
  // energieA = ((MetaRad)lastFace.meta).energyDensityUp;
 
  Face thisFace = myObject.faces.get(myObject.faces.size()-1);
 
  Architronik thisArchi;
 
  if(lastAddedFace!=null){
    thisArchi = new Architronik(thisFace,lastAddedFace);
  }
  else{
    thisArchi = new Architronik(thisFace);
  }
 
  myBots.add(thisArchi);
  lastAddedFace = thisArchi;
}
 
ArrayList myBots = new ArrayList();
 
 
  Face        curr;
  Architronik next;
 
  // TransformLinear sideA;
  // TransformLinear sideB;
 
  int         thisdelta;
 
  Architronik(Face cur){
    this.curr = cur;
  }
 
  Architronik(Face cur, Architronik pre){
    this(cur);
    this.next = pre;
  }
 
  int lengthA = 0;
  int lengthB = 0;
 
  int totalA(){
    int total = getSide(2).numOfParents();
    if(next!=null)
      total += next.totalA();
    return total;
  }
 
  int totalB(){
    int total = getSide(3).numOfParents();
    if(next!=null)
      total += next.totalB();
    return total;
  }
 
  void updatyeThisDelta(){
    thisdelta = totalA()-totalB();
    lengthA = getSide(2).numOfParents();
    lengthB = getSide(3).numOfParents();
  }
 
 
  void setSide(int k, int j){
    curr.pt(k).parent(1).parent(0).replaceParent(0,sides[j]);
  }
 
  Transform getSide(int k){
    return (Transform)curr.pt(k).parent(1).parent(0).parent(0);
  }
 
 
  void randomChange(){
    // Anar.println("*"+((Object)getSide(2)).getClass().getName());
    updatyeThisDelta();
    setSide(2,(int)random(3));
    setSide(3,(int)random(3));
    Anar.println("*A:"+totalB()+" B:"+totalA()+" delta:"+thisdelta);
  }
 
  void transformFormEnergy(){
    updatyeThisDelta();
 
    float energieCurr = ((RenderRadSim)curr.render).energyDensityFront;
    float energieNext = ((RenderRadSim)next.curr.render).energyDensityFront;
 
 
    int maxModulor = 2;
    int maxDelta = 3;
 
 
    // if current element has more energy than next
    if(energieCurr>energieNext){
      // if no angle increase its size without changing orientation
      if( (lengthA==lengthB)&& (lengthA<maxModulor)){
        lengthA++;
        lengthB++;
      }
      // if angle (A>B) increase it if possible
      else
        if( (delta<maxDelta)&& (lengthA>lengthB)&& (lengthA<maxModulor)){
          lengthA++;
          thisdelta++;
        }
        // if angle (B>A) increase it if possible
        else
          if( (thisdelta> -maxDelta)&& (lengthA<lengthB)&& (lengthB<maxModulor)){
            lengthB++;
            thisdelta--;
          }
 
    }
    else{
      // if no angle decrease its size without changing orientation
      if( (lengthA==lengthB)&& (lengthA>0)){
        lengthA--;
        lengthB--;
      }
      // if no angle & smallest size, choose angle that decrease thisdelta
      if( (lengthA==lengthB)&& (lengthA==0)){
        if(thisdelta>0){
          lengthB++;
          thisdelta--;
        }
        else{
          lengthA++;
          thisdelta++;
        }
      }
      // if angle (A>B) decrease it if possible
      else
        if( (thisdelta> -maxDelta)&& (lengthA>lengthB)){
          lengthA--;
          thisdelta--;
        }
        // if angle (B>A) decrease it if possible
        else
          if( (thisdelta<maxDelta)&& (lengthA<lengthB)){
            lengthB--;
            thisdelta++;
          }
 
    }
 
    if(lengthA<0)
      lengthA = 0;
    if(lengthA>maxModulor)
      lengthA = maxModulor;
 
    if(lengthB<0)
      lengthB = 0;
    if(lengthB>maxModulor)
      lengthB = maxModulor;
 
 
    next.setSide(2,lengthA);
    next.setSide(3,lengthB);
 
 
    simThread.simulate(myObject);
    simThread.runNow();
    isSimRunning = true;
  }
 
 
}
 
 
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
// So Rad
boolean   isSimRunning = true;
 
RadEngine simThread;
 
 
@Override
void radSimDone() {
  isSimRunning = false;
  // SwitchRender
  // MetaRad.switchRender(myObject);
}
 
// /////////////////////////////////
// /////////////////////////////////
// /////////////////////////////////
 
 
 
 
 



screenshots