mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-26 17:54:52 +02:00
projection, half moulding
This commit is contained in:
@@ -436,12 +436,13 @@ class GraphicsAPI extends BaseAPI {
|
||||
/**
|
||||
* Reset the canvas bitmap to a uniform color.
|
||||
*/
|
||||
clear(color = `white`) {
|
||||
clear(color = `white`, preserveTransforms = false) {
|
||||
this.ctx.cacheStyle();
|
||||
this.resetTransform();
|
||||
this.ctx.fillStyle = color;
|
||||
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
this.ctx.restoreStyle();
|
||||
if (!preserveTransforms) this.resetTransform();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -34,8 +34,11 @@ class Bezier extends Original {
|
||||
this.ctx = apiInstance.ctx;
|
||||
}
|
||||
|
||||
getPointNear(point, d = 5) {
|
||||
const { x, y } = point;
|
||||
project(x, y) {
|
||||
return super.project({ x, y });
|
||||
}
|
||||
|
||||
getPointNear(x, y, d = 5) {
|
||||
const p = this.points;
|
||||
for (let i = 0, e = p.length; i < e; i++) {
|
||||
let dx = Math.abs(p[i].x - x);
|
||||
@@ -46,46 +49,6 @@ class Bezier extends Original {
|
||||
}
|
||||
}
|
||||
|
||||
getProjectionPoint(point) {
|
||||
const { x, y } = point;
|
||||
// project this point onto the curve and return _that_ point
|
||||
const n = this.lut.length - 1,
|
||||
p = this.points;
|
||||
|
||||
let d,
|
||||
closest,
|
||||
smallestDistance = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
// coarse check
|
||||
this.lut.forEach((p, i) => {
|
||||
d = p.dist(x, y);
|
||||
if (d < smallestDistance) {
|
||||
smallestDistance = d;
|
||||
p.t = i / n;
|
||||
closest = p;
|
||||
}
|
||||
});
|
||||
|
||||
// fine check
|
||||
for (let o = -0.1, t, np, st = closest.t; o <= 0.1; o += 0.005) {
|
||||
t = st + o;
|
||||
if (t < 0) continue;
|
||||
if (t > 1) continue;
|
||||
np = new Point(
|
||||
compute(t, p[0].x, p[1].x, p[2].x, p[3].x),
|
||||
compute(t, p[0].y, p[1].y, p[2].y, p[3].y)
|
||||
);
|
||||
d = np.dist(x, y);
|
||||
if (d < smallestDistance) {
|
||||
smallestDistance = d;
|
||||
closest = np;
|
||||
closest.t = t;
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
drawCurve(color = `#333`) {
|
||||
const ctx = this.ctx;
|
||||
ctx.cacheStyle();
|
||||
|
@@ -32,7 +32,7 @@ function getABC(n, S, B, E, t) {
|
||||
x: B.x + (B.x - C.x) / s,
|
||||
y: B.y + (B.y - C.y) / s,
|
||||
};
|
||||
return { A: A, B: B, C: C };
|
||||
return { A, B, C };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,6 +238,15 @@ class Bezier {
|
||||
return utils.length(this.derivative.bind(this));
|
||||
}
|
||||
|
||||
getABC(t, B) {
|
||||
let S = this.points[0];
|
||||
let E = this.points[this.order];
|
||||
let ret = getABC(this.order, S, B || this.get(t), E, t);
|
||||
ret.S = S;
|
||||
ret.E = E;
|
||||
return ret;
|
||||
}
|
||||
|
||||
getLUT(steps) {
|
||||
this.verify();
|
||||
steps = steps || 100;
|
||||
@@ -248,8 +257,11 @@ class Bezier {
|
||||
// We want a range from 0 to 1 inclusive, so
|
||||
// we decrement and then use <= rather than <:
|
||||
steps--;
|
||||
for (let t = 0; t <= steps; t++) {
|
||||
this._lut.push(this.compute(t / steps));
|
||||
for (let i = 0, p, t; i < steps; i++) {
|
||||
t = i / (steps - 1);
|
||||
p = this.compute(t);
|
||||
p.t = t;
|
||||
this._lut.push(p);
|
||||
}
|
||||
return this._lut;
|
||||
}
|
||||
|
@@ -90,12 +90,14 @@ const utils = {
|
||||
compute: function (t, points, _3d) {
|
||||
// shortcuts
|
||||
if (t === 0) {
|
||||
points[0].t = 0;
|
||||
return points[0];
|
||||
}
|
||||
|
||||
const order = points.length - 1;
|
||||
|
||||
if (t === 1) {
|
||||
points[order].t = 1;
|
||||
return points[order];
|
||||
}
|
||||
|
||||
@@ -104,6 +106,7 @@ const utils = {
|
||||
|
||||
// constant?
|
||||
if (order === 0) {
|
||||
points[0].t = t;
|
||||
return points[0];
|
||||
}
|
||||
|
||||
@@ -112,6 +115,7 @@ const utils = {
|
||||
const ret = {
|
||||
x: mt * p[0].x + t * p[1].x,
|
||||
y: mt * p[0].y + t * p[1].y,
|
||||
t: t,
|
||||
};
|
||||
if (_3d) {
|
||||
ret.z = mt * p[0].z + t * p[1].z;
|
||||
@@ -141,6 +145,7 @@ const utils = {
|
||||
const ret = {
|
||||
x: a * p[0].x + b * p[1].x + c * p[2].x + d * p[3].x,
|
||||
y: a * p[0].y + b * p[1].y + c * p[2].y + d * p[3].y,
|
||||
t: t,
|
||||
};
|
||||
if (_3d) {
|
||||
ret.z = a * p[0].z + b * p[1].z + c * p[2].z + d * p[3].z;
|
||||
@@ -162,6 +167,7 @@ const utils = {
|
||||
}
|
||||
dCpts.splice(dCpts.length - 1, 1);
|
||||
}
|
||||
dCpts[0].t = t;
|
||||
return dCpts[0];
|
||||
},
|
||||
|
||||
@@ -186,6 +192,7 @@ const utils = {
|
||||
x: (f1 * p[0].x + f2 * p[1].x) / d,
|
||||
y: (f1 * p[0].y + f2 * p[1].y) / d,
|
||||
z: !_3d ? false : (f1 * p[0].z + f2 * p[1].z) / d,
|
||||
t: t,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -200,6 +207,7 @@ const utils = {
|
||||
x: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x) / d,
|
||||
y: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y) / d,
|
||||
z: !_3d ? false : (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z) / d,
|
||||
t: t,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -217,6 +225,7 @@ const utils = {
|
||||
z: !_3d
|
||||
? false
|
||||
: (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z + f4 * p[3].z) / d,
|
||||
t: t,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
Reference in New Issue
Block a user