Published
Edited
Dec 5, 2021
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Martin Roberts’ original function
function gap0(n) {
return n < 80 ? 2.66 : n < 1e3 ? 3.33 : n < 4e4 ? 10 : 25;
}
Insert cell
// Jacob’s suggestion
function gap1(n) {
return Math.pow(2, 0.25 * Math.log2(n + 40));
}
Insert cell
// Fil’s tweaking
function gap2(n) {
return 0.5 * (n + 40) ** 0.15;
}
Insert cell
// Fil’s constant (obtained by optimizing for the size of the last cell)
function gap3(n) {
return 0.7012;
}
Insert cell
// @jrus' implementation of http://extremelearning.com.au/how-to-evenly-distribute-points-on-a-sphere-more-effectively-than-the-canonical-fibonacci-lattice/
// with a mult tweak
function* fib_pts(n, gap) {
const lonstep = 720 / (Math.sqrt(5) + 1);
const degrees = 180 / Math.PI;
const polegap = gap(n);
const latstep = 2 / (n - 1 + 2 * polegap); // not n-3!
const latstart = -1 + polegap * latstep;

yield [0, -90];
if (n <= 1) return;
for (let i = 1; i < n - 1; i++) {
const lon = lonstep * i - 360 * Math.round((lonstep * i) / 360);
const lat = degrees * Math.asin(latstart + i * latstep);
yield [lon, lat];
}
yield [0, 90];
}
Insert cell
points = Array.from(fib_pts(n, gap))
Insert cell
Insert cell
projection = d3
//.geoOrthographic()
.geoInterruptedMollweideHemispheres()
.rotate([90, 0, -90])
.fitExtent(
[
[1, 1],
[width - 1, height - 1]
],
sphere
)
//.rotate([0, -30])
.precision(0.1)
Insert cell
height = 640
Insert cell
sphere = ({type: "Sphere"})
Insert cell
graticule = d3.geoGraticule10()
Insert cell
d3 = require("d3@7", "d3-geo-projection@3", "d3-inertia@0.2", "d3-geo-voronoi@2")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more