Recently I've been looking at Povray, pyprocessing, and cfdg (version 3.0) as tools for creating digital images. I have branched two separate blogs where I mainly explore jruby + processing and processing.py

Wednesday, 30 December 2009

Peano curve fractal using Lindenmayer Systems

   1 import lsystem.*;
   2 import java.text.CharacterIterator;
   3 import java.text.StringCharacterIterator;
   4 
   5 Grammar grammar; 
   6 float drawLength;
   7 float xpos;
   8 float ypos;
   9 float DELTA = PI/3; // 60 degrees
  10 float theta = 0;
  11 String production;
  12 ArrayList points;
  13 
  14 void setup() {
  15   size(800, 800);
  16   createLSystem();
  17   points = new ArrayList();
  18   stroke(255);
  19   strokeWeight(3);
  20   smooth();
  21   xpos = width * 0.65;
  22   ypos = height * 0.9;
  23   translateRules();
  24   noLoop();
  25 }
  26 
  27 void createLSystem(){
  28   int generations = 4;
  29   String axiom = "XF";
  30   grammar = new SimpleGrammar(this, axiom);
  31   grammar.addRule('X', "X+YF++YF-FX--FXFX-YF+");
  32   grammar.addRule('Y', "-FX+YFYF++YF+FX--FX-Y");
  33   float startLength = 100;
  34   production = grammar.createGrammar(generations);
  35   drawLength = startLength * pow(0.6, generations); 
  36 }
  37 
  38 void translateRules() {
  39   CharacterIterator it = new StringCharacterIterator(production);
  40   for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
  41     switch(ch){
  42     case 'F':
  43       float[] temp = {
  44         xpos, ypos, (xpos += drawLength * cos(theta)), (ypos -= drawLength * sin(theta))
  45         };
  46         points.add(temp);
  47       break;
  48     case '+':
  49       theta += (DELTA);
  50       break;
  51     case '-':
  52       theta -= (DELTA);
  53       break;
  54     case 'X':
  55       break;
  56     case 'Y':
  57       break;
  58     default:
  59       System.err.println("character " + ch + " not in grammar");
  60     }
  61   }
  62 }
  63 
  64 void draw() {
  65   background(0);
  66   float[] tmp; // placeholder for array of points that describe line 
  67   for (int i = 0; i < points.size(); i++)
  68   { 
  69     tmp = (float[])points.get(i);
  70     line(tmp[0], tmp[1], tmp[2], tmp[3]);
  71   }
  72 }



Thursday, 17 December 2009

Anar+ Library

I have just started playing with this library and it is pretty impressive, my first attempts will most likely get posted on my ruby-processing blog as it is an obvious thing to try get it working in that environment. 
Partly because:-
1 it will/should be new ground
2 I like to explore code in ruby (mainly because it often doesn't often get in the way like other languages often do)

Tuesday, 8 December 2009

Islands in the processing ide using my lsystem library

NB: Revised version to fit my re-factored custom library 08 January 2010 which I have now extended to support weighted rules (note Grammar is now an interface the two implementing classes are SimpleGrammar and StochasticGrammar for weighted rules).
Here is an example island.pde which I created in the processing ide using my custom lsystem library (available to download from kenai see recent previous postings for the link).

   1 import lsystem.*;  // new library since 8 January 2008
   2 
   3 import java.text.CharacterIterator;
   4 import java.text.StringCharacterIterator;
   5 
   6 Grammar grammar; 
   7 float drawLength;
   8 float xpos;
   9 float ypos;
  10 float DELTA = PI/2; // 90 degrees
  11 float theta = 0;
  12 String production;
  13 ArrayList points;
  14 
  15 void setup() {
  16   size(500, 500);
  17   createLSystem();
  18   points = new ArrayList();
  19   stroke(255);
  20   noFill();
  21   smooth();
  22   xpos = width/4;
  23   ypos = height/4;
  24   translateRules();
  25   noLoop();
  26 }
  27 
  28 void createLSystem(){
  29   int generations = 2;
  30   String axiom = "F-F-F-F";
  31   grammar = new SimpleGrammar(this, axiom); // new since 8 January 2008
  32   grammar.addRule('F', "F+f-FF+F+FF+Ff+FF-f+FF-F-FF-Ff-FFF");
  33   grammar.addRule('f', "ffffff");
  34   float startLength = 1000;
  35   production = grammar.createGrammar(generations);
  36   drawLength = startLength * pow((1/12.0), generations); 
  37 }
  38 
  39 void translateRules() {
  40   CharacterIterator it = new StringCharacterIterator(production);
  41   for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
  42     switch(ch){
  43     case 'F':
  44       float[] temp = {
  45         xpos, ypos, (xpos += drawLength * cos(theta)), (ypos -= drawLength * sin(theta))
  46       };
  47       points.add(temp);
  48       break;
  49     case 'f':
  50       xpos += drawLength * cos(theta)/2;
  51       ypos -= drawLength * sin(theta)/2;
  52       break;
  53     case '+':
  54       theta += (DELTA);
  55       break;
  56     case '-':
  57       theta -= (DELTA);
  58       break;
  59     default:
  60       System.err.println("character " + ch + " not in grammar");
  61     }
  62   }
  63 }
  64 
  65 void draw() {
  66   background(0);
  67   float[] tmp; // placeholder for array of points that describe line 
  68   for (int i = 0; i < points.size(); i++)
  69   { 
  70     tmp = (float[])points.get(i);
  71     line(tmp[0], tmp[1], tmp[2], tmp[3]);
  72   }
  73 }

 

