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:   Test01aDeployRadIKLocal.pde
   JAVA Download:   Test01aDeployRadIKLocal.java


Click on anar+ terms to get the documentation.

import processing.opengl.*;
import processing.opengl.*;
import anar.*;
 
// import geometry.Point3D;
 
 
// import com.sun.xml.internal.bind.v2.runtime.reflect.ListIterator;
 
 
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();
 
		generatorAddOneFixedFace();
		generatorAddOneFixedFace();
 
		// 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 = true;
 
 
	void keyPressed(){
 
		switch(key){
		case 'q':
			simThread.simulate(myObject);
			simThread.runNow();
			isSimRunning = true;
			break;
		case ' ':
			// generatorAddOneFixedFace();
			// generatorAddOneFixedFace();
			generatorTestOneFace();
			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;
			if(isAddingFace)
				radSimDone();
			break;
		case 'r':
			angle.set(0);
			invAngle.set( -angle.get());
			break;
		case 't':
			angle.set(0.3f);
			invAngle.set( -angle.get());
			break;
		case 'a':
			anar.tools.TextIO.write( ((Object)this).getClass().getName()+".lsp",myObject.toAutocad());
			break;
		case 'b':
			ptsA.pt(ptsA.numOfPts()-2).parentToString();
			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();
 
	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 = Anar.Pt(0,0,0,"originA");
		Pt originB = Anar.Pt(10,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;
 
 
	// define table of possibilities {translation A, translation B, rotation}
	// int[][] table= {{1,1,0}, {1,1,1}, {1,1,2}, {1,1,3}, {1,1,4}};
	int[][] table      = {{0, 0, 0}, {0, 0, 1}, {0, 0, 2}, {0, 0, 3}, {0, 0, 4}, {0, 1, 0}, {0, 1, 1}, {0, 1, 2}, {0, 1, 3}, {0, 1, 4}, {1, 0, 0}, {1, 0, 1},
			{1, 0, 2}, {1, 0, 3}, {1, 0, 4}, {0, 2, 0}, {0, 2, 1}, {0, 2, 2}, {0, 2, 3}, {0, 2, 4}, {2, 0, 0}, {2, 0, 1}, {2, 0, 2}, {2, 0, 3}, {2, 0, 4}, {1, 1, 0},
			{1, 1, 1}, {1, 1, 2}, {1, 1, 3}, {1, 1, 4}, {1, 2, 0}, {1, 2, 1}, {1, 2, 2}, {1, 2, 3}, {1, 2, 4}, {2, 1, 0}, {2, 1, 1}, {2, 1, 2}, {2, 1, 3}, {2, 1, 4},
			{2, 2, 0}, {2, 2, 1}, {2, 2, 2}, {2, 2, 3}, {2, 2, 4}};
 
	int     best       = 0;
	float   bestEnergy = 0;
	// current table element being tested
	int     testTable  = 0;
	// boolean to avoid testing solutions with unwanted delta
	boolean noTest     = false;
 
 
	void generatorModifyToBest(){
 
		Anar.println("modify to "+best);
 
		// modify the geometry according to best result
 
		// update delta
		delta += table[best][0]-table[best][1];
 
		// find translation A & B of penultimate growth in ptsA and ptsB and modify
		// find translation A & B of penultimate growth in ptsA and ptsB and modify
		Pt pA = ptsA.pt(ptsA.numOfPts()-2);
		pA.parent(1).parent(0).replaceParent(0,sides[table[best][0]]);
 
		Pt pB = ptsB.pt(ptsB.numOfPts()-2);
		pB.parent(1).parent(0).replaceParent(0,sides[table[best][1]]);
 
		// find rotation and modify
		pA = ptsA.ptEnd();
		pB = ptsB.ptEnd();
 
		pA.parent(1).parent(1).replaceParent(0,rotations[table[best][2]]);
		pB.parent(1).parent(1).replaceParent(0,rotations[table[best][2]]);
 
		// 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("-------------------");
 
		// then run simulation over the whole geometry
		// ie change measure flag to true on all faces
 
		simThread.simulate(myObject);
		simThread.runNow();
		isSimRunning = true;
	}
 
 
	void generatorTestOneFace(){
		// here generate new face with all possibilities and run simulation on it.
 
		Anar.println("testing "+testTable);
 
		int maxDelta = 3;
 
 
		// first generate new face
		// translations apply to previous element
 
		// (we won't accept delta to be too long as we want to keep the set of faces
		// to a small set of cases
		if(abs(delta+table[testTable][0]-table[testTable][1])<maxDelta){
 
			// find translation A & B of penultimate growth in ptsA and ptsB and
			// modify
			Pt pA = ptsA.pt(ptsA.numOfPts()-2);
			pA.parent(1).parent(0).replaceParent(0,sides[table[testTable][0]]);
 
			Pt pB = ptsB.pt(ptsB.numOfPts()-2);
			pB.parent(1).parent(0).replaceParent(0,sides[table[testTable][1]]);
 
 
			// find rotation and modify
			pA = ptsA.ptEnd();
			pB = ptsB.ptEnd();
 
			pA.parent(1).parent(1).replaceParent(0,rotations[table[testTable][2]]);
			pB.parent(1).parent(1).replaceParent(0,rotations[table[testTable][2]]);
 
			// myObject = null;
			myObject = new SweepTwoPaths(ptsA,ptsB);
 
			// launch the simulation
			// will measure only the currently constructed face
			simThread.scene.add(myObject);
			simThread.objToMeasure.add(myObject.faceEnd());
			simThread.runNow();
			isSimRunning = true;
 
		}
		else{
			// return as if simulated with corresponding flag
			noTest = true;
			radSimDone();
		}
 
	}
 
 
	void generatorAddOneFixedFace(){
 
 
		// default size for new face
		int lengthA = 1;
		int lengthB = 1;
 
		PtDER newPtA = Anar.Pt(previousA,"A"+faceCount);
		PtDER newPtB = Anar.Pt(previousB,"B"+faceCount++);
 
 
		// 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
		// default rotation for new face angle = 0
		Transform rotmp = rotations[2];
 
		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("-------------------");
 
	}
 
 
	// /////////////////////////////////
	// /////////////////////////////////
	// /////////////////////////////////
	// So Rad
	boolean   isSimRunning = true;
 
	RadEngine simThread;
 
	@Override
	void radSimDone() {
		isSimRunning = false;
 
		if(isAddingFace){
 
			if(testTable>=table.length){
				// returning from whole geometry test
				// restart testing single element
				testTable = 0;
				best = 0;
				bestEnergy = 0f;
				generatorAddOneFixedFace();
				generatorTestOneFace();
			}
			else{
				float energy = 0f;
 
				if( !noTest){
					// here check if energy returned is better than best element in table
					energy = ((RenderRadSim)myObject.faces.get(myObject.faces.size()-1).render).energyDensityFront;
 
					// select the best
					if(energy>bestEnergy){
						best = testTable;
						bestEnergy = energy;
					}
				}
				else
					noTest = false;
 
				Anar.println("return "+energy+" -- "+best+" - "+bestEnergy);
 
				if(++testTable<table.length){
					generatorTestOneFace();
				}
				else{
					generatorModifyToBest();
				}
 
 
			}
		}
		// SwitchRender
		// MetaRad.switchRender(myObject);
	}
 
	// /////////////////////////////////
	// /////////////////////////////////
	// /////////////////////////////////
 
 
 
 
 



screenshots