56 lines
2.3 KiB
JavaScript
56 lines
2.3 KiB
JavaScript
import { curves } from "../const.mjs";
|
|
class BezierUtils {
|
|
/**
|
|
* Calculate length of bezier curve.
|
|
* Analytical solution is impossible, since it involves an integral that does not integrate in general.
|
|
* Therefore numerical solution is used.
|
|
* @private
|
|
* @param fromX - Starting point x
|
|
* @param fromY - Starting point y
|
|
* @param cpX - Control point x
|
|
* @param cpY - Control point y
|
|
* @param cpX2 - Second Control point x
|
|
* @param cpY2 - Second Control point y
|
|
* @param toX - Destination point x
|
|
* @param toY - Destination point y
|
|
* @returns - Length of bezier curve
|
|
*/
|
|
static curveLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY) {
|
|
let result = 0, t = 0, t2 = 0, t3 = 0, nt = 0, nt2 = 0, nt3 = 0, x = 0, y = 0, dx = 0, dy = 0, prevX = fromX, prevY = fromY;
|
|
for (let i = 1; i <= 10; ++i)
|
|
t = i / 10, t2 = t * t, t3 = t2 * t, nt = 1 - t, nt2 = nt * nt, nt3 = nt2 * nt, x = nt3 * fromX + 3 * nt2 * t * cpX + 3 * nt * t2 * cpX2 + t3 * toX, y = nt3 * fromY + 3 * nt2 * t * cpY + 3 * nt * t2 * cpY2 + t3 * toY, dx = prevX - x, dy = prevY - y, prevX = x, prevY = y, result += Math.sqrt(dx * dx + dy * dy);
|
|
return result;
|
|
}
|
|
/**
|
|
* Calculate the points for a bezier curve and then draws it.
|
|
*
|
|
* Ignored from docs since it is not directly exposed.
|
|
* @ignore
|
|
* @param cpX - Control point x
|
|
* @param cpY - Control point y
|
|
* @param cpX2 - Second Control point x
|
|
* @param cpY2 - Second Control point y
|
|
* @param toX - Destination point x
|
|
* @param toY - Destination point y
|
|
* @param points - Path array to push points into
|
|
*/
|
|
static curveTo(cpX, cpY, cpX2, cpY2, toX, toY, points) {
|
|
const fromX = points[points.length - 2], fromY = points[points.length - 1];
|
|
points.length -= 2;
|
|
const n = curves._segmentsCount(
|
|
BezierUtils.curveLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY)
|
|
);
|
|
let dt = 0, dt2 = 0, dt3 = 0, t2 = 0, t3 = 0;
|
|
points.push(fromX, fromY);
|
|
for (let i = 1, j = 0; i <= n; ++i)
|
|
j = i / n, dt = 1 - j, dt2 = dt * dt, dt3 = dt2 * dt, t2 = j * j, t3 = t2 * j, points.push(
|
|
dt3 * fromX + 3 * dt2 * j * cpX + 3 * dt * t2 * cpX2 + t3 * toX,
|
|
dt3 * fromY + 3 * dt2 * j * cpY + 3 * dt * t2 * cpY2 + t3 * toY
|
|
);
|
|
}
|
|
}
|
|
export {
|
|
BezierUtils
|
|
};
|
|
//# sourceMappingURL=BezierUtils.mjs.map
|