Skip to content

Commit

Permalink
two point equidistant clipped to the Sphere
Browse files Browse the repository at this point in the history
  • Loading branch information
Fil committed Jun 23, 2024
1 parent 69963b3 commit 6ae1419
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 10 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,17 @@ Alan K. Philbrick’s interrupted sinu-Mollweide projection.

An interrupted sinusoidal projection with asymmetrical lobe boundaries.

<a href="#geoTwoPointEquidistant" name="geoTwoPointEquidistant">#</a> d3.<b>geoTwoPointEquidistant</b>(point0, point1) · [Source](https://github.com/d3/d3-geo-polygon/blob/main/src/reclip.js)

The two-point equidistant projection, displaying 99.9996% of the sphere thanks to polygon clipping.

<a href="#geoTwoPointEquidistantUsa" name="geoTwoPointEquidistantUsa">#</a> d3.<b>geoTwoPointEquidistantUsa</b>() · [Source](https://github.com/d3/d3-geo-polygon/blob/main/src/reclip.js)

[<img src="https://raw.githubusercontent.com/d3/d3-geo-polygon/main/test/snapshots/twoPointEquidistantUsa.png" width="480" height="250">](https://observablehq.com/@d3/two-point-equidistant)

The two-point equidistant projection with points [-158°, 21.5°] and [-77°, 39°], approximately representing Honolulu, HI and Washington, D.C.

### New projections

New projections are introduced:

Expand Down
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ export {
geoInterruptedMollweide,
geoInterruptedMollweideHemispheres,
geoInterruptedSinuMollweide,
geoInterruptedSinusoidal
geoInterruptedSinusoidal,
geoTwoPointEquidistant,
geoTwoPointEquidistantUsa
} from "./reclip.js";
22 changes: 21 additions & 1 deletion src/reclip.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {merge} from "d3-array";
import {geoInterpolate} from "d3-geo";
import {geoDistance, geoInterpolate} from "d3-geo";
import {
geoBerghaus as berghaus,
geoGingery as gingery,
Expand All @@ -11,6 +11,7 @@ import {
geoInterruptedMollweideHemispheres as interruptedMollweideHemispheres,
geoInterruptedSinuMollweide as interruptedSinuMollweide,
geoInterruptedSinusoidal as interruptedSinusoidal,
geoTwoPointEquidistant as twoPointEquidistant
} from "d3-geo-projection";
import geoClipPolygon from "./clip/polygon.js";

Expand All @@ -27,6 +28,8 @@ export function geoInterruptedMollweide() { return clipInterrupted(interruptedMo
export function geoInterruptedMollweideHemispheres() { return clipInterrupted(interruptedMollweideHemispheres.apply(this, arguments)); }
export function geoInterruptedSinuMollweide() { return clipInterrupted(interruptedSinuMollweide.apply(this, arguments)); }
export function geoInterruptedSinusoidal() { return clipInterrupted(interruptedSinusoidal.apply(this, arguments)); }
export function geoTwoPointEquidistant() { return clipTwoPointEquidistant.apply(this, arguments); }
export function geoTwoPointEquidistantUsa() { return geoTwoPointEquidistant([-158, 21.5], [-77, 39]); }

function reclip(projection, vertical = false) {
const {lobes} = projection;
Expand Down Expand Up @@ -97,3 +100,20 @@ function clipInterrupted(projection) {

return reset(projection);
}

function clipTwoPointEquidistant(a, b) {
const epsilon = 1e-3;
const u = geoDistance(a, b) * 90 / Math.PI + epsilon;
const ellipse = {
type: "Polygon",
coordinates: [[
[180 - u, epsilon],
[180 - u, -epsilon],
[-180 + u, -epsilon],
[-180 + u, epsilon],
[180 - u, epsilon]
]
]
};
return twoPointEquidistant(a, b).preclip(geoClipPolygon(ellipse).clipPoint(false));
}
24 changes: 16 additions & 8 deletions test/snapshots.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
geoPolyhedralCollignon,
geoPolyhedralWaterman,
geoTetrahedralLee,
geoTwoPointEquidistantUsa
} from "../src/index.js";

const width = 960;
Expand Down Expand Up @@ -138,7 +139,7 @@ export async function tetrahedralLeeSouth() {
.rotate([-30, 0])
.angle(-30)
.precision(0.1)
.fitSize([960, 500], { type: "Sphere" })
.fitSize([width, height], { type: "Sphere" })
);
}

Expand All @@ -152,19 +153,19 @@ export async function gingery() {
}

export async function berghaus7() {
return renderWorld(geoBerghaus().lobes(7).fitSize([960, 500], { type: "Sphere" }));
return renderWorld(geoBerghaus().lobes(7).fitSize([width, height], { type: "Sphere" }));
}

export async function berghaus13() {
return renderWorld(geoBerghaus().lobes(13).fitSize([960, 500], { type: "Sphere" }));
return renderWorld(geoBerghaus().lobes(13).fitSize([width, height], { type: "Sphere" }));
}

export async function gingery7() {
return renderWorld(geoGingery().lobes(7).fitSize([960, 500], { type: "Sphere" }));
return renderWorld(geoGingery().lobes(7).fitSize([width, height], { type: "Sphere" }));
}

export async function gingery3() {
return renderWorld(geoGingery().lobes(3).fitSize([960, 500], { type: "Sphere" }));
return renderWorld(geoGingery().lobes(3).fitSize([width, height], { type: "Sphere" }));
}

export async function goodeOcean() {
Expand Down Expand Up @@ -242,6 +243,13 @@ export async function interruptedSinusoidal() {
return renderWorld(geoInterruptedSinusoidal());
}

// https://github.com/d3/d3-geo/issues/46
export async function twoPointEquidistantUsa() {
return renderWorld(
geoTwoPointEquidistantUsa().fitSize([width, height], { type: "Sphere" })
);
}

// more tests

// https://github.com/d3/d3-geo-polygon/issues/7
Expand All @@ -250,7 +258,7 @@ export async function cubic45() {
geoCubic()
.parents([-1, 2, 0, 2, 5, 2])
.rotate([0, 0, 45])
.fitSize([960, 500], { type: "Sphere" })
.fitSize([width, height], { type: "Sphere" })
);
}

Expand All @@ -274,7 +282,7 @@ export async function rhombicHalf1() {
geoRhombic()
.parents([-1, 0, 6, 2, 1, 9, 11, 3, 4, 8, 6, 10])
.precision(0.1)
.fitSize([960, 500], { type: "Sphere" })
.fitSize([width, height], { type: "Sphere" })
);
}
export async function rhombicHalf2() {
Expand All @@ -283,7 +291,7 @@ export async function rhombicHalf2() {
.parents([4, 0, 6, 2, 1, 9, 11, 3, 4, 8, -1, 10])
.angle(-19.5)
.precision(0.1)
.fitSize([960, 500], { type: "Sphere" })
.fitSize([width, height], { type: "Sphere" })
);
}

Expand Down
Binary file added test/snapshots/twoPointEquidistantUsa.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 6ae1419

Please sign in to comment.