| import {cartesian, cartesianNormalizeInPlace, spherical} from "./cartesian.js"; |
| import constant from "./constant.js"; |
| import {acos, cos, degrees, epsilon, radians, sin, tau} from "./math.js"; |
| import {rotateRadians} from "./rotation.js"; |
|
|
| |
| export function circleStream(stream, radius, delta, direction, t0, t1) { |
| if (!delta) return; |
| var cosRadius = cos(radius), |
| sinRadius = sin(radius), |
| step = direction * delta; |
| if (t0 == null) { |
| t0 = radius + direction * tau; |
| t1 = radius - step / 2; |
| } else { |
| t0 = circleRadius(cosRadius, t0); |
| t1 = circleRadius(cosRadius, t1); |
| if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau; |
| } |
| for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) { |
| point = spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]); |
| stream.point(point[0], point[1]); |
| } |
| } |
|
|
| |
| function circleRadius(cosRadius, point) { |
| point = cartesian(point), point[0] -= cosRadius; |
| cartesianNormalizeInPlace(point); |
| var radius = acos(-point[1]); |
| return ((-point[2] < 0 ? -radius : radius) + tau - epsilon) % tau; |
| } |
|
|
| export default function() { |
| var center = constant([0, 0]), |
| radius = constant(90), |
| precision = constant(2), |
| ring, |
| rotate, |
| stream = {point: point}; |
|
|
| function point(x, y) { |
| ring.push(x = rotate(x, y)); |
| x[0] *= degrees, x[1] *= degrees; |
| } |
|
|
| function circle() { |
| var c = center.apply(this, arguments), |
| r = radius.apply(this, arguments) * radians, |
| p = precision.apply(this, arguments) * radians; |
| ring = []; |
| rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert; |
| circleStream(stream, r, p, 1); |
| c = {type: "Polygon", coordinates: [ring]}; |
| ring = rotate = null; |
| return c; |
| } |
|
|
| circle.center = function(_) { |
| return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), circle) : center; |
| }; |
|
|
| circle.radius = function(_) { |
| return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), circle) : radius; |
| }; |
|
|
| circle.precision = function(_) { |
| return arguments.length ? (precision = typeof _ === "function" ? _ : constant(+_), circle) : precision; |
| }; |
|
|
| return circle; |
| } |
|
|