diff --git a/package.json b/package.json index 7066786..ceaeb95 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,14 @@ { "name": "Philippe Rivière", "url": "https://visionscarto.net" + }, + { + "name": "Enrico Spinielli", + "url": "https://enrico.spinielli.net/" + }, + { + "name": "Ronnie Bathoorn", + "url": "https://github.com/bathoorn" } ], "type": "module", diff --git a/src/polyhedral/butterfly.js b/src/butterfly.js similarity index 85% rename from src/polyhedral/butterfly.js rename to src/butterfly.js index 051fa68..68f1e9b 100644 --- a/src/polyhedral/butterfly.js +++ b/src/butterfly.js @@ -1,7 +1,7 @@ import {geoCentroid as centroid, geoGnomonic as gnomonic} from "d3-geo"; -import {pi} from "../math.js"; -import polyhedral from "./index.js"; -import octahedron from "./octahedron.js"; +import {pi} from "./math.js"; +import polyhedral from "./polyhedral/index.js"; +import octahedron from "./polyhedral/octahedron.js"; export default function(faceProjection = ((face) => { const c = centroid({type: "MultiPoint", coordinates: face}); diff --git a/src/collignon.js b/src/collignon.js index 57f322f..e129e1e 100644 --- a/src/collignon.js +++ b/src/collignon.js @@ -1,6 +1,9 @@ -// code duplicated from d3-geo-projection +import {geoCentroid as centroid, geoProjection as projection} from "d3-geo"; import {asin, pi, sin, sqrt, sqrtPi} from "./math.js"; +import polyhedral from "./polyhedral/index.js"; +import octahedron from "./polyhedral/octahedron.js"; +// code duplicated from d3-geo-projection export function collignonRaw(lambda, phi) { const alpha = sqrt(1 - sin(phi)); return [(2 / sqrtPi) * lambda * alpha, sqrtPi * (1 - alpha)]; @@ -10,3 +13,35 @@ collignonRaw.invert = function(x, y) { const lambda = (y / sqrtPi - 1); return [lambda ? x * sqrt(pi) / lambda / 2 : 0, asin(1 - lambda ** 2)]; }; + + +const kx = 2 / sqrt(3); + +function collignonK(a, b) { + const p = collignonRaw(a, b); + return [p[0] * kx, p[1]]; +} + +collignonK.invert = (x,y) => collignonRaw.invert(x / kx, y); + +export default function(faceProjection = (face) => { + const c = centroid({type: "MultiPoint", coordinates: face}); + return projection(collignonK).translate([0, 0]).scale(1).rotate(c[1] > 0 ? [-c[0], 0] : [180 - c[0], 180]); +}) { + const faces = octahedron.map((face) => ({face, project: faceProjection(face)})); + + [-1, 0, 0, 1, 0, 1, 4, 5].forEach((d, i) => { + const node = faces[d]; + node && (node.children || (node.children = [])).push(faces[i]); + }); + + return polyhedral( + faces[0], + (lambda, phi) => faces[lambda < -pi / 2 ? phi < 0 ? 6 : 4 + : lambda < 0 ? phi < 0 ? 2 : 0 + : lambda < pi / 2 ? phi < 0 ? 3 : 1 + : phi < 0 ? 7 : 5]) + .angle(-30) + .scale(121.906) + .center([0, 48.5904]); +} diff --git a/src/cubic.js b/src/cubic.js index 61122c6..82d6bb2 100644 --- a/src/cubic.js +++ b/src/cubic.js @@ -5,7 +5,21 @@ * */ import voronoi from "./polyhedral/voronoi.js"; -import { default as cube } from "./polyhedral/cube.js"; +import {atan, degrees, sqrt1_2} from "./math.js"; + +const phi1 = atan(sqrt1_2) * degrees; +const cube1 = [ + [0, phi1], [90, phi1], [180, phi1], [-90, phi1], + [0, -phi1], [90, -phi1], [180, -phi1], [-90, -phi1] +]; +const cube = [ + [0, 3, 2, 1], // N + [0, 1, 5, 4], + [1, 2, 6, 5], + [2, 3, 7, 6], + [3, 0, 4, 7], + [4, 5, 6, 7] // S +].map((face) => face.map((i) => cube1[i])); export default function() { const polygons = { diff --git a/src/polyhedral/dodecahedral.js b/src/dodecahedral.js similarity index 92% rename from src/polyhedral/dodecahedral.js rename to src/dodecahedral.js index a6b0c0d..fcecfb6 100644 --- a/src/polyhedral/dodecahedral.js +++ b/src/dodecahedral.js @@ -1,5 +1,5 @@ -import {acos, asin, degrees, sqrt} from "../math.js"; -import voronoi from "./voronoi.js"; +import {acos, asin, degrees, sqrt} from "./math.js"; +import voronoi from "./polyhedral/voronoi.js"; export default function() { const A0 = asin(1/sqrt(3)) * degrees; diff --git a/src/index.js b/src/index.js index 05175c1..d30a047 100644 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,11 @@ export {default as geoClipPolygon} from "./clip/polygon.js"; export {default as geoIntersectArc} from "./intersect.js"; export {default as geoPolyhedral} from "./polyhedral/index.js"; -export {default as geoPolyhedralButterfly} from "./polyhedral/butterfly.js"; -export {default as geoPolyhedralCollignon} from "./polyhedral/collignon.js"; -export {default as geoPolyhedralWaterman} from "./polyhedral/waterman.js"; +export {default as geoPolyhedralButterfly} from "./butterfly.js"; +export {default as geoPolyhedralCollignon} from "./collignon.js"; +export {default as geoPolyhedralWaterman} from "./waterman.js"; export {default as geoPolyhedralVoronoi} from "./polyhedral/voronoi.js"; -export {default as geoDodecahedral} from "./polyhedral/dodecahedral.js"; +export {default as geoDodecahedral} from "./dodecahedral.js"; export {default as geoCox, coxRaw as geoCoxRaw} from "./cox.js"; export {default as geoTetrahedralLee, leeRaw as geoLeeRaw} from "./tetrahedralLee.js"; export {default as geoGrayFullerRaw} from "./grayfuller.js"; diff --git a/src/polyhedral/collignon.js b/src/polyhedral/collignon.js deleted file mode 100644 index 8d3537d..0000000 --- a/src/polyhedral/collignon.js +++ /dev/null @@ -1,36 +0,0 @@ -import {geoCentroid as centroid, geoProjection as projection} from "d3-geo"; -import {collignonRaw} from "../collignon.js"; -import {pi, sqrt} from "../math.js"; -import polyhedral from "./index.js"; -import octahedron from "./octahedron.js"; - -const kx = 2 / sqrt(3); - -function collignonK(a, b) { - const p = collignonRaw(a, b); - return [p[0] * kx, p[1]]; -} - -collignonK.invert = (x,y) => collignonRaw.invert(x / kx, y); - -export default function(faceProjection = (face) => { - const c = centroid({type: "MultiPoint", coordinates: face}); - return projection(collignonK).translate([0, 0]).scale(1).rotate(c[1] > 0 ? [-c[0], 0] : [180 - c[0], 180]); -}) { - const faces = octahedron.map((face) => ({face, project: faceProjection(face)})); - - [-1, 0, 0, 1, 0, 1, 4, 5].forEach((d, i) => { - const node = faces[d]; - node && (node.children || (node.children = [])).push(faces[i]); - }); - - return polyhedral( - faces[0], - (lambda, phi) => faces[lambda < -pi / 2 ? phi < 0 ? 6 : 4 - : lambda < 0 ? phi < 0 ? 2 : 0 - : lambda < pi / 2 ? phi < 0 ? 3 : 1 - : phi < 0 ? 7 : 5]) - .angle(-30) - .scale(121.906) - .center([0, 48.5904]); -} diff --git a/src/polyhedral/cube.js b/src/polyhedral/cube.js deleted file mode 100644 index 97969ee..0000000 --- a/src/polyhedral/cube.js +++ /dev/null @@ -1,17 +0,0 @@ -import {atan, degrees, sqrt1_2} from "../math.js"; - -const phi1 = atan(sqrt1_2) * degrees; - -const cube = [ - [0, phi1], [90, phi1], [180, phi1], [-90, phi1], - [0, -phi1], [90, -phi1], [180, -phi1], [-90, -phi1] -]; - -export default [ - [0, 3, 2, 1], // N - [0, 1, 5, 4], - [1, 2, 6, 5], - [2, 3, 7, 6], - [3, 0, 4, 7], - [4, 5, 6, 7] // S -].map((face) => face.map((i) => cube[i])); diff --git a/src/polyhedral/waterman.js b/src/waterman.js similarity index 96% rename from src/polyhedral/waterman.js rename to src/waterman.js index 2070a69..b741885 100644 --- a/src/polyhedral/waterman.js +++ b/src/waterman.js @@ -1,7 +1,7 @@ import {geoCentroid as centroid, geoGnomonic as gnomonic} from "d3-geo"; -import {asin, atan2, cos, degrees, max, min, pi, radians, sin} from "../math.js"; -import polyhedral from "./index.js"; -import octahedron from "./octahedron.js"; +import {asin, atan2, cos, degrees, max, min, pi, radians, sin} from "./math.js"; +import polyhedral from "./polyhedral/index.js"; +import octahedron from "./polyhedral/octahedron.js"; export default function(faceProjection = ((face) => { const c = face.length === 6 ? centroid({type: "MultiPoint", coordinates: face}) : face[0];