Skip to content

Instantly share code, notes, and snippets.

@travisdoesmath
Last active December 26, 2017 10:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save travisdoesmath/fb9720ffc478b5d2fe129cf6f60ae0fa to your computer and use it in GitHub Desktop.
Save travisdoesmath/fb9720ffc478b5d2fe129cf6f60ae0fa to your computer and use it in GitHub Desktop.
Golden Spiral Squares
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: black;
}
.square {
fill: none;
stroke-width: 1.5px;
}
.mainSquare {
fill: none;
stroke-width: 2px;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var n_splits = 3;
var width = 960,
height = 500,
color = d3.scaleSequential(d3.interpolateRainbow).domain([0, 2**(n_splits+3)]);
var getTransformationMatrix = function(T) {
return [
[T.A * Math.cos(T.theta), -T.A * Math.sin(T.theta), T.t_x],
[T.A * Math.sin(T.theta), T.A * Math.cos(T.theta), T.t_y],
[0,0,1]
];
}
var splitTransformation = function(T) {
var detM = 2 * Math.sqrt(T.A)*Math.cos(T.theta/2)+T.A+1
var new_t_x = (T.t_x * (Math.sqrt(T.A) * Math.cos(T.theta/2) + 1) + T.t_y * Math.sqrt(T.A) * Math.sin(T.theta/2))/detM;
var new_t_y = (T.t_y * (Math.sqrt(T.A) * Math.cos(T.theta/2) + 1) - T.t_x * Math.sqrt(T.A) * Math.sin(T.theta/2))/detM;
var T_split = {
'A':Math.sqrt(T.A),
'theta':T.theta/2,
't_x':new_t_x,
't_y':new_t_y
};
return T_split;
}
var transform_point = function(T, point) {
T_matrix = getTransformationMatrix(T);
var x = point[0],
y = point[1];
var T_x = T_matrix[0][0] * x + T_matrix[0][1] * y + T_matrix[0][2],
T_y = T_matrix[1][0] * x + T_matrix[1][1] * y + T_matrix[1][2];
return [T_x, T_y];
}
var transform_square = function(T, square) {
var new_square = [
transform_point(T, square[0]),
transform_point(T, square[1]),
transform_point(T, square[2]),
transform_point(T, square[3]),
];
return new_square;
}
var ruler = function(x, levels) {
var value = 1
for (var i = 0; i <= levels; i++) {
if (x % 2**i == 1) {
value += 2**(i-1);
}
}
return value / (2**levels);
}
var square = [[0,0],[0,1],[1,1],[1,0]];
T = {
'A':Math.sqrt(5)/2 - 0.5,
'theta':-Math.PI/2,
't_x':1,
't_y':1
}
for (var i = 0; i < n_splits; i++) {
T = splitTransformation(T);
}
squares = [square];
for (var i = 0; i < 2**(n_splits+3); i++) {
square = transform_square(T, square);
squares.push(square);
}
var svg = d3.select("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(100,150)");
svg.append("rect")
.attr("width", width)
.attr("height", height)
.attr("x", -100)
.attr("y", -150)
.attr("fill", "black")
var scaleX = d3.scaleLinear().domain([0,1]).range([0,275])
var scaleY = d3.scaleLinear().domain([0,1]).range([275,0])
var drawSquare = function(square) {
return "M" + scaleX(square[0][0]) + "," + scaleY(square[0][1])
+ "L" + scaleX(square[1][0]) + "," + scaleY(square[1][1])
+ "L" + scaleX(square[2][0]) + "," + scaleY(square[2][1])
+ "L" + scaleX(square[3][0]) + "," + scaleY(square[3][1])
+ "L" + scaleX(square[0][0]) + "," + scaleY(square[0][1])
}
var squarePaths = svg.selectAll(".square")
.data(squares)
.enter()
.append("path")
.attr("d",function(d) { return drawSquare(d); })
.attr("class","square")
.attr("stroke", function(d, i) { return color(i); })
n_splits = 0;
T = {
'A':Math.sqrt(5)/2 - 0.5,
'theta':-Math.PI/2,
't_x':1,
't_y':1
}
var square = [[0,0],[0,1],[1,1],[1,0]];
squares = [square];
for (var i = 0; i < 2**(n_splits+3); i++) {
square = transform_square(T, square);
squares.push(square);
}
var mainRectangle = svg.selectAll(".mainSquare")
.data(squares)
.enter()
.append("path")
.attr("d",function(d) { return drawSquare(d); })
.attr("class","mainSquare")
.attr("stroke", "white")
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment