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

Monday, 21 March 2011

Re-factored (1L) context sensitive sketch in (vanilla) processing

Here I have re-factored the sketch in my previous blog entry to use the Pen and PenStack classes from my LSystems library, by doing so I have avoided need for affine transforms and matrix operations (the latter can be confusing). The thing to note is that if you need to add a non context sensitive rule using my library the 'premis' should be character, and the rule a String.
Obviously the context sensitive 'premis' must be a String, currently (at version 0.7.0) my LSystem library only supports (1L) context sensitive rules (further it does not support null or wild card context characters). I might think about supporting (2L) context sensitive rules at some stage.

/**
 * cs_test3.pde by Martin Prout
 * Demonstrates a simple (1L) context sensitive grammar with ignored
 * symbols. Makes use of Pen and PenStack from LSystem utilities, avoids
 * use of processing affine transforms and matrix operations.
 */

import lsystem.turtle.*;
import lsystem.collection.*;
import lsystem.CSGrammar;

CSGrammar grammar;
float distance = 30;
float THETA = radians(30);
color startColor = color(255, 0, 0);
color endColor = color(0, 255, 0);
float drawLength = 30;
void setup() {
  size(350, 180);
  createGrammar();  
  strokeWeight(4);
  iterateGrammar();
}

void createGrammar() {
  String axiom = "G[+F]F[-F][+F]F";  
  grammar = new CSGrammar(this, axiom); // initialize library
  grammar.addRule("G<F", "G");          // add cs replacement rule
  grammar.setIgnoreList("-+[]");
}

void render(float xpos, float ypos, String production) {
  PenStack stack = new PenStack(this); // initialize local stack
  float theta = -PI/2; // this way is up in the processing environment
  Pen pen = new Pen(this, xpos, ypos, theta, drawLength, startColor); 
  CharacterIterator it = grammar.getIterator(production);
  for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
    switch (ch) {
    case 'F': 
      pen.setColor(startColor);    
      drawLine(pen);
      break;
    case 'G': 
      pen.setColor(endColor);    
      drawLine(pen);
      break;  
    case '-':
      pen.setTheta(pen.getTheta() - THETA);
      break;
    case '+':
      pen.setTheta(pen.getTheta() + THETA);
      break;
    case '[':
      stack.push(new Pen(pen));
      break;
    case ']':
      pen = stack.pop();
      break;     
    default:
      System.err.println("character " + ch + " not in grammar");
    }
  }
}

void iterateGrammar() {
  for (int i = 0; i < 6; i++) {  
    String production = grammar.createGrammar(i);
    float xpos = 40 + (i * 50);
    float ypos = height * 0.9;
    render(xpos, ypos, production);
  }
}

void drawLine(Pen pen) { // draws line and sets new pen position
  float x_temp = pen.getX(); 
  float y_temp = pen.getY();
  pen.setX(x_temp + pen.getLength() * cos(pen.getTheta()));
  pen.setY(y_temp + pen.getLength() * sin(pen.getTheta())); 
  stroke(pen.getColor());
  line(x_temp, y_temp, pen.getX(), pen.getY());
}


No comments:

Post a Comment

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