Sunday, 6 December 2009

Cesàro (or Torn Square) Fractal using Lindenmayer System

Revised version as of 8th January 2010, nows uses once more re-factored lsystem library.

   1 import lsystem.*;
   2 
   3 // ripped.pde
   4 
   5 
   6 float drawLength;
   7 float xpos;
   8 float ypos;
   9 float DELTA = QUARTER_PI/4; // 11.25 degrees
  10 ArrayList points;
  11 float theta = 0;
  12 Grammar grammar;
  13 String production;
  14 
  15 void setup() {
  16   size(500, 500);
  17   createLSystem();
  18   points = new ArrayList();
  19   stroke(255, 0, 0);
  20   noFill();
  21   smooth();
  22   translateRules();
  23   background(0);
  24   noLoop();
  25 }
  26 
  27 void createLSystem(){
  28   int generations = 5;                 // set no of recursions
  29   String axiom = "F7-F7-F7-F7-";  // NB  '-' without prefix repeat = 1 (so 7 means 8 repeats or PI/2)
  30   grammar = new SimpleGrammar(this, axiom);  // initialize custom library
  31   grammar.addRule('F', "F6-F76+F6-F"); // add rule
  32   float startLength = 180;
  33   production = grammar.createGrammar(generations);
  34   drawLength = startLength * pow(0.5, generations); 
  35 }
  36 
  37 void translateRules() {
  38   xpos = width/20;  // set starting position
  39   ypos = height/20;
  40   int repeat = 1;
  41   float x_temp, y_temp;
  42   CharacterIterator it = new StringCharacterIterator(production);
  43   for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
  44     switch (ch) {
  45     case 'F':
  46       x_temp = xpos;
  47       y_temp = ypos;
  48       xpos += drawLength * repeat * cos(theta);
  49       ypos -= drawLength * repeat * sin(theta);
  50       float[] point = {x_temp, y_temp, xpos, ypos};
  51       points.add(point);
  52       repeat = 1;
  53       break;
  54     case '+':
  55       theta += (DELTA * repeat);
  56       repeat = 1;
  57       break;
  58     case '-':
  59       theta -= (DELTA * repeat);
  60       repeat = 1;
  61       break;
  62     case '6':
  63       repeat += 6;
  64       break;
  65     case '7':
  66       repeat += 7;
  67       break;
  68     default:
  69       System.err.println("character " + ch + " not in grammar");
  70     }
  71   }
  72 }
  73 
  74 void draw() {
  75   float[] point;
  76   for (int i = 0; i < points.size(); i++) {
  77     point = (float[])points.get(i);
  78     line(point[0], point[1], point[2], point[3]);
  79   }        
  80 }


Friday, 4 December 2009

Heighway Dragon Using L-Systems and processing

Another example demonstrating the usefulness of a custom library, you barely have to think to produce an interesting fractal graphic (well once you have a bit of a grasp of the rules or access to a crib sheet). Note I have posted my library on kenai "http://kenai.com/projects/l-system-utilities" from where you can check it out (example now works with revised library 8th January 2010).

   1 import lsystem.*;
   2 
   3 // dragon.pde
   4  
   5 
   6 final float DELTA = (PI/180) * 45; // 45 degrees
   7 final float REDUCE = 1/sqrt(2);
   8 String production;
   9 float drawLength;
  10 float theta;
  11 float xpos;
  12 float ypos;
  13 ArrayList points;
  14 Grammar grammar;
  15 
  16 void setup() {
  17   size(600, 500);
  18   createLSystem();
  19   points = new ArrayList();
  20   stroke(255, 0, 0);
  21   noFill();
  22   smooth();
  23   translateRules();
  24   background(0);
  25   noLoop();
  26 }
  27 
  28 void createLSystem(){
  29   int generations = 14;                 // set no of recursions
  30   String axiom = "FX";  // NB  '-' without prefix repeat = 1 (so 7 means 8 repeats or PI/2)
  31   grammar = new SimpleGrammar(this, axiom);  // initialize custom library
  32   grammar.addRule('X', "+FX--FY+");    // add rule
  33   grammar.addRule('Y', "-FX++FY-");
  34   float startLength = 100;
  35   production = grammar.createGrammar(generations);
  36   drawLength = startLength * pow(REDUCE, generations); 
  37 }
  38 
  39 void translateRules() {
  40   xpos = width*0.7;
  41   ypos = height/3;
  42   float x_temp, y_temp;
  43   CharacterIterator it = new StringCharacterIterator(production);
  44   for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
  45     switch (ch) {
  46     case 'F':
  47       x_temp = xpos;
  48       y_temp = ypos;
  49       xpos -= drawLength * cos(theta);
  50       ypos += drawLength * sin(theta);
  51       float[] point = {
  52         x_temp, y_temp, xpos, ypos};
  53       points.add(point);
  54       break;
  55     case '+':
  56       theta += (DELTA);
  57       break;
  58     case '-':
  59       theta -= (DELTA);
  60       break;
  61     case 'X':  // recognize grammar and do nothing
  62       break;
  63     case 'Y':  // recognize grammar and do nothing
  64       break;
  65     default:
  66       System.err.println("character " + ch + " not in grammar");
  67     }
  68   }
  69 }
  70 
  71 void draw() {
  72   float[] point;
  73   for (int i = 0; i < points.size(); i++) {
  74     point = (float[])points.get(i);
  75     line(point[0], point[1], point[2], point[3]);
  76   }
  77 }


 

