23. September 2013
Here I tried to write a "flower generator". In an early phase it worked already pretty well with key commands but I wanted to add a GUI. Therefor I needed to loop the draw() function again which caused the randomly created flowers to be drawn sixty times per second. So I was looking for a solution to have a working GUI and a fixed image. Max gave me the hint to look at the PGraphics class which allows you to draw into an off-screen graphics buffer. After struggling quite a while I finally managed to understand and use the new possibilities for what I intended. After getting everything to work the icing on the cake was the implementation of an export function which saves the current frame without GUI elements as a .png to the project folder. Here some of the generated images: For a better overview I split the document into three different tabs. The main application
/*
Use the sliders to adjust certain values or control them with the following keys:
1: less leafs
2: more leafs
3: thinner leafs
4: thicker leafs
5: shorter leafs
6: longer leafs
7: set shape to ellipse
8: set shape to triangle
9: set shape to rectangle
s: export the current frame as a .png to project folder
*/
// import controlP5 for the GUI
import controlP5.*;
// import a java.util for a timestamp which will be needed when exporting a frame
import java.util.Calendar;
// declare some classes
ControlP5 cp5;
PGraphics pg;
// declare some variables
int shapeWidth;
int shapeHeight;
int leafs; // amount of leafs
int shape;
void setup()
{
//make it fullscreen
size(displayWidth, displayHeight);
// set the frame rate to 20 fps
frameRate(20);
// change random seed
randomSeed(millis());
//get the GUI
GUI();
// instantiation of the object "pg"
pg = createGraphics(displayWidth, displayHeight);
//draw a flower at startup
flower();
}
void draw()
{
// draw the PGraphics image
image(pg, 0, 0);
}
// draw the flower
void flower()
{
// start the drawing
pg.beginDraw();
pg.ellipseMode(CORNER);
pg.rectMode(CORNER);
pg.pushMatrix();
pg.translate(width/2, height/2);
pg.smooth();
pg.background(200);
pg.noStroke();
zeichnen(pg, leafs);
pg.popMatrix();
pg.endDraw();
}
// draw the leafs
void zeichnen(PGraphics pg, int leafs)
{
for (int i = 0; i < leafs; i++) {
int leafClr = (int)random(100, 255);
pg.fill(0, leafClr, 0, 100);
// change the shape
switch(shape)
{
case 1:
pg.ellipse(-shapeWidth/2, 0, shapeWidth, shapeHeight);
break;
case 2:
pg.triangle(0, 0, shapeWidth, shapeHeight, random(shapeWidth*0.4, shapeWidth*1.2), random(shapeHeight*0.4, shapeHeight*1.2));
break;
case 3:
pg.rect(-shapeWidth/2, 0, random(shapeWidth*0.4, shapeWidth*1.2), random(shapeHeight*0.4, shapeHeight*1.2));
break;
}
pg.rotate(random(PI*0.2, PI));
}
}
// the timestamp used for naming exported frames
String timestamp() {
Calendar now = Calendar.getInstance();
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
}
The GUI
// set up the GUI
void GUI()
{
cp5 = new ControlP5(this);
cp5.addSlider("leafs")
.setPosition(50, 50)
.setRange(1, 200)
.setValue(50)
.setId(1)
;
cp5.addSlider("shapeWidth")
.setPosition(250, 50)
.setRange(5, 500)
.setValue(50)
.setId(2)
;
cp5.addSlider("shapeHeight")
.setPosition(450, 50)
.setRange(5, 500)
.setValue(200)
.setId(3)
;
cp5.addSlider("shape")
.setPosition(650, 50)
.setWidth(100)
.setRange(1, 3) // values can range from big to small as well
.setValue(1)
.setNumberOfTickMarks(3)
.setSliderMode(Slider.FLEXIBLE)
.setId(4)
;
}
void controlEvent(ControlEvent theEvent) {
switch(theEvent.getId()) {
case(1):
flower();
break;
case(2):
flower();
break;
case(3):
flower();
break;
case(4):
flower();
break;
}
}
The keyReleased() functions
// assign functions to keys
void keyReleased() {
switch (key) {
case '1':
flower();
cp5.getController("leafs").setValue(leafs-=5);
break;
case '2':
flower();
cp5.getController("leafs").setValue(leafs+=5);
break;
case '3':
flower();
cp5.getController("shapeWidth").setValue(shapeWidth-=5);
break;
case '4':
flower();
cp5.getController("shapeWidth").setValue(shapeWidth+=5);
break;
case '5':
flower();
cp5.getController("shapeHeight").setValue(shapeHeight-=7);
break;
case '6':
flower();
cp5.getController("shapeHeight").setValue(shapeHeight+=7);
break;
case '7':
flower();
cp5.getController("shape").setValue(shape=1);
break;
case '8':
flower();
cp5.getController("shape").setValue(shape=2);
break;
case '9':
flower();
cp5.getController("shape").setValue(shape=3);
break;
case 's':
saveFrame(timestamp()+"_##.png");
break;
case 'S':
saveFrame(timestamp()+"_##.png");
break;
}
}