| 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; |
| } |
|
|