Skip to content

Commit 13445de

Browse files
authored
Merge pull request #447 from ihsavru/dev
Add Koch Curve example
2 parents 4b697bd + 5d31820 commit 13445de

File tree

3 files changed

+411
-0
lines changed

3 files changed

+411
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* @name Koch Curve
3+
* @description Renders a simple fractal, the Koch snowflake. Each recursive level is drawn in sequence.
4+
* By Daniel Shiffman
5+
*/
6+
7+
let k;
8+
9+
function setup() {
10+
createCanvas(710, 400);
11+
frameRate(1); // Animate slowly
12+
k = new KochFractal();
13+
}
14+
15+
function draw() {
16+
background(0);
17+
// Draws the snowflake!
18+
k.render();
19+
// Iterate
20+
k.nextLevel();
21+
// Let's not do it more than 5 times. . .
22+
if (k.getCount() > 5) {
23+
k.restart();
24+
}
25+
}
26+
27+
// A class to describe one line segment in the fractal
28+
// Includes methods to calculate midp5.Vectors along the line according to the Koch algorithm
29+
30+
function KochLine(a,b) {
31+
// Two p5.Vectors,
32+
// start is the "left" p5.Vector and
33+
// end is the "right p5.Vector
34+
this.start = a.copy();
35+
this.end = b.copy();
36+
37+
this.display = function() {
38+
stroke(255);
39+
line(this.start.x, this.start.y, this.end.x, this.end.y);
40+
}
41+
42+
this.kochA = function() {
43+
return this.start.copy();
44+
}
45+
46+
// This is easy, just 1/3 of the way
47+
this.kochB = function() {
48+
let v = p5.Vector.sub(this.end, this.start);
49+
v.div(3);
50+
v.add(this.start);
51+
return v;
52+
}
53+
54+
// More complicated, have to use a little trig to figure out where this p5.Vector is!
55+
this.kochC = function() {
56+
let a = this.start.copy(); // Start at the beginning
57+
let v = p5.Vector.sub(this.end, this.start);
58+
v.div(3);
59+
a.add(v); // Move to point B
60+
v.rotate(-PI/3); // Rotate 60 degrees
61+
a.add(v); // Move to point C
62+
return a;
63+
}
64+
65+
// Easy, just 2/3 of the way
66+
this.kochD = function() {
67+
let v = p5.Vector.sub(this.end, this.start);
68+
v.mult(2/3.0);
69+
v.add(this.start);
70+
return v;
71+
}
72+
73+
this.kochE = function() {
74+
return this.end.copy();
75+
}
76+
}
77+
78+
// A class to manage the list of line segments in the snowflake pattern
79+
80+
function KochFractal() {
81+
this.start = createVector(0,height-20); // A p5.Vector for the start
82+
this.end = createVector(width,height-20); // A p5.Vector for the end
83+
this.lines = []; // An array to keep track of all the lines
84+
this.count = 0;
85+
86+
this.nextLevel = function() {
87+
// For every line that is in the arraylist
88+
// create 4 more lines in a new arraylist
89+
this.lines = this.iterate(this.lines);
90+
this.count++;
91+
}
92+
93+
this.restart = function() {
94+
this.count = 0; // Reset count
95+
this.lines = []; // Empty the array list
96+
this.lines.push(new KochLine(this.start,this.end)); // Add the initial line (from one end p5.Vector to the other)
97+
}
98+
this.restart();
99+
100+
this.getCount = function() {
101+
return this.count;
102+
}
103+
104+
// This is easy, just draw all the lines
105+
this.render = function() {
106+
for(let i = 0; i < this.lines.length; i++) {
107+
this.lines[i].display();
108+
}
109+
}
110+
111+
// This is where the **MAGIC** happens
112+
// Step 1: Create an empty arraylist
113+
// Step 2: For every line currently in the arraylist
114+
// - calculate 4 line segments based on Koch algorithm
115+
// - add all 4 line segments into the new arraylist
116+
// Step 3: Return the new arraylist and it becomes the list of line segments for the structure
117+
118+
// As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . .
119+
this.iterate = function(before) {
120+
let now = []; // Create emtpy list
121+
for(let i = 0; i < this.lines.length; i++) {
122+
let l = this.lines[i];
123+
// Calculate 5 koch p5.Vectors (done for us by the line object)
124+
let a = l.kochA();
125+
let b = l.kochB();
126+
let c = l.kochC();
127+
let d = l.kochD();
128+
let e = l.kochE();
129+
// Make line segments between all the p5.Vectors and add them
130+
now.push(new KochLine(a,b));
131+
now.push(new KochLine(b,c));
132+
now.push(new KochLine(c,d));
133+
now.push(new KochLine(d,e));
134+
}
135+
return now;
136+
}
137+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* @name Koch Curve
3+
* @description Renders a simple fractal, the Koch snowflake. Each recursive level is drawn in sequence.
4+
* By Daniel Shiffman
5+
*/
6+
7+
let k;
8+
9+
function setup() {
10+
createCanvas(710, 400);
11+
frameRate(1); // Animate slowly
12+
k = new KochFractal();
13+
}
14+
15+
function draw() {
16+
background(0);
17+
// Draws the snowflake!
18+
k.render();
19+
// Iterate
20+
k.nextLevel();
21+
// Let's not do it more than 5 times. . .
22+
if (k.getCount() > 5) {
23+
k.restart();
24+
}
25+
}
26+
27+
// A class to describe one line segment in the fractal
28+
// Includes methods to calculate midp5.Vectors along the line according to the Koch algorithm
29+
30+
function KochLine(a,b) {
31+
// Two p5.Vectors,
32+
// start is the "left" p5.Vector and
33+
// end is the "right p5.Vector
34+
this.start = a.copy();
35+
this.end = b.copy();
36+
37+
this.display = function() {
38+
stroke(255);
39+
line(this.start.x, this.start.y, this.end.x, this.end.y);
40+
}
41+
42+
this.kochA = function() {
43+
return this.start.copy();
44+
}
45+
46+
// This is easy, just 1/3 of the way
47+
this.kochB = function() {
48+
let v = p5.Vector.sub(this.end, this.start);
49+
v.div(3);
50+
v.add(this.start);
51+
return v;
52+
}
53+
54+
// More complicated, have to use a little trig to figure out where this p5.Vector is!
55+
this.kochC = function() {
56+
let a = this.start.copy(); // Start at the beginning
57+
let v = p5.Vector.sub(this.end, this.start);
58+
v.div(3);
59+
a.add(v); // Move to point B
60+
v.rotate(-PI/3); // Rotate 60 degrees
61+
a.add(v); // Move to point C
62+
return a;
63+
}
64+
65+
// Easy, just 2/3 of the way
66+
this.kochD = function() {
67+
let v = p5.Vector.sub(this.end, this.start);
68+
v.mult(2/3.0);
69+
v.add(this.start);
70+
return v;
71+
}
72+
73+
this.kochE = function() {
74+
return this.end.copy();
75+
}
76+
}
77+
78+
// A class to manage the list of line segments in the snowflake pattern
79+
80+
function KochFractal() {
81+
this.start = createVector(0,height-20); // A p5.Vector for the start
82+
this.end = createVector(width,height-20); // A p5.Vector for the end
83+
this.lines = []; // An array to keep track of all the lines
84+
this.count = 0;
85+
86+
this.nextLevel = function() {
87+
// For every line that is in the arraylist
88+
// create 4 more lines in a new arraylist
89+
this.lines = this.iterate(this.lines);
90+
this.count++;
91+
}
92+
93+
this.restart = function() {
94+
this.count = 0; // Reset count
95+
this.lines = []; // Empty the array list
96+
this.lines.push(new KochLine(this.start,this.end)); // Add the initial line (from one end p5.Vector to the other)
97+
}
98+
this.restart();
99+
100+
this.getCount = function() {
101+
return this.count;
102+
}
103+
104+
// This is easy, just draw all the lines
105+
this.render = function() {
106+
for(let i = 0; i < this.lines.length; i++) {
107+
this.lines[i].display();
108+
}
109+
}
110+
111+
// This is where the **MAGIC** happens
112+
// Step 1: Create an empty arraylist
113+
// Step 2: For every line currently in the arraylist
114+
// - calculate 4 line segments based on Koch algorithm
115+
// - add all 4 line segments into the new arraylist
116+
// Step 3: Return the new arraylist and it becomes the list of line segments for the structure
117+
118+
// As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . .
119+
this.iterate = function(before) {
120+
let now = []; // Create emtpy list
121+
for(let i = 0; i < this.lines.length; i++) {
122+
let l = this.lines[i];
123+
// Calculate 5 koch p5.Vectors (done for us by the line object)
124+
let a = l.kochA();
125+
let b = l.kochB();
126+
let c = l.kochC();
127+
let d = l.kochD();
128+
let e = l.kochE();
129+
// Make line segments between all the p5.Vectors and add them
130+
now.push(new KochLine(a,b));
131+
now.push(new KochLine(b,c));
132+
now.push(new KochLine(c,d));
133+
now.push(new KochLine(d,e));
134+
}
135+
return now;
136+
}
137+
}

0 commit comments

Comments
 (0)