Built with blockbuilder.org
forked from anonymous's block: Geodesic Random
license: mit |
Built with blockbuilder.org
forked from anonymous's block: Geodesic Random
!function(){function n(n){return d3.merge(e.map(function(t){var o=r(t[0],t[1]),u=r(t[0],t[2]),i=[];i.push([t[0],o(1/n),u(1/n)]);for(var a=1;n>a;++a){for(var e=r(o(a/n),u(a/n)),c=r(o((a+1)/n),u((a+1)/n)),f=0;a>=f;++f)i.push([e(f/a),c(f/(a+1)),c((f+1)/(a+1))]);for(var f=0;a>f;++f)i.push([e(f/a),c((f+1)/(a+1)),e((f+1)/a)])}return i}))}function t(t){function r(n,t){var r;(n[0]<t[0]||n[0]==t[0]&&(n[1]<t[1]||n[1]==t[1]&&n[2]<t[2]))&&(r=n,n=t,t=r),u[n.map(o)+" "+t.map(o)]=[n,t]}function o(n){return d3.round(n,4)}var u={};return n(t).forEach(function(n){r(n[0],n[1]),r(n[1],n[2]),r(n[2],n[0])}),d3.values(u)}function r(n,t){var r=n[0],o=n[1],u=n[2],i=t[0]-r,a=t[1]-o,e=t[2]-u;return function(n){return[r+n*i,o+n*a,u+n*e]}}function o(n){var t=n[0],r=n[1],o=n[2];return[Math.atan2(r,t)*i,Math.acos(o/Math.sqrt(t*t+r*r+o*o))*i-90]}var u=1.618033988749895,i=180/Math.PI,a=[[1,u,0],[-1,u,0],[1,-u,0],[-1,-u,0],[0,1,u],[0,-1,u],[0,1,-u],[0,-1,-u],[u,0,1],[-u,0,1],[u,0,-1],[-u,0,-1]],e=[[0,1,4],[1,9,4],[4,9,5],[5,9,3],[2,3,7],[3,2,5],[7,10,2],[0,8,10],[0,4,8],[8,2,10],[8,4,5],[8,5,2],[1,0,6],[11,1,6],[3,9,11],[6,10,7],[3,11,7],[11,6,7],[6,0,10],[9,1,11]].map(function(n){return n.map(function(n){return a[n]})});d3.geodesic={multipolygon:function(t){return{type:"MultiPolygon",coordinates:n(~~t).map(function(n){return n=n.map(o),n.push(n[0]),n=[n]})}},polygons:function(n){return d3.geodesic.multipolygon(~~n).coordinates.map(function(n){return{type:"Polygon",coordinates:n}})},multilinestring:function(n){return{type:"MultiLineString",coordinates:t(~~n).map(function(n){return n.map(o)})}}}}(); |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
#subdivision { | |
position: absolute; | |
top: 20px; | |
left: 20px; | |
} | |
#subdivision input { | |
width: 200px; | |
} | |
</style> | |
<div id="subdivision"> | |
<input type="range" min="1" max="12" value="8"> | |
<output name="subdivision"></output> | |
</div> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script src="d3.geodesic.min.js"></script> | |
<script> | |
var width = 960, | |
height = 500; | |
var velocity = [.010, .005], | |
t0 = Date.now(); | |
var projection = d3.geo.orthographic() | |
.scale(height / -1.05 - 200) | |
.translate([width/2-250, height/2]) | |
var canvas = d3.select("body").append("canvas") | |
.attr("width", width) | |
.attr("height", height); | |
var context = canvas.node().getContext("2d"); | |
context.strokeStyle = "#cccccc"; | |
context.lineWidth = .25; | |
var faces; | |
var output = d3.select("output"); | |
var input = d3.select("input") | |
.on("input", function() { geodesic(+this.value); }) | |
.on("change", function() { geodesic(+this.value); }) | |
.each(function() { geodesic(+this.value); }); | |
d3.timer(function() { | |
var time = Date.now() - t0; | |
projection.rotate([time * velocity[0], time * velocity[1]]); | |
redraw(); | |
}); | |
function redraw() { | |
context.clearRect(0, 0, width, height); | |
faces.forEach(function(d) { | |
d.polygon[0] = projection(d[0]); | |
d.polygon[1] = projection(d[1]); | |
d.polygon[2] = projection(d[2]); | |
if (d.visible = d.polygon.area() > 0) { | |
context.fillStyle = 'white'; | |
context.beginPath(); | |
drawTriangle(d.polygon); | |
context.fill(); | |
} | |
}); | |
context.beginPath(); | |
faces.forEach(function(d) { | |
if (d.visible) { | |
drawTriangle(d.polygon); | |
} | |
}); | |
context.stroke(); | |
} | |
function drawTriangle(triangle) { | |
context.moveTo(triangle[0][0], triangle[0][1]); | |
context.lineTo(triangle[1][0], triangle[1][1]); | |
context.lineTo(triangle[2][0], triangle[2][1]); | |
context.closePath(); | |
} | |
function geodesic(subdivision) { | |
output.text(subdivision); | |
faces = d3.geodesic.polygons(subdivision).map(function(d) { | |
d = d.coordinates[0]; | |
d.pop(); // use an open polygon | |
d.fill = d3.hsl(d[0][0], 1, .5) + ""; | |
d.polygon = d3.geom.polygon(d.map(projection)); | |
return d; | |
}); | |
redraw(); | |
} | |
</script> |