(f, extent, minSteps, maxSteps)
| 119928 | // subdivide up to accuracy of 0.5 degrees |
| 119929 | const MIN_RADIANS = 0.5 * Math.PI / 180; // Adaptively sample an interpolated function over a domain extent |
| 119930 | function sampleCurve(f, extent, minSteps, maxSteps) { |
| 119931 | minSteps = minSteps || 25; |
| 119932 | maxSteps = Math.max(minSteps, maxSteps || 200); |
| 119933 | const point = (x)=>[ |
| 119934 | x, |
| 119935 | f(x) |
| 119936 | ], minX = extent[0], maxX = extent[1], span = maxX - minX, stop = span / maxSteps, prev = [ |
| 119937 | point(minX) |
| 119938 | ], next = []; |
| 119939 | if (minSteps === maxSteps) { |
| 119940 | // no adaptation, sample uniform grid directly and return |
| 119941 | for(let i = 1; i < maxSteps; ++i)prev.push(point(minX + i / minSteps * span)); |
| 119942 | prev.push(point(maxX)); |
| 119943 | return prev; |
| 119944 | } else { |
| 119945 | // sample minimum points on uniform grid |
| 119946 | // then move on to perform adaptive refinement |
| 119947 | next.push(point(maxX)); |
| 119948 | for(let i = minSteps; --i > 0;)next.push(point(minX + i / minSteps * span)); |
| 119949 | } |
| 119950 | let p0 = prev[0]; |
| 119951 | let p1 = next[next.length - 1]; |
| 119952 | const sx = 1 / span; |
| 119953 | const sy = scaleY(p0[1], next); |
| 119954 | while(p1){ |
| 119955 | // midpoint for potential curve subdivision |
| 119956 | const pm = point((p0[0] + p1[0]) / 2); |
| 119957 | const dx = pm[0] - p0[0] >= stop; |
| 119958 | if (dx && angleDelta(p0, pm, p1, sx, sy) > MIN_RADIANS) // maximum resolution has not yet been met, and |
| 119959 | // subdivision midpoint is sufficiently different from endpoint |
| 119960 | // save subdivision, push midpoint onto the visitation stack |
| 119961 | next.push(pm); |
| 119962 | else { |
| 119963 | // subdivision midpoint sufficiently similar to endpoint |
| 119964 | // skip subdivision, store endpoint, move to next point on the stack |
| 119965 | p0 = p1; |
| 119966 | prev.push(p1); |
| 119967 | next.pop(); |
| 119968 | } |
| 119969 | p1 = next[next.length - 1]; |
| 119970 | } |
| 119971 | return prev; |
| 119972 | } |
| 119973 | function scaleY(init, points1) { |
| 119974 | let ymin = init; |
| 119975 | let ymax = init; |
nothing calls this directly
no test coverage detected