Thursday, 3 December 2009

Here is a penrose snowflake I have created with my custom library

Here is another application of my lsystem library. The library has custom rule class to store the string replacement rule. The main feature is a parser that can cope with multiple rules (see plant of my previous post). The Turtle and TurtleStack are lightweight replacements for the processing matrix functions. Just for the experience I have posted my library on kenai "http://kenai.com/projects/l-system-utilities" from where you will be able to check it out (this is the revised version as of 8 January 2010).
   1 import lsystem.*;
   2 
   3 // penrose.pde
   4 
   5 
   6 float drawLength;
   7 float xpos;
   8 float ypos;
   9 float DELTA = PI/10; // 18 degrees
  10 ArrayList points;
  11 float theta = 0;
  12 Grammar grammar;
  13 TurtleStack ts;
  14 String production;
  15 
  16 void setup() {
  17   size(1000, 1000);
  18   createLSystem();
  19   points = new ArrayList();
  20   stroke(255, 0, 0);
  21   noFill();
  22   smooth();
  23   translateRules();
  24   noLoop();
  25 }
  26 
  27 void createLSystem(){
  28   int generations = 3;                 // set no of recursions
  29   String axiom = "F3-F3-F3-F3-F3-";  // NB  '-' without prefix repeat = 1 (so 3 means 4 repeats or 72 degrees)
  30   grammar = new SimpleGrammar(this, axiom);  // initialize custom library SimpleGrammar (non-stochastic)
  31   grammar.addRule('F', "F3-F3-F45-F++F3-F"); // add rule
  32   float startLength = 480;
  33   production = grammar.createGrammar(generations);
  34   drawLength = startLength * pow(0.4, generations); 
  35 }
  36 
  37 void translateRules() {
  38   TurtleStack ts = new TurtleStack(this);
  39   xpos = width/4;
  40   ypos = height * 0.9;
  41   int repeats = 1;
  42   CharacterIterator it = new StringCharacterIterator(production);
  43   for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
  44     Turtle turtle;
  45     switch(ch){
  46     case 'F':
  47       float[] temp = {
  48         xpos, ypos, (xpos += drawLength * repeats * cos(theta)), (ypos += drawLength * repeats * sin(theta))
  49       };
  50       points.add(temp);
  51       repeats = 1;
  52       break;
  53     case '+':
  54       theta += (DELTA * repeats);
  55       repeats = 1;
  56       break;
  57     case '-':
  58       theta -= (DELTA * repeats);
  59       repeats = 1;
  60       break;
  61     case '[':
  62       ts.push(new Turtle(xpos, ypos, theta));
  63       break;
  64     case ']':
  65       turtle = ts.pop();
  66       xpos = turtle.getX();
  67       ypos = turtle.getY();
  68       theta = turtle.getTheta();
  69       break;
  70     case '3':
  71       repeats += 3;
  72       break;
  73     case '4':
  74       repeats += 4;
  75       break;
  76     case '5':
  77       repeats += 5;
  78       break;
  79     default:
  80       System.err.println("character " + ch + " not in grammar");
  81     }
  82   }
  83 }
  84 
  85 void draw() {
  86   background(0);
  87   float[] tmp;
  88   for (int i =0; i < points.size(); i++)
  89   { 
  90     tmp = (float[])points.get(i);
  91     line(tmp[0], tmp[1], tmp[2], tmp[3]);
  92   }
  93 }
  94 
  95 


Followers

Blog Archive

About Me

My photo
Pembrokeshire, United Kingdom
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2