aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/bezierFit.ts242
1 files changed, 112 insertions, 130 deletions
diff --git a/src/client/util/bezierFit.ts b/src/client/util/bezierFit.ts
index 57c6dbbde..784bb2e18 100644
--- a/src/client/util/bezierFit.ts
+++ b/src/client/util/bezierFit.ts
@@ -1,5 +1,4 @@
import { Point } from "../../pen-gestures/ndollar";
-import { max } from "lodash";
class SmartRect {
minx: number = 0;
@@ -21,45 +20,38 @@ class SmartRect {
public ContainsPercentage(other: SmartRect, axis: Point) {
var ret = 0;
- var minx = Math.max(other.TopLeft.X * axis.X + other.TopLeft.Y * axis.Y, this.TopLeft.X * axis.X + this.TopLeft.Y * axis.Y);
- var maxx = Math.max(other.BotRight.X * axis.X + other.BotRight.Y * axis.Y, this.BotRight.X * axis.X + this.BotRight.Y * axis.Y);
- ret = maxx > minx ? (maxx - minx) / (axis == new Point(1, 0) ? other.Width : other.Height) : 0;
+ const minx = Math.max(other.TopLeft.X * axis.X + other.TopLeft.Y * axis.Y, this.TopLeft.X * axis.X + this.TopLeft.Y * axis.Y);
+ const maxx = Math.max(other.BotRight.X * axis.X + other.BotRight.Y * axis.Y, this.BotRight.X * axis.X + this.BotRight.Y * axis.Y);
+ ret = maxx > minx ? (maxx - minx) / (axis === new Point(1, 0) ? other.Width : other.Height) : 0;
return ret;
}
public static Bounds(p: Point[]) {
- var r = new SmartRect();
+ const r = new SmartRect();
if (p.length > 0) {
r.minx = p[0].X; // These are the most likely to be extremal
r.maxx = p.lastElement().X;
r.miny = p[0].Y;
r.maxy = p.lastElement().Y;
- if (r.minx > r.maxx) {
- var tmp = r.minx;
- r.minx = r.maxx;
- r.maxx = tmp;
- }
- if (r.miny > r.maxy) {
- var tmp = r.miny;
- r.miny = r.maxy;
- r.maxy = tmp;
- }
+ if (r.minx > r.maxx) [r.minx, r.maxx] = [r.maxx, r.minx];
+ if (r.miny > r.maxy) [r.miny, r.maxy] = [r.maxy, r.miny];
- for (var pt of p) {
- if (pt.X < r.minx)
+ for (const pt of p) {
+ if (pt.X < r.minx) {
r.minx = pt.X;
- else if (pt.X > r.maxx)
+ } else if (pt.X > r.maxx) {
r.maxx = pt.X;
-
- if (pt.Y < r.miny)
+ }
+ if (pt.Y < r.miny) {
r.miny = pt.Y;
- else if (pt.Y > r.maxy)
+ } else if (pt.Y > r.maxy) {
r.maxy = pt.Y;
+ }
}
}
return r;
}
-};
+}
function Normalize(p: Point) {
const len = Math.sqrt(p.X * p.X + p.Y * p.Y);
@@ -67,7 +59,7 @@ function Normalize(p: Point) {
}
function ReparameterizeBezier(d: Point[], first: number, last: number, u: number[], bezCurve: Point[]) {
- var uPrime = new Array<number>(last - first + 1); // New parameter values
+ const uPrime = new Array<number>(last - first + 1); // New parameter values
for (var i = first; i <= last; i++) {
uPrime[i - first] = NewtonRaphsonRootFind(bezCurve, d[i], u[i - first]);
@@ -76,36 +68,36 @@ function ReparameterizeBezier(d: Point[], first: number, last: number, u: number
}
function ComputeMaxError(d: Point[], first: number, last: number, bezCurve: Point[], u: number[]) {
var maxError = 0; // Maximum error
-
var splitPoint2D = (last - first + 1) / 2;
for (var i = first + 1; i < last; i++) {
- var P = [0, 0]; // point on curve
+ const P = [0, 0]; // point on curve
EvalBezierFast(bezCurve, u[i - first], P);
- var dx = P[0] - d[i].X;// offset from point to curve
- var dy = P[1] - d[i].Y;
- var dist = Math.sqrt(dx * dx + dy * dy); // Current error
+ const dx = P[0] - d[i].X;// offset from point to curve
+ const dy = P[1] - d[i].Y;
+ const dist = Math.sqrt(dx * dx + dy * dy); // Current error
if (dist >= maxError) {
maxError = dist;
- if (splitPoint2D)
+ if (splitPoint2D) {
splitPoint2D = i;
+ }
}
}
return { maxError, splitPoint2D };
}
function ChordLengthParameterize(d: Point[], first: number, last: number) {
- var u = new Array<number>(last - first + 1);// Parameterization
+ const u = new Array<number>(last - first + 1);// Parameterization
var prev = 0.0;
u[0] = prev;
for (var i = first + 1; i <= last; i++) {
- var lastd = d[i - 1];
- var curd = d[i];
- var dx = lastd.X - curd.X;
- var dy = lastd.Y - curd.Y;
+ const lastd = d[i - 1];
+ const curd = d[i];
+ const dx = lastd.X - curd.X;
+ const dy = lastd.Y - curd.Y;
prev = u[i - first] = prev + Math.sqrt(dx * dx + dy * dy);
}
- var ulastfirst = u[last - first];
+ const ulastfirst = u[last - first];
for (var i = first + 1; i <= last; i++) {
u[i - first] /= ulastfirst;
}
@@ -116,12 +108,12 @@ function ChordLengthParameterize(d: Point[], first: number, last: number) {
* B0, B1, B2, B3 :
* Bezier multipliers
*/
-function B0(u: number) { var tmp = 1.0 - u; return tmp * tmp * tmp; }
-function B1(u: number) { var tmp = 1.0 - u; return 3 * u * tmp * tmp; }
-function B2(u: number) { var tmp = 1.0 - u; return 3 * u * u * tmp; }
+function B0(u: number) { const tmp = 1.0 - u; return tmp * tmp * tmp; }
+function B1(u: number) { const tmp = 1.0 - u; return 3 * u * tmp * tmp; }
+function B2(u: number) { const tmp = 1.0 - u; return 3 * u * u * tmp; }
function B3(u: number) { return u * u * u; }
function bounds(p: Point[]) {
- var r = new SmartRect(p[0].X, p[0].Y, p[3].X, p[3].Y); // These are the most likely to be extremal
+ const r = new SmartRect(p[0].X, p[0].Y, p[3].X, p[3].Y); // These are the most likely to be extremal
if (r.minx > r.maxx) (r.minx, r.maxx);
if (r.miny > r.maxy) [r.miny, r.maxy] = [r.maxy, r.miny]; // swap min & max
@@ -137,10 +129,9 @@ function bounds(p: Point[]) {
}
-
function splitCubic(p: Point[], t: number, left: Point[], right: Point[]) {
- var sz = 4;
- var Vtemp = new Array<Array<Point>>(4);
+ const sz = 4;
+ const Vtemp = new Array<Array<Point>>(4);
for (var i = 0; i < 4; i++) Vtemp[i] = new Array<Point>(4);
/* Copy control points */
@@ -153,8 +144,8 @@ function splitCubic(p: Point[], t: number, left: Point[], right: Point[]) {
/* Triangle computation */
for (var i = 1; i < sz; i++) {
for (var j = 0; j < sz - i; j++) {
- var a = Vtemp[i - 1][j];
- var b = Vtemp[i - 1][j + 1];
+ const a = Vtemp[i - 1][j];
+ const b = Vtemp[i - 1][j + 1];
Vtemp[i][j].X = b.X * t + a.X * (1 - t);
Vtemp[i][j].Y = b.Y * t + a.Y * (1 - t); // Vtemp[i][j] = Point2D::Lerp(Vtemp[i - 1][j], Vtemp[i - 1][j + 1], t);
}
@@ -214,14 +205,14 @@ function splitCubic(p: Point[], t: number, left: Point[], right: Point[]) {
*/
function recursively_intersect(a: Point[], t0: number, t1: number, deptha: number, b: Point[], u0: number, u1: number, depthb: number, parameters: number[][]) {
if (deptha > 0) {
- var a1 = new Array<Point>(4), a2 = new Array<Point>(4);
+ const a1 = new Array<Point>(4), a2 = new Array<Point>(4);
splitCubic(a, 0.5, a1, a2);
- var tmid = (t0 + t1) * 0.5;
+ const tmid = (t0 + t1) * 0.5;
deptha--;
if (depthb > 0) {
- var b1 = new Array<Point>(4), b2 = new Array<Point>(4);
+ const b1 = new Array<Point>(4), b2 = new Array<Point>(4);
splitCubic(b, 0.5, b1, b2);
- var umid = (u0 + u1) * 0.5;
+ const umid = (u0 + u1) * 0.5;
depthb--;
if (SmartRect.Intersect(bounds(a1), bounds(b1))) {
recursively_intersect(a1, t0, tmid, deptha, b1, u0, umid, depthb, parameters);
@@ -247,9 +238,9 @@ function recursively_intersect(a: Point[], t0: number, t1: number, deptha: numbe
}
else {
if (depthb > 0) {
- var b1 = new Array<Point>(4), b2 = new Array<Point>(4);
+ const b1 = new Array<Point>(4), b2 = new Array<Point>(4);
splitCubic(b, 0.5, b1, b2);
- var umid = (u0 + u1) * 0.5;
+ const umid = (u0 + u1) * 0.5;
depthb--;
if (SmartRect.Intersect(bounds(a), bounds(b1))) {
recursively_intersect(a, t0, t1, deptha, b1, u0, umid, depthb, parameters);
@@ -260,20 +251,20 @@ function recursively_intersect(a: Point[], t0: number, t1: number, deptha: numbe
}
else // Both segments are fully subdivided; now do line segments
{
- var xlk = a[3].X - a[0].X;
- var ylk = a[3].Y - a[0].Y;
- var xnm = b[3].X - b[0].X;
- var ynm = b[3].Y - b[0].Y;
- var xmk = b[0].X - a[0].X;
- var ymk = b[0].Y - a[0].Y;
- var det = xnm * ylk - ynm * xlk;
- if (1.0 + det == 1.0) {
+ const xlk = a[3].X - a[0].X;
+ const ylk = a[3].Y - a[0].Y;
+ const xnm = b[3].X - b[0].X;
+ const ynm = b[3].Y - b[0].Y;
+ const xmk = b[0].X - a[0].X;
+ const ymk = b[0].Y - a[0].Y;
+ const det = xnm * ylk - ynm * xlk;
+ if (1.0 + det === 1.0) {
return;
}
else {
- var detinv = 1.0 / det;
- var s = (xnm * ymk - ynm * xmk) * detinv;
- var t = (xlk * ymk - ylk * xmk) * detinv;
+ const detinv = 1.0 / det;
+ const s = (xnm * ymk - ynm * xmk) * detinv;
+ const t = (xlk * ymk - ylk * xmk) * detinv;
if ((s < 0.0) || (s > 1.0) || (t < 0.0) || (t > 1.0) || Number.isNaN(s) || Number.isNaN(t)) {
return;
}
@@ -296,7 +287,7 @@ function EvalBezier(V: Point[], degree: number, t: number, result: number[]) {
return;
}
- var Vtemp = [new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)]; // Local copy of control points
+ const Vtemp = [new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)]; // Local copy of control points
/* Copy array */
for (var i = 0; i <= degree; i++) {
@@ -317,14 +308,11 @@ function EvalBezier(V: Point[], degree: number, t: number, result: number[]) {
}
function EvalBezierFast(p: Point[], t: number, result: number[]) {
- var n = 3;
- var u: number, bc: number, tn: number, tmpX: number, tmpY: number;
- u = 1.0 - t;
- bc = 1;
- tn = 1;
-
- tmpX = p[0].X * u;
- tmpY = p[0].Y * u;
+ const n = 3;
+ const u = 1.0 - t;
+ var bc = 1, tn = 1;
+ var tmpX = p[0].X * u;
+ var tmpY = p[0].Y * u;
tn = tn * t;
bc = bc * (n - 1 + 1) / 1;
tmpX = (tmpX + tn * bc * p[1].X) * u;
@@ -342,22 +330,21 @@ function EvalBezierFast(p: Point[], t: number, result: number[]) {
*Approximate unit tangents at endpoints and "center" of digitized curve
*/
function ComputeLeftTangent(d: Point[], end: number) {
- var use = 1;
- var tHat1 = new Point(d[end + use].X - d[end].X, d[end + use].Y - d[end].Y);
+ const use = 1;
+ const tHat1 = new Point(d[end + use].X - d[end].X, d[end + use].Y - d[end].Y);
return Normalize(tHat1);
}
function ComputeRightTangent(d: Point[], end: number) {
- var available = end;
- var use = 1;
- var tHat2 = new Point(d[end - use].X - d[end].X, d[end - use].Y - d[end].Y);
+ const use = 1;
+ const tHat2 = new Point(d[end - use].X - d[end].X, d[end - use].Y - d[end].Y);
return Normalize(tHat2);
}
function ComputeCenterTangent(d: Point[], center: number) {
- if (center == 0) {
+ if (center === 0) {
return ComputeLeftTangent(d, center);
}
- var V1 = ComputeLeftTangent(d, center); // d[center] - d[center-1];
- var V2 = ComputeRightTangent(d, center); // d[center] - d[center + 1];
+ const V1 = ComputeLeftTangent(d, center); // d[center] - d[center-1];
+ const V2 = ComputeRightTangent(d, center); // d[center] - d[center + 1];
var tHatCenter = new Point((-V1.X + V2.X) / 2.0, (-V1.Y + V2.Y) / 2.0);
if (tHatCenter === new Point(0, 0)) {
tHatCenter = new Point(-V1.Y, -V1.X);// V1.Perp();
@@ -365,15 +352,15 @@ function ComputeCenterTangent(d: Point[], center: number) {
return Normalize(tHatCenter);
}
function GenerateBezier(d: Point[], first: number, last: number, uPrime: number[], tHat1: Point, tHat2: Point, result: Point[] /* must be prealloacted to size 4 */) {
- var nPts = last - first + 1; // Number of pts in sub-curve
- var Ax = new Array<number>(nPts * 2);// Precomputed rhs for eqn //std::vector<Vector2D> A(nPts * 2);
- var Ay = new Array<number>(nPts * 2);// Precomputed rhs for eqn //std::vector<Vector2D> A(nPts * 2);
+ const nPts = last - first + 1; // Number of pts in sub-curve
+ const Ax = new Array<number>(nPts * 2);// Precomputed rhs for eqn //std::vector<Vector2D> A(nPts * 2);
+ const Ay = new Array<number>(nPts * 2);// Precomputed rhs for eqn //std::vector<Vector2D> A(nPts * 2);
/* Compute the A's */
for (var i = 0; i < nPts; i++) {
- var uprime = uPrime[i];
- var b1 = B1(uprime);
- var b2 = B2(uprime);
+ const uprime = uPrime[i];
+ const b1 = B1(uprime);
+ const b2 = B2(uprime);
Ax[i] = tHat1.X * b1;
Ay[i] = tHat1.Y * b1;
Ax[i + 1 * nPts] = tHat2.X * b2;
@@ -381,44 +368,41 @@ function GenerateBezier(d: Point[], first: number, last: number, uPrime: number[
}
/* Create the C and X matrices */
- var C = [[0, 0], [0, 0]];
- var df = d[first];
- var dl = d[last];
+ const C = [[0, 0], [0, 0]];
+ const df = d[first];
+ const dl = d[last];
- var X = [0, 0]; // Matrix X
+ const X = [0, 0]; // Matrix X
for (var i = 0; i < nPts; i++) {
C[0][0] += Ax[i] * Ax[i] + Ay[i] * Ay[i]; //A[i+0*nPts].Dot(A[i+0*nPts]);
C[0][1] += Ax[i] * Ax[i + nPts] + Ay[i] * Ay[i + nPts];//A[i+0*nPts].Dot(A[i+1*nPts]);
C[1][0] = C[0][1];
C[1][1] += Ax[i + nPts] * Ax[i + nPts] + Ay[i + nPts] * Ay[i + nPts];// A[i+1*nPts].Dot(A[i+1*nPts]);
- var uprime = uPrime[i];
- var b0plb1 = B0(uprime) + B1(uprime);
- var b2plb3 = B2(uprime) + B3(uprime);
- var df1 = d[first + i];
- var tmpX = df1.X - (df.X * b0plb1 + (dl.X * b2plb3));
- var tmpY = df1.Y - (df.Y * b0plb1 + (dl.Y * b2plb3));
+ const uprime = uPrime[i];
+ const b0plb1 = B0(uprime) + B1(uprime);
+ const b2plb3 = B2(uprime) + B3(uprime);
+ const df1 = d[first + i];
+ const tmpX = df1.X - (df.X * b0plb1 + (dl.X * b2plb3));
+ const tmpY = df1.Y - (df.Y * b0plb1 + (dl.Y * b2plb3));
X[0] += Ax[i] * tmpX + Ay[i] * tmpY; // A[i+0*nPts].Dot(tmp)
X[1] += Ax[i + nPts] * tmpX + Ay[i + nPts] * tmpY; //A[i+1*nPts].Dot(tmp)
}
/* Compute the determinants of C and X */
- var det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1];
- var det_C0_X = C[0][0] * X[1] - C[0][1] * X[0];
- var det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1];
+ const det_C0_C1 = (C[0][0] * C[1][1] - C[1][0] * C[0][1]) || (C[0][0] * C[1][1]) * 10e-12;
+ const det_C0_X = C[0][0] * X[1] - C[0][1] * X[0];
+ const det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1];
/* Finally, derive alpha values */
- if (det_C0_C1 == 0.0) {
- det_C0_C1 = (C[0][0] * C[1][1]) * 10e-12;
- }
- var alpha_l = (det_C0_C1 == 0) ? 0.0 : det_X_C1 / det_C0_C1;
- var alpha_r = (det_C0_C1 == 0) ? 0.0 : det_C0_X / det_C0_C1;
+ var alpha_l = (det_C0_C1 === 0) ? 0.0 : det_X_C1 / det_C0_C1;
+ var alpha_r = (det_C0_C1 === 0) ? 0.0 : det_C0_X / det_C0_C1;
/* If alpha negative, use the Wu/Barsky heuristic (see text) */
/* (if alpha is 0, you get coincident control points that lead to
* divide by zero in any subsequent NewtonRaphsonRootFind() call. */
- var segLength = Math.sqrt((df.X - dl.X) * (df.X - dl.X) + (df.Y - dl.Y) * (df.Y - dl.Y));
- var epsilon = 1.0e-6 * segLength;
+ const segLength = Math.sqrt((df.X - dl.X) * (df.X - dl.X) + (df.Y - dl.Y) * (df.Y - dl.Y));
+ const epsilon = 1.0e-6 * segLength;
if (alpha_l < epsilon || alpha_r < epsilon) {
/* fall back on standard (probably inaccurate) formula, and subdivide further if needed. */
alpha_l = alpha_r = segLength / 3.0;
@@ -432,15 +416,15 @@ function GenerateBezier(d: Point[], first: number, last: number, uPrime: number[
result[3] = dl;
result[1] = new Point(df.X + (tHat1.X * alpha_l), df.Y + (tHat1.Y * alpha_l));
result[2] = new Point(dl.X + (tHat2.X * alpha_r), dl.Y + (tHat2.Y * alpha_r));
-
}
+
/*
* NewtonRaphsonRootFind :
* Use Newton-Raphson iteration to find better root.
*/
function NewtonRaphsonRootFind(Q: Point[], P: Point, u: number) {
- var Q1 = [new Point(0, 0), new Point(0, 0), new Point(0, 0)], Q2 = [new Point(0, 0), new Point(0, 0)]; // Q' and Q''
- var Q_u = [0, 0], Q1_u = [0, 0], Q2_u = [0, 0]; //u evaluated at Q, Q', & Q''
+ const Q1 = [new Point(0, 0), new Point(0, 0), new Point(0, 0)], Q2 = [new Point(0, 0), new Point(0, 0)]; // Q' and Q''
+ const Q_u = [0, 0], Q1_u = [0, 0], Q2_u = [0, 0]; //u evaluated at Q, Q', & Q''
/* Compute Q(u) */
var uPrime: number; // Improved u
@@ -463,25 +447,24 @@ function NewtonRaphsonRootFind(Q: Point[], P: Point, u: number) {
EvalBezier(Q2, 1, u, Q2_u);
/* Compute f(u)/f'(u) */
- var numerator = (Q_u[0] - P.X) * (Q1_u[0]) + (Q_u[1] - P.Y) * (Q1_u[1]);
- var denominator = (Q1_u[0]) * (Q1_u[0]) + (Q1_u[1]) * (Q1_u[1]) + (Q_u[0] - P.X) * (Q2_u[0]) + (Q_u[1] - P.Y) * (Q2_u[1]);
- if (denominator == 0.0)
+ const numerator = (Q_u[0] - P.X) * (Q1_u[0]) + (Q_u[1] - P.Y) * (Q1_u[1]);
+ const denominator = (Q1_u[0]) * (Q1_u[0]) + (Q1_u[1]) * (Q1_u[1]) + (Q_u[0] - P.X) * (Q2_u[0]) + (Q_u[1] - P.Y) * (Q2_u[1]);
+ if (denominator === 0.0) {
uPrime = u;
- else uPrime = u - (numerator / denominator);/* u = u - f(u)/f'(u) */
+ } else uPrime = u - (numerator / denominator);/* u = u - f(u)/f'(u) */
return uPrime;
}
function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2: Point, error: number, result: Point[]) {
- var bezCurve = new Array<Point>(4); // Control points of fitted Bezier curve
- var splitPoint2D: number; // Point2D to split point set at
- var maxIterations = 4; // Max times to try iterating
+ const bezCurve = new Array<Point>(4); // Control points of fitted Bezier curve
+ const maxIterations = 4; // Max times to try iterating
- var iterationError = error * error; // Error below which you try iterating
- var nPts = last - first + 1; // Number of points in subset
+ const iterationError = error * error; // Error below which you try iterating
+ const nPts = last - first + 1; // Number of points in subset
/* Use heuristic if region only has two points in it */
- if (nPts == 2) {
- var dist = Math.sqrt((d[first].X - d[last].X) * (d[first].X - d[last].X) + (d[first].Y - d[last].Y) * (d[first].Y - d[last].Y)) / 3;
+ if (nPts === 2) {
+ const dist = Math.sqrt((d[first].X - d[last].X) * (d[first].X - d[last].X) + (d[first].Y - d[last].Y) * (d[first].Y - d[last].Y)) / 3;
bezCurve[0] = d[first];
bezCurve[3] = d[last];
@@ -499,7 +482,7 @@ function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2:
GenerateBezier(d, first, last, u, tHat1, tHat2, bezCurve);
/* Find max deviation of points to fitted curve */
- var { maxError, splitPoint2D } = ComputeMaxError(d, first, last, bezCurve, u); // Maximum fitting error
+ const { maxError, splitPoint2D } = ComputeMaxError(d, first, last, bezCurve, u); // Maximum fitting error
if (maxError < Math.abs(error)) {
result.push(bezCurve[1]);
result.push(bezCurve[2]);
@@ -511,9 +494,9 @@ function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2:
/* and iteration */
if (maxError < iterationError) {
for (var i = 0; i < maxIterations; i++) {
- var uPrime = ReparameterizeBezier(d, first, last, u, bezCurve); // Improved parameter values
+ const uPrime = ReparameterizeBezier(d, first, last, u, bezCurve); // Improved parameter values
GenerateBezier(d, first, last, uPrime, tHat1, tHat2, bezCurve);
- var { maxError, splitPoint2D } = ComputeMaxError(d, first, last, bezCurve, uPrime);
+ const { maxError } = ComputeMaxError(d, first, last, bezCurve, uPrime);
if (maxError < error) {
result.push(bezCurve[1]);
result.push(bezCurve[2]);
@@ -525,16 +508,15 @@ function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2:
}
/* Fitting failed -- split at max error point and fit recursively */
- var tHatCenter = splitPoint2D >= last - 1 ? ComputeRightTangent(d, splitPoint2D) : ComputeCenterTangent(d, splitPoint2D);
+ const tHatCenter = splitPoint2D >= last - 1 ? ComputeRightTangent(d, splitPoint2D) : ComputeCenterTangent(d, splitPoint2D);
FitCubic(d, first, splitPoint2D, tHat1, tHatCenter, error, result);
- var negThatCenter = new Point(-tHatCenter.X, -tHatCenter.Y);
+ const negThatCenter = new Point(-tHatCenter.X, -tHatCenter.Y);
FitCubic(d, splitPoint2D, last, negThatCenter, tHat2, error, result);
}
export function FitCurve(d: Point[], error: number) {
- var tHat1 = ComputeLeftTangent(d, 0); // Unit tangent vectors at endpoints
- var tHat2 = ComputeRightTangent(d, d.length - 1);
- var result: Point[] = [];
- result.push(d[0]);
+ const tHat1 = ComputeLeftTangent(d, 0); // Unit tangent vectors at endpoints
+ const tHat2 = ComputeRightTangent(d, d.length - 1);
+ const result = [d[0]];
FitCubic(d, 0, d.length - 1, tHat1, tHat2, error, result);
return result;
}
@@ -543,14 +525,14 @@ export function FitOneCurve(d: Point[], tHat1?: Point, tHat2?: Point) {
tHat2 = tHat2 ?? Normalize(ComputeRightTangent(d, d.length - 1));
tHat2 = new Point(-tHat2.X, -tHat2.Y);
var u = ChordLengthParameterize(d, 0, d.length - 1);
- var bezCurveCtrls = [new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)];
+ const bezCurveCtrls = [new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)];
GenerateBezier(d, 0, d.length - 1, u, tHat1, tHat2, bezCurveCtrls); /* Find max deviation of points to fitted curve */
var finalCtrls = bezCurveCtrls.slice();
var { maxError: error } = ComputeMaxError(d, 0, d.length - 1, bezCurveCtrls, u);
for (var i = 0; i < 10; i++) {
- var uPrime = ReparameterizeBezier(d, 0, d.length - 1, u, bezCurveCtrls); // Improved parameter values
+ const uPrime = ReparameterizeBezier(d, 0, d.length - 1, u, bezCurveCtrls); // Improved parameter values
GenerateBezier(d, 0, d.length - 1, uPrime, tHat1, tHat2, bezCurveCtrls);
- var { maxError } = ComputeMaxError(d, 0, d.length - 1, bezCurveCtrls, uPrime);
+ const { maxError } = ComputeMaxError(d, 0, d.length - 1, bezCurveCtrls, uPrime);
if (maxError < error) {
error = maxError;
finalCtrls = bezCurveCtrls.slice();