NuclearDispersionSystem/ant-design-vue-jeecg/node_modules/@antv/g/lib/shapes/math/cubic.js

157 lines
3.4 KiB
Java
Raw Normal View History

2023-09-14 14:47:11 +08:00
var Util = require('../../util/index');
var vec2 = Util.vec2;
function cubicAt(p0, p1, p2, p3, t) {
var onet = 1 - t;
return onet * onet * (onet * p3 + 3 * t * p2) + t * t * (t * p0 + 3 * onet * p1);
}
function cubicDerivativeAt(p0, p1, p2, p3, t) {
var onet = 1 - t;
return 3 * (((p1 - p0) * onet + 2 * (p2 - p1) * t) * onet + (p3 - p2) * t * t);
}
function cubicProjectPoint(x1, y1, x2, y2, x3, y3, x4, y4, x, y, out) {
var t;
var interval = 0.005;
var d = Infinity;
var _t;
var v1;
var d1;
var d2;
var v2;
var prev;
var next;
var EPSILON = 0.0001;
var v0 = [x, y];
for (_t = 0; _t < 1; _t += 0.05) {
v1 = [cubicAt(x1, x2, x3, x4, _t), cubicAt(y1, y2, y3, y4, _t)];
d1 = vec2.squaredDistance(v0, v1);
if (d1 < d) {
t = _t;
d = d1;
}
}
d = Infinity;
for (var i = 0; i < 32; i++) {
if (interval < EPSILON) {
break;
}
prev = t - interval;
next = t + interval;
v1 = [cubicAt(x1, x2, x3, x4, prev), cubicAt(y1, y2, y3, y4, prev)];
d1 = vec2.squaredDistance(v0, v1);
if (prev >= 0 && d1 < d) {
t = prev;
d = d1;
} else {
v2 = [cubicAt(x1, x2, x3, x4, next), cubicAt(y1, y2, y3, y4, next)];
d2 = vec2.squaredDistance(v0, v2);
if (next <= 1 && d2 < d) {
t = next;
d = d2;
} else {
interval *= 0.5;
}
}
}
if (out) {
out.x = cubicAt(x1, x2, x3, x4, t);
out.y = cubicAt(y1, y2, y3, y4, t);
}
return Math.sqrt(d);
}
function cubicExtrema(p0, p1, p2, p3) {
var a = 3 * p0 - 9 * p1 + 9 * p2 - 3 * p3;
var b = 6 * p1 - 12 * p2 + 6 * p3;
var c = 3 * p2 - 3 * p3;
var extrema = [];
var t1;
var t2;
var discSqrt;
if (Util.isNumberEqual(a, 0)) {
if (!Util.isNumberEqual(b, 0)) {
t1 = -c / b;
if (t1 >= 0 && t1 <= 1) {
extrema.push(t1);
}
}
} else {
var disc = b * b - 4 * a * c;
if (Util.isNumberEqual(disc, 0)) {
extrema.push(-b / (2 * a));
} else if (disc > 0) {
discSqrt = Math.sqrt(disc);
t1 = (-b + discSqrt) / (2 * a);
t2 = (-b - discSqrt) / (2 * a);
if (t1 >= 0 && t1 <= 1) {
extrema.push(t1);
}
if (t2 >= 0 && t2 <= 1) {
extrema.push(t2);
}
}
}
return extrema;
}
function base3(t, p1, p2, p3, p4) {
var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4;
var t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
return t * t2 - 3 * p1 + 3 * p2;
}
function cubiclLen(x1, y1, x2, y2, x3, y3, x4, y4, z) {
if (Util.isNil(z)) {
z = 1;
}
z = z > 1 ? 1 : z < 0 ? 0 : z;
var z2 = z / 2;
var n = 12;
var Tvalues = [-0.1252, 0.1252, -0.3678, 0.3678, -0.5873, 0.5873, -0.7699, 0.7699, -0.9041, 0.9041, -0.9816, 0.9816];
var Cvalues = [0.2491, 0.2491, 0.2335, 0.2335, 0.2032, 0.2032, 0.1601, 0.1601, 0.1069, 0.1069, 0.0472, 0.0472];
var sum = 0;
for (var i = 0; i < n; i++) {
var ct = z2 * Tvalues[i] + z2;
var xbase = base3(ct, x1, x2, x3, x4);
var ybase = base3(ct, y1, y2, y3, y4);
var comb = xbase * xbase + ybase * ybase;
sum += Cvalues[i] * Math.sqrt(comb);
}
return z2 * sum;
}
module.exports = {
at: cubicAt,
derivativeAt: cubicDerivativeAt,
projectPoint: function projectPoint(x1, y1, x2, y2, x3, y3, x4, y4, x, y) {
var rst = {};
cubicProjectPoint(x1, y1, x2, y2, x3, y3, x4, y4, x, y, rst);
return rst;
},
pointDistance: cubicProjectPoint,
extrema: cubicExtrema,
len: cubiclLen
};