Download node_modules/d3-geo/src/clip/index.js from NKessler/Horizon: direct link, hf CLI and curl.
- Browser
- Download file 3.6 kB
-
https://huggingface.co/NKessler/Horizon/resolve/main/node_modules/d3-geo/src/clip/index.js
- Command line
-
hf download hf://NKessler/Horizon/node_modules/d3-geo/src/clip/index.js
-
curl -L -o index.js https://huggingface.co/NKessler/Horizon/resolve/main/node_modules/d3-geo/src/clip/index.js
3.6 kB
| import clipBuffer from "./buffer.js"; | |
| import clipRejoin from "./rejoin.js"; | |
| import {epsilon, halfPi} from "../math.js"; | |
| import polygonContains from "../polygonContains.js"; | |
| import {merge} from "d3-array"; | |
| export default function(pointVisible, clipLine, interpolate, start) { | |
| return function(sink) { | |
| var line = clipLine(sink), | |
| ringBuffer = clipBuffer(), | |
| ringSink = clipLine(ringBuffer), | |
| polygonStarted = false, | |
| polygon, | |
| segments, | |
| ring; | |
| var clip = { | |
| point: point, | |
| lineStart: lineStart, | |
| lineEnd: lineEnd, | |
| polygonStart: function() { | |
| clip.point = pointRing; | |
| clip.lineStart = ringStart; | |
| clip.lineEnd = ringEnd; | |
| segments = []; | |
| polygon = []; | |
| }, | |
| polygonEnd: function() { | |
| clip.point = point; | |
| clip.lineStart = lineStart; | |
| clip.lineEnd = lineEnd; | |
| segments = merge(segments); | |
| var startInside = polygonContains(polygon, start); | |
| if (segments.length) { | |
| if (!polygonStarted) sink.polygonStart(), polygonStarted = true; | |
| clipRejoin(segments, compareIntersection, startInside, interpolate, sink); | |
| } else if (startInside) { | |
| if (!polygonStarted) sink.polygonStart(), polygonStarted = true; | |
| sink.lineStart(); | |
| interpolate(null, null, 1, sink); | |
| sink.lineEnd(); | |
| } | |
| if (polygonStarted) sink.polygonEnd(), polygonStarted = false; | |
| segments = polygon = null; | |
| }, | |
| sphere: function() { | |
| sink.polygonStart(); | |
| sink.lineStart(); | |
| interpolate(null, null, 1, sink); | |
| sink.lineEnd(); | |
| sink.polygonEnd(); | |
| } | |
| }; | |
| function point(lambda, phi) { | |
| if (pointVisible(lambda, phi)) sink.point(lambda, phi); | |
| } | |
| function pointLine(lambda, phi) { | |
| line.point(lambda, phi); | |
| } | |
| function lineStart() { | |
| clip.point = pointLine; | |
| line.lineStart(); | |
| } | |
| function lineEnd() { | |
| clip.point = point; | |
| line.lineEnd(); | |
| } | |
| function pointRing(lambda, phi) { | |
| ring.push([lambda, phi]); | |
| ringSink.point(lambda, phi); | |
| } | |
| function ringStart() { | |
| ringSink.lineStart(); | |
| ring = []; | |
| } | |
| function ringEnd() { | |
| pointRing(ring[0][0], ring[0][1]); | |
| ringSink.lineEnd(); | |
| var clean = ringSink.clean(), | |
| ringSegments = ringBuffer.result(), | |
| i, n = ringSegments.length, m, | |
| segment, | |
| point; | |
| ring.pop(); | |
| polygon.push(ring); | |
| ring = null; | |
| if (!n) return; | |
| // No intersections. | |
| if (clean & 1) { | |
| segment = ringSegments[0]; | |
| if ((m = segment.length - 1) > 0) { | |
| if (!polygonStarted) sink.polygonStart(), polygonStarted = true; | |
| sink.lineStart(); | |
| for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]); | |
| sink.lineEnd(); | |
| } | |
| return; | |
| } | |
| // Rejoin connected segments. | |
| // TODO reuse ringBuffer.rejoin()? | |
| if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); | |
| segments.push(ringSegments.filter(validSegment)); | |
| } | |
| return clip; | |
| }; | |
| } | |
| function validSegment(segment) { | |
| return segment.length > 1; | |
| } | |
| // Intersections are sorted along the clip edge. For both antimeridian cutting | |
| // and circle clipping, the same comparison is used. | |
| function compareIntersection(a, b) { | |
| return ((a = a.x)[0] < 0 ? a[1] - halfPi - epsilon : halfPi - a[1]) | |
| - ((b = b.x)[0] < 0 ? b[1] - halfPi - epsilon : halfPi - b[1]); | |
| } | |