UNPKG

d3-geo-polygon

Version:

Clipping and geometric operations for spherical polygons.

81 lines (68 loc) 1.86 kB
import { abs, atan2, cos, exp, halfPi, log, pow, sin, sqrt } from "./math.js"; export function complexAtan(x, y) { const x2 = x * x, y_1 = y + 1, t = 1 - x2 - y * y; return [ 0.5 * ((x >= 0 ? halfPi : -halfPi) - atan2(t, 2 * x)), -0.25 * log(t * t + 4 * x2) + 0.5 * log(y_1 * y_1 + x2) ]; } export function complexDivide(a, b) { if (b[1]) (a = complexMul(a, [b[0], -b[1]])), (b = complexNorm2(b)); else b = b[0]; return [a[0] / b, a[1] / b]; } export function complexMul(a, b) { return [a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]]; } export function complexAdd(a, b) { return [a[0] + b[0], a[1] + b[1]]; } export function complexSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; } export function complexNorm2(a) { return a[0] * a[0] + a[1] * a[1]; } export function complexNorm(a) { return sqrt(complexNorm2(a)); } export function complexLogHypot(a, b) { const _a = abs(a); const _b = abs(b); if (a === 0) return log(_b); if (b === 0) return log(_a); if (_a < 3000 && _b < 3000) return log(a * a + b * b) * 0.5; return log(a / cos(atan2(b, a))); } // adapted from https://github.com/infusion/Complex.js export function complexPow(a, n) { let b = a[1], arg, loh; a = a[0]; if (a === 0 && b === 0) return [0, 0]; if (typeof n === "number") n = [n, 0]; if (!n[1]) { if (b === 0 && a >= 0) { return [pow(a, n[0]), 0]; } else if (a === 0) { switch ((n[1] % 4 + 4) % 4) { case 0: return [pow(b, n[0]), 0]; case 1: return [0, pow(b, n[0])]; case 2: return [-pow(b, n[0]), 0]; case 3: return [0, -pow(b, n[0])]; } } } arg = atan2(b, a); loh = complexLogHypot(a, b); a = exp(n[0] * loh - n[1] * arg); b = n[1] * loh + n[0] * arg; return [a * cos(b), a * sin(b)]; }