Last active
December 25, 2015 16:09
-
-
Save vicapow/7003904 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype HTML> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
</head> | |
<body> | |
<script> | |
var svg = d3.select('body').append('svg') | |
var d = -3 // how far the box is from the camera | |
box = translate(generateBox(10, 2), [0, 0, -3]) | |
function generateBox(n, width){ | |
var s = width / (n - 1), t = width / 2 | |
var points = [] | |
for(var x = 0; x < n; x++){ | |
for(var y = 0; y < n; y++){ | |
for(var z = 0; z < n; z++){ | |
points.push([x * s - t, y * s - t, z * s - t]) | |
} | |
} | |
} | |
return points | |
} | |
function generateGrid(n, width){ | |
var s = width / n, t = width / 2 | |
var points = [] | |
for(var x = 0; x < n; x++){ | |
for(var y = 0; y < n; y++){ | |
points.push([x * s - t, y * s - t, 0]) | |
} | |
} | |
return points | |
} | |
function rotate(points, theta){ | |
return points.slice(0).map(function(p){ | |
return [ | |
p[0] * Math.cos(theta) - p[2] * Math.sin(theta) | |
, p[1] | |
, p[0] * Math.sin(theta) + p[2] * Math.cos(theta) | |
] | |
}) | |
} | |
function translate(points, delta){ | |
return points.slice(0).map(function(p){ | |
return [p[0] + delta[0], p[1] + delta[1], p[2] + delta[2]] | |
}) | |
} | |
// eye is located at [0, 0, 0] | |
// eye is pointing at [0,0,-1] | |
// image plane is at [0, 0, -1] | |
imagePlane = [0, 0, -1] | |
function vec_scale3d(vec, scale){ | |
return [vec[0] * scale, vec[1] * scale, vec[2] * scale] | |
} | |
var scale = d3.scale.linear().domain([0, 1]).range([300, 600]) | |
var circles = svg.selectAll('circle').data(box) | |
circles.enter().append('circle') | |
var theta = 0 | |
setInterval(function(){ | |
var t = translate(box, [0, 0, -d]) | |
t = rotate(t, theta += 0.01) | |
t = translate(t, [0, 0, d]) | |
t = t.map(function(p){ | |
var Ax = p[0], Ay = p[1], Az = p[2] | |
var Bz = imagePlane[2] | |
return vec_scale3d(p, Bz / Az) | |
}) | |
circles.data(t).attr({ | |
r: 1 | |
, cx: function(d){ return scale(d[0]) } | |
, cy: function(d){ return scale(d[1]) } | |
}) | |
}, 10) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment