Skip to content

Instantly share code, notes, and snippets.

@Fil
Last active June 7, 2017 21:02
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 Fil/694ba0d0bc1fc4c24eb257dc210eb01a to your computer and use it in GitHub Desktop.
Save Fil/694ba0d0bc1fc4c24eb257dc210eb01a to your computer and use it in GitHub Desktop.
Furuti 3 globe clip polygon
license: gpl-3.0

Research for d3-geo's polyhedra projections; issue #86: we need to recreate projection.clipPolygon() at least for this type of polygon.

Polygon coordinates given by adding these lines in src/polyhedra/index.js:

  var polygon = [];
  outline({point: function(λ, φ) { polygon.push([λ, φ]); }}, root);
  polygon.push(polygon[0]);
  console.log(polygon);

Here we exagerated the value of epsilon to show how this works.

With the usual epsilon, the polygon would look like a line, because its “interior” (in purple) covers the whole sphere. The green line is actually the polygon's edge on both sides. The polygon has almost no “exterior” (in white).

forked from mbostock's block: This Is a Globe

forked from Fil's block: Furuti 3 globe clip polygon

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 500;
var radius = height / 2 - 20,
scale = radius,
velocity = .015;
var projection = d3.geoOrthographic()
.translate([width / 2, height / 2])
.scale(scale)
.clipAngle(90);
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
// retina display
var devicePixelRatio = window.devicePixelRatio || 1;
canvas.style('width', canvas.attr('width')+'px');
canvas.style('height', canvas.attr('height')+'px');
canvas.attr('width', canvas.attr('width') * devicePixelRatio);
canvas.attr('height', canvas.attr('height') * devicePixelRatio);
context.scale(devicePixelRatio,devicePixelRatio);
var path = d3.geoPath()
.projection(projection)
.context(context);
d3.json("https://gist.githubusercontent.com/mbostock/4090846/raw/d534aba169207548a8a3d670c9c2cc719ff05c47/world-110m.json", function(error, world) {
if (error) throw error;
var land = topojson.feature(world, world.objects.land);
var polygon = /* f3 */
[ [ 89.42139757619105, 34.98933287542549 ],
[ 89.42139757619105, -34.98933287542549 ],
[ 0.5786024238089479, -34.98933287542549 ],
[ 0.5786024238089479, 34.98933287542549 ],
[ -0.5786024238089479, 34.98933287542549 ],
[ -0.5786024238089479, -34.98933287542549 ],
[ 0, -35.81174578592711 ],
[ 90, -35.81174578592711 ],
[ 180, -35.81174578592711 ],
[ -90, -35.81174578592711 ],
[ -89.42139757619105, -34.98933287542549 ],
[ -89.42139757619105, 34.98933287542549 ],
[ -90.57860242380896, 34.98933287542549 ],
[ -90.57860242380896, -34.98933287542549 ],
[ -179.42139757619105, -34.98933287542549 ],
[ -179.42139757619105, 34.98933287542549 ],
[ 179.42139757619105, 34.98933287542549 ],
[ 179.42139757619105, -34.98933287542549 ],
[ 90.57860242380896, -34.98933287542549 ],
[ 90.57860242380896, 34.98933287542549 ],
[ 89.42139757619105, 34.98933287542549 ] ];
d3.timer(function(elapsed) {
context.clearRect(0, 0, width, height);
projection.rotate([velocity * elapsed, 0]);
context.beginPath();
path(land);
context.lineWidth = 1;
context.strokeStyle = 'black';
context.stroke();
context.fillStyle = '#eee';
context.fill();
context.beginPath();
path({type: "Polygon", coordinates: [polygon]});
context.lineWidth = 2.5;
context.strokeStyle = '#3f3';
context.stroke();
context.fillStyle = 'rgba(0,0,100,0.1)';
context.fill();
context.beginPath();
context.arc(width / 2, height / 2, radius, 0, 2 * Math.PI, true);
context.lineWidth = 3;
context.strokeStyle = 'black';
context.stroke();
});
});
d3.select(self.frameElement).style("height", height + "px");
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment