-
Notifications
You must be signed in to change notification settings - Fork 0
/
penrose2.html
159 lines (140 loc) · 4.71 KB
/
penrose2.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="paper.js"></script>
<script type="text/javascript">
/*
Reference: http://preshing.com/20110831/penrose-tiling-explained/
*/
var Tiling = (function (lib) {
lib = lib || {};
var Point = lib.Point;
if (!Point) throw new Error('Point is not defined');
var subdivide = function (triangles, depth) {
var GOLDENRATIO = (1.0 + Math.sqrt(5)) / 2.0;
var result = [];
for (var i = 0; i < triangles.length; i++) {
var t = triangles[i];
var color = t[0], A = t[1], B = t[2], C = t[3]
// color0, A1, B2, C3
if (color === 0) {
// Subdivide red triangle
var P = C.add(B.subtract(C).divide(GOLDENRATIO));
result.push([0, C, P, B, 0], [1, P, C, A, 1]);
} else {
// Subdivide blue triangle
var Q = B.add(A.subtract(B).divide(GOLDENRATIO));
var R = A.add(C.subtract(A).divide(GOLDENRATIO));
result.push([1, B, C, R, 2], [1, B, Q, R, 3], [0, Q, R, A, 4]);
}
}
return result;
}
var generateSeedSun = function(options){
options = options || {};
// Create wheel of red triangles around the origin
var triangles = []
for (var i = 0; i < 10; i++) {
var A = new Point(0, 0);
var phi1 = (2.0*i - 1) * Math.PI / 10.0;
var B = new Point(Math.cos(phi1), Math.sin(phi1));
phi2 = (2.0*i + 1) * Math.PI / 10.0;
var C = new Point(Math.cos(phi2), Math.sin(phi2));
if (i % 2 === 0) {
var temp = B;
B = C;
C = temp;
}
triangles.push([1, A, B, C]);
}
return triangles;
}
var generate = function(options) {
options = options || {};
depth = options.depth || 8;
// Create a seed
var triangles = generateSeedSun();
// Perform subdivisions
for (var i = 0; i < depth; i++) {
triangles = subdivide(triangles, i);
}
return triangles;
}
return {
generate: generate
};
})({Point: paper.Point});
</script>
<script type="text/paperscript" canvas="myCanvas">
function shuffle(arr) {
var j, x, i;
var len = arr.length;
for (i = len - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = arr[i];
arr[i] = arr[j];
arr[j] = x;
}
}
function getRandomColor() {
var r = Math.floor(Math.random()*255);
var g = Math.floor(Math.random()*255);
var b = Math.floor(Math.random()*255);
return 'rgba('+r+','+g+','+b+',0.7)';
}
function getRandomColors() {
var colors = [];
var len = Math.floor(Math.random()*4) + 2; // 2 to 5 colors is ideal
for (var i=0; i<len; i++) {
colors.push(getRandomColor());
}
console.log(colors);
return colors;
}
var makeTriangle = function(t) {
var path = new Path();
path.moveTo(t[1].x, t[1].y);
path.lineTo(t[2].x, t[2].y);
path.lineTo(t[3].x, t[3].y);
path.closePath();
return path;
}
var paths = [];
var draw = function (triangles) {
var fillColors = getRandomColors();
var group = new Group();
paths = [];
for (var i=0; i<triangles.length; i++) {
var t = triangles[i];
var p = makeTriangle(t);
p.t4 = t[4];
p.fillColor = fillColors[p.t4 % fillColors.length];
paths.push(p);
group.addChild(p);
}
return group;
}
var delta = 0;
function onFrame(event) {
delta += event.delta;
if (delta > 3) {
delta = 0;
var fillColors = getRandomColors();
for (var i=0; i<paths.length; i++) {
var p = paths[i];
p.fillColor = fillColors[p.t4 % fillColors.length];
}
}
}
var tiles = Tiling.generate({depth: 8});
var group = draw(tiles);
var x = window.innerWidth;
var y = window.innerHeight;
project.activeLayer.scale(1120, new Point(0, 0));
project.activeLayer.translate(new Point(x/2, y/2));
</script>
</head>
<body>
<canvas id="myCanvas" width="1920" height="959" resize></canvas>
</body>
</html>