(function() { // From http://bl.ocks.org/mbostock/3057239 var φ = 1.618033988749895, ρ = 180 / Math.PI; var vertices = [ [1,φ,0], [-1,φ,0], [1,-φ,0], [-1,-φ,0], [0,1,φ], [0,-1,φ], [0,1,-φ], [0,-1,-φ], [φ,0,1], [-φ,0,1], [φ,0,-1], [-φ,0,-1] ]; var triangles = [ [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(triangle) { return triangle.map(function(i) { return vertices[i]; }); }); d3.geodesic = { multipolygon: function(n) { return { type: "MultiPolygon", coordinates: geodesic(~~n).map(function(triangle) { triangle = triangle.map(project); triangle.push(triangle[0]); return [triangle]; }) }; }, polygons: function(n) { return geodesic(~~n).map(function(triangle) { triangle = triangle.map(project); triangle.push(triangle[0]); return {type: "Polygon", coordinates: [triangle]}; }); } }; function geodesic(n) { return d3.merge(triangles.map(function(triangle) { var i01 = interpolate(triangle[0], triangle[1]), i02 = interpolate(triangle[0], triangle[2]), triangles = []; triangles.push([ triangle[0], i01(1 / n), i02(1 / n) ]); for (var i = 1; i < n; ++i) { var i1 = interpolate(i01(i / n), i02(i / n)), i2 = interpolate(i01((i + 1) / n), i02((i + 1) / n)); for (var j = 0; j <= i; ++j) { triangles.push([ i1(j / i), i2(j / (i + 1)), i2((j + 1) / (i + 1)) ]); } for (var j = 0; j < i; ++j) { triangles.push([ i1(j / i), i1((j + 1) / i), i2((j + 1) / (i + 1)) ]); } } return triangles; })); } function interpolate(p0, p1) { var x0 = p0[0], y0 = p0[1], z0 = p0[2], x1 = p1[0] - x0, y1 = p1[1] - y0, z1 = p1[2] - z0; return function(t) { return [ x0 + t * x1, y0 + t * y1, z0 + t * z1 ]; }; } function project(p) { var x = p[0], y = p[1], z = p[2]; return [ Math.atan2(y, x) * ρ, Math.acos(z / Math.sqrt(x * x + y * y + z * z)) * ρ - 90 ]; } })();