aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/bezierFit.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util/bezierFit.ts')
-rw-r--r--src/client/util/bezierFit.ts26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/client/util/bezierFit.ts b/src/client/util/bezierFit.ts
index bb3b6b1eb..fbc2bb7cd 100644
--- a/src/client/util/bezierFit.ts
+++ b/src/client/util/bezierFit.ts
@@ -561,7 +561,7 @@ function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2:
* Convert polyline coordinates to a (multi) segment bezier curve
* @param d - polyline coordinates
* @param error - how much error to allow in fitting (measured in pixels)
- * @returns
+ * @returns
*/
export function FitCurve(d: Point[], error: number) {
const tHat1 = ComputeLeftTangent(d, 0); // Unit tangent vectors at endpoints
@@ -592,6 +592,30 @@ export function FitOneCurve(d: Point[], tHat1?: Point, tHat2?: Point) {
return { finalCtrls, error };
}
+// alpha determines how far away the tangents are, or the "tightness" of the bezier
+export function GenerateControlPoints(coordinates: Point[], alpha = 0.1) {
+ const firstEnd = coordinates.length ? [coordinates[0], coordinates[0]] : [];
+ const lastEnd = coordinates.length ? [coordinates.lastElement(), coordinates.lastElement()] : [];
+ const points: Point[] = coordinates.slice(1, coordinates.length - 1).flatMap((pt, index, inkData) => {
+ const prevPt: Point = index === 0 ? firstEnd[0] : inkData[index - 1];
+ const nextPt: Point = index === inkData.length - 1 ? lastEnd[0] : inkData[index + 1];
+ if (prevPt.X === nextPt.X) {
+ const verticalDist = nextPt.Y - prevPt.Y;
+ return [{ X: pt.X, Y: pt.Y - alpha * verticalDist }, pt, pt, { X: pt.X, Y: pt.Y + alpha * verticalDist }];
+ } else if (prevPt.Y === nextPt.Y) {
+ const horizDist = nextPt.X - prevPt.X;
+ return [{ X: pt.X - alpha * horizDist, Y: pt.Y }, pt, pt, { X: pt.X + alpha * horizDist, Y: pt.Y }];
+ }
+ // tangent vectors between the adjacent points
+ const tanX = nextPt.X - prevPt.X;
+ const tanY = nextPt.Y - prevPt.Y;
+ const ctrlPt1: Point = { X: pt.X - alpha * tanX, Y: pt.Y - alpha * tanY };
+ const ctrlPt2: Point = { X: pt.X + alpha * tanX, Y: pt.Y + alpha * tanY };
+ return [ctrlPt1, pt, pt, ctrlPt2];
+ });
+ return [...firstEnd, ...points, ...lastEnd];
+}
+
/*
static double GetTValueFromSValue (const BezierRep &parent, double t, double endT, bool left, double influenceDistance, double &excess) {
double dist = 0;