|
import {Adder} from "d3-array"; |
|
import {atan2, cos, quarterPi, radians, sin, tau} from "./math.js"; |
|
import noop from "./noop.js"; |
|
import stream from "./stream.js"; |
|
|
|
export var areaRingSum = new Adder(); |
|
|
|
|
|
|
|
var areaSum = new Adder(), |
|
lambda00, |
|
phi00, |
|
lambda0, |
|
cosPhi0, |
|
sinPhi0; |
|
|
|
export var areaStream = { |
|
point: noop, |
|
lineStart: noop, |
|
lineEnd: noop, |
|
polygonStart: function() { |
|
areaRingSum = new Adder(); |
|
areaStream.lineStart = areaRingStart; |
|
areaStream.lineEnd = areaRingEnd; |
|
}, |
|
polygonEnd: function() { |
|
var areaRing = +areaRingSum; |
|
areaSum.add(areaRing < 0 ? tau + areaRing : areaRing); |
|
this.lineStart = this.lineEnd = this.point = noop; |
|
}, |
|
sphere: function() { |
|
areaSum.add(tau); |
|
} |
|
}; |
|
|
|
function areaRingStart() { |
|
areaStream.point = areaPointFirst; |
|
} |
|
|
|
function areaRingEnd() { |
|
areaPoint(lambda00, phi00); |
|
} |
|
|
|
function areaPointFirst(lambda, phi) { |
|
areaStream.point = areaPoint; |
|
lambda00 = lambda, phi00 = phi; |
|
lambda *= radians, phi *= radians; |
|
lambda0 = lambda, cosPhi0 = cos(phi = phi / 2 + quarterPi), sinPhi0 = sin(phi); |
|
} |
|
|
|
function areaPoint(lambda, phi) { |
|
lambda *= radians, phi *= radians; |
|
phi = phi / 2 + quarterPi; |
|
|
|
|
|
|
|
|
|
var dLambda = lambda - lambda0, |
|
sdLambda = dLambda >= 0 ? 1 : -1, |
|
adLambda = sdLambda * dLambda, |
|
cosPhi = cos(phi), |
|
sinPhi = sin(phi), |
|
k = sinPhi0 * sinPhi, |
|
u = cosPhi0 * cosPhi + k * cos(adLambda), |
|
v = k * sdLambda * sin(adLambda); |
|
areaRingSum.add(atan2(v, u)); |
|
|
|
|
|
lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi; |
|
} |
|
|
|
export default function(object) { |
|
areaSum = new Adder(); |
|
stream(object, areaStream); |
|
return areaSum * 2; |
|
} |
|
|