96 lines
1.8 KiB
Java
96 lines
1.8 KiB
Java
var Util = require('../../util/index');
|
|
|
|
var vec2 = Util.vec2;
|
|
|
|
function quadraticAt(p0, p1, p2, t) {
|
|
var onet = 1 - t;
|
|
return onet * (onet * p0 + 2 * t * p1) + t * t * p2;
|
|
}
|
|
|
|
function quadraticProjectPoint(x1, y1, x2, y2, x3, y3, x, y, out) {
|
|
var t;
|
|
var interval = 0.005;
|
|
var d = Infinity;
|
|
var d1;
|
|
var v1;
|
|
var v2;
|
|
|
|
var _t;
|
|
|
|
var d2;
|
|
var i;
|
|
var EPSILON = 0.0001;
|
|
var v0 = [x, y];
|
|
|
|
for (_t = 0; _t < 1; _t += 0.05) {
|
|
v1 = [quadraticAt(x1, x2, x3, _t), quadraticAt(y1, y2, y3, _t)];
|
|
d1 = vec2.squaredDistance(v0, v1);
|
|
|
|
if (d1 < d) {
|
|
t = _t;
|
|
d = d1;
|
|
}
|
|
}
|
|
|
|
d = Infinity;
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
if (interval < EPSILON) {
|
|
break;
|
|
}
|
|
|
|
var prev = t - interval;
|
|
var next = t + interval;
|
|
v1 = [quadraticAt(x1, x2, x3, prev), quadraticAt(y1, y2, y3, prev)];
|
|
d1 = vec2.squaredDistance(v0, v1);
|
|
|
|
if (prev >= 0 && d1 < d) {
|
|
t = prev;
|
|
d = d1;
|
|
} else {
|
|
v2 = [quadraticAt(x1, x2, x3, next), quadraticAt(y1, y2, y3, next)];
|
|
d2 = vec2.squaredDistance(v0, v2);
|
|
|
|
if (next <= 1 && d2 < d) {
|
|
t = next;
|
|
d = d2;
|
|
} else {
|
|
interval *= 0.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (out) {
|
|
out.x = quadraticAt(x1, x2, x3, t);
|
|
out.y = quadraticAt(y1, y2, y3, t);
|
|
}
|
|
|
|
return Math.sqrt(d);
|
|
}
|
|
|
|
function quadraticExtrema(p0, p1, p2) {
|
|
var a = p0 + p2 - 2 * p1;
|
|
|
|
if (Util.isNumberEqual(a, 0)) {
|
|
return [0.5];
|
|
}
|
|
|
|
var rst = (p0 - p1) / a;
|
|
|
|
if (rst <= 1 && rst >= 0) {
|
|
return [rst];
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
module.exports = {
|
|
at: quadraticAt,
|
|
projectPoint: function projectPoint(x1, y1, x2, y2, x3, y3, x, y) {
|
|
var rst = {};
|
|
quadraticProjectPoint(x1, y1, x2, y2, x3, y3, x, y, rst);
|
|
return rst;
|
|
},
|
|
pointDistance: quadraticProjectPoint,
|
|
extrema: quadraticExtrema
|
|
}; |