import processing.opengl.*; import processing.opengl.*; import anar.*; // import geometry.Point3D; 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 = true; void keyPressed(){ switch(key){ case 'q': simThread.simulate(myObject); simThread.runNow(); isSimRunning = true; break; case ' ': generatorAddOneFace(); break; case 'w': // MetaRad.switchRender(myObject); 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': transformOneFace((int)random(myObject.faces.size()-1)); 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(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 // I1){ 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(energieAA0&&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; } void transformOneFace(int k){ if(k>myObject.faces.size()-1) k = myObject.faces.size()-2; Face faceA = myObject.faces.get(k); Face faceAA = myObject.faces.get(k+1); energieA = ((RenderRadSim)faceA.render).energyDensityFront; energieAA = ((RenderRadSim)faceAA.render).energyDensityFront; // println(((Object)faceA.pt(2).parent(1).parent(0).parent(0).parent(0)).getClass().getName()); // println(faceA.pt(2).parent(1).parent(0).parent(0).numOfParents()); int ldelta = 0; for (int i = 0; ienergieAA){ // if no angle increase its size without changing orientation if( (locLengthA==locLengthB)&& (locLengthAB) increase it if possible else if( (deltalocLengthB)&& (locLengthAA) increase it if possible else if( (delta> -maxDelta)&& (locLengthA0)){ faceA.pt(2).parent(1).parent(0).parent(0,sides[locLengthA-1]); faceA.pt(3).parent(1).parent(0).parent(0,sides[locLengthB-1]); } // if no angle & smallest size, choose angle that decrease delta if( (locLengthA==locLengthB)&& (locLengthA==0)){ if(delta>0){ faceA.pt(3).parent(1).parent(0).parent(0,sides[locLengthB+1]); } else{ faceA.pt(2).parent(1).parent(0).parent(0,sides[locLengthA+1]); } } // if angle (A>B) decrease it if possible else if( (delta> -maxDelta)&& (locLengthA>locLengthB)){ faceA.pt(2).parent(1).parent(0).parent(0,sides[locLengthA-1]); } // if angle (B>A) decrease it if possible else if( (delta