Skip to content

Instantly share code, notes, and snippets.

@robbrit
Created August 4, 2010 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robbrit/507511 to your computer and use it in GitHub Desktop.
Save robbrit/507511 to your computer and use it in GitHub Desktop.
/**
* This program reads an L-system from standard input and outputs a PGM image.
* The following characters are possible:
* uppercase: Move forward with pen down
* lowercase: Move forward with pen up
* +: turn left
* -: turn right
* [: push current turtle state
* ]: pop turtle state
* usage: turtle ANGLE STEP_SIZE > output.pgm
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
using namespace std;
typedef unsigned char byte;
#define SIZE 800
byte world[SIZE][SIZE];
struct _turtle{
double x, y;
double vx, vy;
int pen_down;
}turtle;
void put_pixel(int x, int y, int which){
if (x >= 0 && x < SIZE && y >= 0 && y < SIZE){
world[y][x] = which;
}
}
void forward(int n){
if (turtle.pen_down){
int i;
double x = turtle.x, y = turtle.y;
for (i = 0; i < n; i++){
put_pixel((int)x, (int)y, 255);
x += turtle.vx;
y += turtle.vy;
}
}
turtle.x += turtle.vx * n;
turtle.y += turtle.vy * n;
}
void normalize(){
double len = sqrt(turtle.vx * turtle.vx + turtle.vy * turtle.vy);
turtle.vx /= len;
turtle.vy /= len;
}
void rotate(double n){
double rad = n / 180.0 * M_PI;
double vx = turtle.vx;
turtle.vx = turtle.vx * cos(rad) - turtle.vy * sin(rad);
turtle.vy = vx * sin(rad) + turtle.vy * cos(rad);
normalize();
}
void home(){
turtle.x = turtle.y = SIZE / 2.0;
turtle.vx = 0.0;
turtle.vy = -1.0;
turtle.pen_down = 0;
}
void pen_down(){
turtle.pen_down = 1;
}
void pen_up(){
turtle.pen_down = 0;
}
int main(int argc, char * argv[]){
char c;
double angle;
int step_size;
angle = atof(argv[1]);
step_size = atoi(argv[2]);
memset(world, 0, sizeof(byte) * SIZE * SIZE);
home();
stack<_turtle> states;
while ((c = getchar())){
if (c == '+'){
rotate(-angle);
}else if (c == '-'){
rotate(angle);
}else if (c == '['){
states.push(turtle);
}else if (c == ']'){
turtle = states.top();
states.pop();
}else if (c >= 'a' && c <= 'z'){
pen_up();
forward(step_size);
}else if (c >= 'A' && c <= 'Z'){
pen_down();
forward(step_size);
pen_up();
}
}
printf("P2\n%d %d\n255\n", SIZE, SIZE);
int i, j;
for (i = 0; i < SIZE; i++){
for (j = 0; j < SIZE; j++){
printf("%d ", 255 - world[i][j]);
}
printf("\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment