# Processing.js

## Koch

by Daniel Shiffman. Renders a simple fractal, the Koch snowflake. Each recursive level drawn in sequence.

Original Processing.org Example: Koch

```// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
KochFractal k;

void setup() {
size(200,200);
background(0);
frameRate(1);  // Animate slowly
k = new KochFractal();
smooth();
}

void draw() {
background(0);
// Draws the snowflake!
k.render();
// Iterate
k.nextLevel();
// Let's not do it more than 5 times. . .
if (k.getCount() > 5) {
k.restart();
}

}

// A class to manage the list of line segments in the snowflake pattern

class KochFractal {
Point start;       // A point for the start
Point end;         // A point for the end
ArrayList lines;   // A list to keep track of all the lines
int count;

public KochFractal()
{
start = new Point(0,height/2 + height/4);
end = new Point(width,height/2  + height/4);
lines = new ArrayList();
restart();
}

void nextLevel()
{
// For every line that is in the arraylist
// create 4 more lines in a new arraylist
lines = iterate(lines);
count++;
}

void restart()
{
count = 0;      // Reset count
lines.clear();  // Empty the array list
lines.add(new KochLine(start,end));  // Add the initial line (from one end point to the other)
}

int getCount() {
return count;
}

// This is easy, just draw all the lines
void render()
{
for(int i = 0; i < lines.size(); i++) {
KochLine l = (KochLine)lines.get(i);
l.render();
}
}

// This is where the **MAGIC** happens
// Step 1: Create an empty arraylist
// Step 2: For every line currently in the arraylist
//   - calculate 4 line segments based on Koch algorithm
//   - add all 4 line segments into the new arraylist
// Step 3: Return the new arraylist and it becomes the list of line segments for the structure

// As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . .
ArrayList iterate(ArrayList before)
{
ArrayList now = new ArrayList();    //Create emtpy list
for(int i = 0; i < before.size(); i++)
{
KochLine l = (KochLine)lines.get(i);   // A line segment inside the list
// Calculate 5 koch points (done for us by the line object)
Point a = l.start();
Point b = l.kochleft();
Point c = l.kochmiddle();
Point d = l.kochright();
Point e = l.end();
// Make line segments between all the points and add them
}
return now;
}

}

// A class to describe one line segment in the fractal
// Includes methods to calculate midpoints along the line according to the Koch algorithm

class KochLine {

// Two points,
// a is the "left" point and
// b is the "right point
Point a,b;

KochLine(Point a_, Point b_) {
a = a_.copy();
b = b_.copy();
}

void render() {
stroke(255);
line(a.x,a.y,b.x,b.y);
}

Point start() {
return a.copy();
}

Point end() {
return b.copy();
}

// This is easy, just 1/3 of the way
Point kochleft()
{
float x = a.x + (b.x - a.x) / 3f;
float y = a.y + (b.y - a.y) / 3f;
return new Point(x,y);
}

// More complicated, have to use a little trig to figure out where this point is!
Point kochmiddle()
{
float x = a.x + 0.5f * (b.x - a.x) + (sin(radians(60))*(b.y-a.y)) / 3;
float y = a.y + 0.5f * (b.y - a.y) - (sin(radians(60))*(b.x-a.x)) / 3;
return new Point(x,y);
}

// Easy, just 2/3 of the way
Point kochright()
{
float x = a.x + 2*(b.x - a.x) / 3f;
float y = a.y + 2*(b.y - a.y) / 3f;
return new Point(x,y);
}

}

class Point {
float x,y;

Point(float x_, float y_) {
x = x_;
y = y_;
}

Point copy() {
return new Point(x,y);
}
}```