top of page

Laser Cutting Computationally Generated Forms

  • Writer: Joelle McDonald
    Joelle McDonald
  • Feb 3, 2025
  • 5 min read

Design 1 - Tornado

This design was inspired by a concentric circle design I was experimenting with. I found that creating somewhat random repetition around a central point created an interesting tunneling perspective. I continued to play with this until I arrived at a design that, to me, emulates the perspective I imagine one would have looking into a tornado from it's upper edge. Depending on the viewer, it could also appear to depict a tornado from below. I chose not to laser this design because I expected the interaction of the quantity and overlap of circles and the laser's capabilities to be less friendly than the others.

Graphic Rendering of Tornado
Graphic Rendering of Tornado

To see the code that created this design, expand the "Tornado Design Code in Processing" section below. This code was written using Processing and is based around a loop with a few randomized variables.

Tornado Design Code in Processing

import processing.pdf.*; //set up ability to export output as pdf

int r = 10; //establish variable for radius, set to 10
int x = 600; //set horizontal center for circle to initialize
int y = 600; //set vertical center for circle to initialize

void setup(){
	size(1200, 1200, PDF, "M2_Design_11.pdf"); //set frame, run as pdf export
	background(0); //set background to white
	stroke(255); //set stroke to black
	noFill(); //draw circles without fill
	noLoop(); //do not repeat, for ease of exporting drawing
}

void draw(){
  for (int i=0; i<300; i+=1){ //set loop to draw 300 circles
    circle(x, y, r); //draw circle
    r -= random(2, 20); //reduce radius by amount between 2 and 20
    x -= random(1, 4); //draw next circle 1-4 units to the left
    y -= random(1, 6); //draw next circle 1-6 units upward
  }

  println("Finished."); //signal all code has run and pdf exported
  exit(); //end the program
}


Design 2 - Dimensional Grid

This design was initially based on the veining in leaves. As I generated a design to emulate that, I found that replicating the branching system into a grid created an interesting depth effect.

Digital rendering of Dimensional Grid (left) and laser etched product (right)
Digital rendering of Dimensional Grid (left) and laser etched product (right)

To see the code that created this design, expand the "Dimensional Grid Code" section below. This code was written in Processing using the Turtle Library created by Leah Buechley. Learn more about the Turtle Library on her site. In this design I made frequent use of the push and pop functions, loops, and variables.

Dimensional Grid Design Code in Processing

import processing.pdf.*;
import Turtle.*;

int size = 50; //length of vertical line between each row
int y = 9; //number of times pattern is repeated vertically
int x = 10; //number of times pattern is repeated horizontally
int k = 55; //angle of the rightward branches
int g = 20; //angle of the leftward branches
int sW = 1; //stroke weight variable

Turtle t;

void setup() {
  size(500,500); //set size of field
  background(255); //set background to white
  stroke(0); //set stroke to black
  strokeWeight(sW); //call stroke weight variable
  t = new Turtle(this); 
  noLoop(); //prevent looping for ease of drawing and export
}

void draw() {
  t.penUp(); //pause drawing
  t.goToPoint(20, height-(size/3)); //move to bottom left corner of field
  t.penDown(); //resume drawing
  for (int j = 0; j < x; j += 1){ //loop to repeat pattern horizontally
  	for (int i = 0; i < y; i += 1) { //loop to repeat pattern vertically
    		t.push(); //remember the turtle's current location
    		t.right(k); //turn k degrees to the right
     		t.forward(size-5); //draw rightward branch
    		t.left(k);//turtle face top of screen
     		t.forward(size);//draw rightward line of pattern
     		t.pop(); //return to remembered location
     		t.push(); //remember turtle location
     		t.left(g); //turn g degrees to the left
     		t.forward(size/1.7); //draw leftward branch
     		t.pop(); //return to remembered location
     		t.forward(size); //draw central stem
     		t.push(); //remember turtle location
     //draw a top set of branches without a stem
     		t.right(k);  //turn k degrees to the right
    		t.forward(size-7);  //draw rightward branch
     		t.pop(); //return to remembered location
     		t.push(); //remember turtle location
     		t.left(g); //turn g degrees to the left
     		t.forward(size/1.7);  //draw leftward branch
     		t.pop(); //return to remembered location
  }

// this section moves the turtle from it's ending point drawing the previous column to its starting point for the next column without drawing a line of its path
     t.penUp(); //pause drawing
     t.back(size*y); //return to the bottom of the center line that was just drawn
     t.right(90); //turn right 
     t.forward(-tan(k)+sW); //move the appropriate distance rightward for the 
		patterns to touch without overlapping
     t.left(90); //turn back in the original direction
     t.penDown(); //resume drawing
  }

// move to the left-most, bottom-most point in the existing pattern without tracing the path
 t.penUp(); //pause drawing
 t.goToPoint(20, height-size/4); //move to the bottom-most point
 t.left(20); //turn toward the leftward braches
 t.forward(size/1.9+4); //move to the left end of the bottom-most, left-most branch
 t.right(20); //face the top of the screen
 t.penDown();//resume drawing
 t.forward(size*y+2); //Draw far left line of pattern to seal border
}

//function to record a pdf of the program upon pressing the "s" key
void keyPressed() { 
  if (key == 's') {  // press 's' to save a pdf of your drawing
    String fileName = "drawing" + getDateString() + ".pdf";
    beginRecord(PDF, fileName);
    draw();
    endRecord();
    println("Saved to file: " + fileName);
  }
} 

//function to retrieve the date and time of running keyPressed function for file 
	naming
String getDateString() {
  String time = str(hour()) + "_" + str(minute()) + "_" + str(second());
  String date = str(year()) + "_" + str(month()) + "_" + str(day());
  return date + "-" + time;
}



Design 3 - Triangle Turbulence

This design was brought about by my desire to play with putting limits on randomization. When I rendered the design I was interested to test how the near-line triangles (those so narrow they look more like a line) would translate to a laser-cut piece. I was pleasantly surprised by the laser cutter's precision.

Digital rendering of Triangle Turbulence (left) and laser cut product on orange background (right)
Digital rendering of Triangle Turbulence (left) and laser cut product on orange background (right)

To see the code that created this design, expand the "Triangle Turbulence Code" section below. This code was written in Processing with nested loops and randomized variables. I took special care with the randomization to distribute the triangles in 25 equal square sections.

Triangle Turbulence Design Code in Processing

import processing.pdf.*; //import library to enable pdf saving
int f = 0; //establish minimum of range for x-point of triangle vertice
int g = 100; //establish maximum range for x-point of triangle vertice
int r = 0; //establish minimum range for y-point of triangle vertice
int s = 100; //establish maximum range for y-point of triangle vertice

void setup(){
  size(500,500, PDF, "M2_Design_3.pdf"); //set size of field, run as pdf export
  background(255); //set background to white
  stroke (0); //set stroke to black
  noFill(); //prevent fill in triangles
  noLoop(); //prevent looping for ease of drawing and export
}

void draw(){
for (int i = 0; i < 5; i += 1){ //loop to repeat pattern vertically
  for (int j = 0; j < 5; j += 1){ //loop to repeat pattern horizontally
    float a = random (f, g); // x-point of first vertex
    float x = random (r, s); //y-point of first vertex
    float b = random (f, g); // x-point of second vertex
    float y = random (r, s); //y-point of second vertex
    float c = random (f, g); // x-point of third vertex
    float z = random (r, s); //y-point of third vertex
    triangle(a, x, b, y, c, z); //draw triangle
    f += 100; //move minimum of range for x-point of triangle vertice rightward
    g += 100; //move maximum of range for x-point of triangle vertice rightward
    }
  f = 0; //reset minimum range for x-point of triangle
  g = 100; //reset maximum range for x-point of triangle
  r+=100; //move minimum of range for y-point of triangle vertice downward
  s+=100; //move maximum of range for y-point of triangle vertice downward
}

  println("Finished."); //signal all code has run and pdf exported
  exit(); //end the program
}


Comments


bottom of page