Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Split out quincuncial projection code.

This will be reused by Gringorten, and any other projections in future
that project a hemisphere into a square.
  • Loading branch information...
commit 77f0b92a89c2a4bd4e23cfb15df88d6e5e8600c6 1 parent 2c461f9
Jason Davies jasondavies authored
1  Makefile
View
@@ -11,6 +11,7 @@ d3.geo.projection.js: \
geo/projection/projection.js \
geo/projection/parallel1.js \
geo/projection/parallel2.js \
+ geo/projection/quincuncial.js \
geo/projection/interrupt.js \
geo/projection/elliptic.js \
geo/projection/aitoff.js \
16 geo/projection/guyou.js
View
@@ -1,4 +1,5 @@
// @import elliptic
+// @import quincuncial
// √k' tn(½K - w) = exp(-ζ).
function guyou(λ, φ) {
@@ -8,15 +9,12 @@ function guyou(λ, φ) {
K = ellipticF(π / 2, k * k),
f = -1;
- var s = λ > 0 ? -1 : 1;
- λ += s * π / 2;
-
var ψ = Math.log(Math.tan(π / 4 + Math.abs(φ) / 2)),
r = Math.exp(f * ψ) / Math.sqrt(k_),
at = guyouComplexAtan(r * Math.cos(f * λ), r * Math.sin(f * λ)),
t = ellipticFi(at[0], at[1], k * k);
- return [-s * .5 * K - t[1], sgn(φ) * (.5 * K - t[0])];
+ return [-t[1], sgn(φ) * (.5 * K - t[0])];
}
function guyouComplexAtan(x, y) {
@@ -43,13 +41,9 @@ guyou.invert = function(x, y) {
K = ellipticF(π / 2, k * k),
f = -1;
- var s = x > 0 ? -1 : 1;
-
- var j = ellipticJi(.5 * K - y, -s * .5 * K - x, k * k),
+ var j = ellipticJi(.5 * K - y, -x, k * k),
tn = guyouComplexDivide(j[0], j[1]),
- λ = Math.atan2(tn[1], tn[0]) / f - s * π / 2;
- if< -π) λ += 2 * π;
- else if> π) λ -= 2 * π;
+ λ = Math.atan2(tn[1], tn[0]) / f;
return [
λ,
@@ -57,4 +51,4 @@ guyou.invert = function(x, y) {
];
};
-(d3.geo.guyou = function() { return projection(guyou); }).raw = guyou;
+d3.geo.guyou = quincuncialProjection(guyou);
50 geo/projection/peirce-quincuncial.js
View
@@ -1,50 +1,6 @@
// @import guyou
+// @import quincuncial
-function peirceQuincuncial(λ, φ) {
- var k_ = (Math.SQRT2 - 1) / (Math.SQRT2 + 1),
- k = Math.sqrt(1 - k_ * k_),
- K = ellipticF(π / 2, k * k);
+var peirceQuincuncialProjection = quincuncialProjection(guyou);
- var t = Math.abs(λ) < π / 2,
- p = guyou(λ +< -π / 2 ? 1.5 : -.5) * π, φ);
-
- p[0] += (t ? .5 : -.5) * K;
-
- var x = (p[0] - p[1]) * Math.SQRT1_2,
- y = (p[0] + p[1]) * Math.SQRT1_2;
-
- if (t) return [x, y];
-
- var d = K * Math.SQRT1_2,
- s = x > 0 ^ y > 0 ? -1 : 1;
-
- return [s * x - sgn(y) * d, s * y - sgn(x) * d];
-}
-
-peirceQuincuncial.invert = function(x0, y0) {
- var k_ = (Math.SQRT2 - 1) / (Math.SQRT2 + 1),
- k = Math.sqrt(1 - k_ * k_),
- K = ellipticF(π / 2, k * k);
-
- var x = (x0 + y0) * Math.SQRT1_2,
- y = (y0 - x0) * Math.SQRT1_2;
-
- var t = Math.abs(x) < .5 * K && Math.abs(y) < .5 * K;
-
- if (!t) {
- var d = K * Math.SQRT1_2,
- s = x > 0 ^ y > 0 ? -1 : 1,
- x1 = -s * (x0 + (y > 0 ? 1 : -1) * d),
- y1 = -s * (y0 + (x > 0 ? 1 : -1) * d);
- x = (-x1 - y1) * Math.SQRT1_2;
- y = (x1 - y1) * Math.SQRT1_2;
- }
-
- x -= (t ? .5 : -.5) * K;
-
- var p = guyou.invert(x, y);
- p[0] += .5 * π;
- return p;
-};
-
-(d3.geo.peirceQuincuncial = function() { return projection(peirceQuincuncial).rotate([-90, -90, 45]).clipAngle(180 - 1e-6); }).raw = peirceQuincuncial;
+(d3.geo.peirceQuincuncial = function() { return peirceQuincuncialProjection().quincuncial(true).rotate([-90, -90, 45]).clipAngle(180 - 1e-6); }).raw = peirceQuincuncialProjection.raw;
82 geo/projection/quincuncial.js
View
@@ -0,0 +1,82 @@
+function quincuncialProjection(projectHemisphere) {
+ var dx = projectHemisphere(π / 2, 0)[0] - projectHemisphere(-π / 2, 0)[0];
+
+ function projection() {
+ var quincuncial = false,
+ m = projectionMutator(projectAt),
+ p = m(quincuncial);
+
+ p.quincuncial = function(_) {
+ if (!arguments.length) return quincuncial;
+ return m(quincuncial = !!_);
+ };
+
+ return p;
+ }
+
+ function projectAt(quincuncial) {
+ var forward;
+
+ if (quincuncial) {
+
+ forward = function(λ, φ) {
+ var t = Math.abs(λ) < π / 2,
+ p = projectHemisphere(t ? λ : λ > 0 ? λ - π : λ + π, φ);
+
+ var x = (p[0] - p[1]) * Math.SQRT1_2,
+ y = (p[0] + p[1]) * Math.SQRT1_2;
+
+ if (t) return [x, y];
+
+ var d = dx * Math.SQRT1_2,
+ s = x > 0 ^ y > 0 ? -1 : 1;
+
+ return [s * x - sgn(y) * d, s * y - sgn(x) * d];
+ };
+
+ forward.invert = function(x0, y0) {
+ var x = (x0 + y0) * Math.SQRT1_2,
+ y = (y0 - x0) * Math.SQRT1_2,
+ t = Math.abs(x) < .5 * dx && Math.abs(y) < .5 * dx;
+
+ if (!t) {
+ var d = dx * Math.SQRT1_2,
+ s = x > 0 ^ y > 0 ? -1 : 1,
+ x1 = -s * (x0 + (y > 0 ? 1 : -1) * d),
+ y1 = -s * (y0 + (x > 0 ? 1 : -1) * d);
+ x = (-x1 - y1) * Math.SQRT1_2;
+ y = (x1 - y1) * Math.SQRT1_2;
+ }
+
+ var p = projectHemisphere.invert(x, y);
+ if (!t) p[0] += x > 0 ? π : -π;
+ return p;
+ };
+
+ } else {
+
+ forward = function(λ, φ) {
+ var s = λ > 0 ? -.5 : .5,
+ point = projectHemisphere(λ + s * π, φ);
+ point[0] -= s * dx;
+ return point;
+ };
+
+ forward.invert = function(x, y) {
+ var s = x > 0 ? -.5 : .5,
+ location = projectHemisphere.invert(x + s * dx, y),
+ λ = location[0] - s * π;
+ if< -π) λ += 2 * π;
+ else if> π) λ -= 2 * π;
+ location[0] = λ;
+ return location;
+ };
+ }
+
+ return forward;
+ }
+
+ projection.raw = projectAt;
+
+ return projection;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.