Skip to content

Commit

Permalink
Add geodesic plugin.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Jul 6, 2012
1 parent 68a5ef3 commit ba8dbf5
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
3 changes: 3 additions & 0 deletions geodesic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Geodesic Grid

Example: <http://bl.ocks.org/3057239>
86 changes: 86 additions & 0 deletions geodesic/geodesic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
(function() {
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 = function(s) {
return {
type: "MultiPolygon",
coordinates: geodesic(Math.round(s)).map(function(triangle) {
triangle = triangle.map(project);
triangle.push(triangle[2]);
return [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))
]);
}
}

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
];
}
})();

0 comments on commit ba8dbf5

Please sign in to comment.