| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.snapLength = exports.nearestPoint = void 0;
- var util_1 = require("./util");
- var EPSILON = 0.0001;
- /**
- * 使用牛顿切割法求最近的点
- * @param {number[]} xArr 点的 x 数组
- * @param {number[]} yArr 点的 y 数组
- * @param {number} x 指定的点 x
- * @param {number} y 指定的点 y
- * @param {Function} tCallback 差值函数
- */
- function nearestPoint(xArr, yArr, x, y, tCallback, length) {
- var t;
- var d = Infinity;
- var v0 = [x, y];
- var segNum = 20;
- if (length && length > 200) {
- segNum = length / 10;
- }
- var increaseRate = 1 / segNum;
- var interval = increaseRate / 10;
- for (var i = 0; i <= segNum; i++) {
- var _t = i * increaseRate;
- var v1 = [tCallback.apply(null, xArr.concat([_t])), tCallback.apply(null, yArr.concat([_t]))];
- var d1 = util_1.distance(v0[0], v0[1], v1[0], v1[1]);
- if (d1 < d) {
- t = _t;
- d = d1;
- }
- }
- // 提前终止
- if (t === 0) {
- return {
- x: xArr[0],
- y: yArr[0],
- };
- }
- if (t === 1) {
- var count = xArr.length;
- return {
- x: xArr[count - 1],
- y: yArr[count - 1],
- };
- }
- d = Infinity;
- for (var i = 0; i < 32; i++) {
- if (interval < EPSILON) {
- break;
- }
- var prev = t - interval;
- var next = t + interval;
- var v1 = [tCallback.apply(null, xArr.concat([prev])), tCallback.apply(null, yArr.concat([prev]))];
- var d1 = util_1.distance(v0[0], v0[1], v1[0], v1[1]);
- if (prev >= 0 && d1 < d) {
- t = prev;
- d = d1;
- }
- else {
- var v2 = [tCallback.apply(null, xArr.concat([next])), tCallback.apply(null, yArr.concat([next]))];
- var d2 = util_1.distance(v0[0], v0[1], v2[0], v2[1]);
- if (next <= 1 && d2 < d) {
- t = next;
- d = d2;
- }
- else {
- interval *= 0.5;
- }
- }
- }
- return {
- x: tCallback.apply(null, xArr.concat([t])),
- y: tCallback.apply(null, yArr.concat([t])),
- };
- }
- exports.nearestPoint = nearestPoint;
- // 近似求解 https://community.khronos.org/t/3d-cubic-bezier-segment-length/62363/2
- function snapLength(xArr, yArr) {
- var totalLength = 0;
- var count = xArr.length;
- for (var i = 0; i < count; i++) {
- var x = xArr[i];
- var y = yArr[i];
- var nextX = xArr[(i + 1) % count];
- var nextY = yArr[(i + 1) % count];
- totalLength += util_1.distance(x, y, nextX, nextY);
- }
- return totalLength / 2;
- }
- exports.snapLength = snapLength;
- //# sourceMappingURL=bezier.js.map
|