From 125a34c5bf09e2dddfed5a5e884bad021f63dca2 Mon Sep 17 00:00:00 2001 From: yzrmn Date: Sat, 27 Jul 2024 15:43:54 +0200 Subject: [PATCH] Change point API --- .../redgeometry-app/src/parts/gpu-cube.ts | 2 +- .../src/utility/straight-skeleton.ts | 2 +- packages/redgeometry/src/core/path-offset.ts | 8 +-- packages/redgeometry/src/core/path.ts | 6 +- .../redgeometry/src/internal/path-offset.ts | 32 +++++----- .../redgeometry/src/internal/path-stroke.ts | 23 ++++---- packages/redgeometry/src/primitives/bezier.ts | 10 +++- packages/redgeometry/src/primitives/edge.ts | 14 +++-- packages/redgeometry/src/primitives/point.ts | 58 ++++++++++--------- .../redgeometry/src/primitives/polygon.ts | 4 +- packages/redgeometry/src/primitives/ray.ts | 10 ++-- 11 files changed, 93 insertions(+), 76 deletions(-) diff --git a/packages/redgeometry-app/src/parts/gpu-cube.ts b/packages/redgeometry-app/src/parts/gpu-cube.ts index 082a427..c957224 100644 --- a/packages/redgeometry-app/src/parts/gpu-cube.ts +++ b/packages/redgeometry-app/src/parts/gpu-cube.ts @@ -339,7 +339,7 @@ function cameraMoveSystem(world: World): void { v = v.unitOrZero().mul(delta * vel); v = camRot.mulVec(v); - camPos = camPos.add(v); + camPos = camPos.addVec(v); } transform.rotation = camRot; diff --git a/packages/redgeometry-app/src/utility/straight-skeleton.ts b/packages/redgeometry-app/src/utility/straight-skeleton.ts index c4de15b..00b3672 100644 --- a/packages/redgeometry-app/src/utility/straight-skeleton.ts +++ b/packages/redgeometry-app/src/utility/straight-skeleton.ts @@ -79,7 +79,7 @@ export class KineticVertex { } public getPositionAt(t: number): Point2 { - return this.orig.addMul(this.vel, t - this.t0); + return this.orig.addMulVec(this.vel, t - this.t0); } } diff --git a/packages/redgeometry/src/core/path-offset.ts b/packages/redgeometry/src/core/path-offset.ts index 3e32c76..4c96b7b 100644 --- a/packages/redgeometry/src/core/path-offset.ts +++ b/packages/redgeometry/src/core/path-offset.ts @@ -248,13 +248,13 @@ export class PathOffsetIncremental2 implements PathOffset2 { private offsetLinear(p1: Point2, m: Vector2): void { const v = m.unit().normal().mul(this.d); - this.buffer.lineTo(p1.add(v)); + this.buffer.lineTo(p1.addVec(v)); } private offsetMove(p0: Point2, m: Vector2): void { const v = m.unit().normal().mul(this.d); - this.buffer.moveTo(p0.add(v)); + this.buffer.moveTo(p0.addVec(v)); } private offsetQuadratic(c0: Bezier2Curve2): void { @@ -538,13 +538,13 @@ export class PathOffsetRecursive2 implements PathOffset2 { private offsetLinear(p1: Point2, m: Vector2): void { const v = m.unit().normal().mul(this.d); - this.buffer.lineTo(p1.add(v)); + this.buffer.lineTo(p1.addVec(v)); } private offsetMove(p0: Point2, m: Vector2): void { const v = m.unit().normal().mul(this.d); - this.buffer.moveTo(p0.add(v)); + this.buffer.moveTo(p0.addVec(v)); } private offsetQuadratic(c0: Bezier2Curve2): void { diff --git a/packages/redgeometry/src/core/path.ts b/packages/redgeometry/src/core/path.ts index 23951df..509a49b 100644 --- a/packages/redgeometry/src/core/path.ts +++ b/packages/redgeometry/src/core/path.ts @@ -619,7 +619,7 @@ export class Path2 implements PathSink2 { // New vector from center (unit midpoint) v = pp1.sub(pp0).mul(0.5); - let pc = pp0.add(v); + let pc = pp0.addVec(v); // If `lenght^2 >= 1` the point is already the center const len2 = v.lenSq(); @@ -631,9 +631,9 @@ export class Path2 implements PathSink2 { v = v.normal().neg().mul(f); if (largeArc !== sweep) { - pc = pc.add(v); + pc = pc.addVec(v); } else { - pc = pc.add(v.neg()); + pc = pc.subVec(v); } } diff --git a/packages/redgeometry/src/internal/path-offset.ts b/packages/redgeometry/src/internal/path-offset.ts index 3eb6f94..c09e8fc 100644 --- a/packages/redgeometry/src/internal/path-offset.ts +++ b/packages/redgeometry/src/internal/path-offset.ts @@ -19,7 +19,7 @@ export function offsetQuadraticSimple(path: Path2, c: Bezier2Curve2, d: number): v1 = v1.mul(2 * d).div(v1.lenSq()); v2 = v2.mul(d); - path.quadTo(c.p1.add(v1), c.p2.add(v2)); + path.quadTo(c.p1.addVec(v1), c.p2.addVec(v2)); } } @@ -70,7 +70,7 @@ export function insertOuterJoin( switch (join) { case JoinType.Bevel: { - path.lineTo(p.addMul(n1, d)); + path.lineTo(p.addMulVec(n1, d)); break; } @@ -80,10 +80,10 @@ export function insertOuterJoin( k = k.mul(2 * d).div(k.lenSq()); if (k.lenSq() <= mld * mld) { - path.lineTo(p.add(k)); + path.lineTo(p.addVec(k)); } - path.lineTo(p.addMul(n1, d)); + path.lineTo(p.addMulVec(n1, d)); break; } @@ -92,16 +92,16 @@ export function insertOuterJoin( k = k.mul(2 * d).div(k.lenSq()); - const pp0 = p.addMul(n0, d); - const pp2 = p.addMul(n1, d); + const pp0 = p.addMulVec(n0, d); + const pp2 = p.addMulVec(n1, d); if (k.lenSq() <= mld * mld) { // Same as miter join - path.lineTo(p.add(k)); + path.lineTo(p.addVec(k)); } else if (n0.dot(n1) <= COS_ACUTE) { // Join is too sharp ('k' is approaching infinity) - path.lineTo(pp0.addMul(n0.normal(), -mld)); - path.lineTo(pp2.addMul(n1.normal(), mld)); + path.lineTo(pp0.addMulVec(n0.normal(), -mld)); + path.lineTo(pp2.addMulVec(n1.normal(), mld)); } else { const kov = k.dot(p.sub(pp0)); const kok = k.dot(k); @@ -110,7 +110,7 @@ export function insertOuterJoin( // Fall back to bevel otherwise if (t > 0) { - const pp1 = p.add(k); + const pp1 = p.addVec(k); path.lineTo(pp0.lerp(pp1, t)); path.lineTo(pp2.lerp(pp1, t)); @@ -122,8 +122,8 @@ export function insertOuterJoin( break; } case JoinType.Round: { - const pp0 = p.addMul(n0, d); - const pp2 = p.addMul(n1, d); + const pp0 = p.addMulVec(n0, d); + const pp2 = p.addMulVec(n1, d); if (n0.dot(n1) < 0) { // Obtuse angle (2 segments) @@ -133,8 +133,8 @@ export function insertOuterJoin( k = k.mul(2 * d).div(k.lenSq()); - const pc1 = p.add(k); - const pp1 = p.addMul(nm, d); + const pc1 = p.addVec(k); + const pp1 = p.addMulVec(nm, d); const pc2 = pc1.lerp(pp1, 2); const w = BezierRCurve2.getWeightFromVectors(p, pc1, pp1); @@ -147,7 +147,7 @@ export function insertOuterJoin( k = k.mul(2 * d).div(k.lenSq()); - const pc = p.add(k); + const pc = p.addVec(k); const w = BezierRCurve2.getWeightFromVectors(p, pc, pp2); @@ -167,5 +167,5 @@ export function insertInnerJoin(path: Path2, p: Point2, n1: Vector2, d: number): path.lineTo(p); // Bevel join - path.lineTo(p.addMul(n1, d)); + path.lineTo(p.addMulVec(n1, d)); } diff --git a/packages/redgeometry/src/internal/path-stroke.ts b/packages/redgeometry/src/internal/path-stroke.ts index 7c54b2f..e9b9b41 100644 --- a/packages/redgeometry/src/internal/path-stroke.ts +++ b/packages/redgeometry/src/internal/path-stroke.ts @@ -295,15 +295,15 @@ export class StrokeState { private insertLinearStroke(p: Point2, m: Vector2): void { const v = m.unit().normal().mul(this.distance); - this.left.lineTo(p.add(v)); - this.right.lineTo(p.add(v.neg())); + this.left.lineTo(p.addVec(v)); + this.right.lineTo(p.subVec(v)); } private insertMoveStroke(p0: Point2, m: Vector2): void { const v = m.unit().normal().mul(this.distance); - this.left.moveTo(p0.add(v)); - this.right.moveTo(p0.add(v.neg())); + this.left.moveTo(p0.addVec(v)); + this.right.moveTo(p0.subVec(v)); } private insertQuadraticDegenerateDashStroke(p0: Point2, p1: Point2, p2: Point2): void { @@ -384,8 +384,8 @@ export class StrokeState { v1 = v1.mul(2 * d).div(v1.lenSq()); v2 = v2.mul(d); - this.left.quadTo(c.p1.add(v1), c.p2.add(v2)); - this.right.quadTo(c.p1.add(v1.neg()), c.p2.add(v2.neg())); + this.left.quadTo(c.p1.addVec(v1), c.p2.addVec(v2)); + this.right.quadTo(c.p1.subVec(v1), c.p2.subVec(v2)); } } @@ -456,8 +456,8 @@ export function insertStrokeCap(path: Path2, p1: Point2, cap: CapType | CustomCa } const v = p1.sub(p0).mul(0.5).normal(); - path.lineTo(p0.add(v)); - path.lineTo(p1.add(v)); + path.lineTo(p0.addVec(v)); + path.lineTo(p1.addVec(v)); path.lineTo(p1); break; @@ -469,9 +469,10 @@ export function insertStrokeCap(path: Path2, p1: Point2, cap: CapType | CustomCa break; } - const v = p1.sub(p0).mul(0.5).normal(); - path.arcTo(p0.add(v), p0.add(v.sub(v.normal()))); - path.arcTo(p1.add(v), p1); + const v0 = p1.sub(p0).mul(0.5).normal(); + const v1 = v0.sub(v0.normal()); + path.arcTo(p0.addVec(v0), p0.addVec(v1)); + path.arcTo(p1.addVec(v0), p1); break; } diff --git a/packages/redgeometry/src/primitives/bezier.ts b/packages/redgeometry/src/primitives/bezier.ts index fa9e283..7084b4f 100644 --- a/packages/redgeometry/src/primitives/bezier.ts +++ b/packages/redgeometry/src/primitives/bezier.ts @@ -348,7 +348,10 @@ export class Bezier2Curve2 { const pp = qa.mul(2 * t).add(qb); const ppp = qa.mul(2); - return p.addMul(pp.normal(), pp.lenSq() / pp.cross(ppp)); + const v = pp.normal(); + const f = pp.lenSq() / pp.cross(ppp); + + return p.addMulVec(v, f); } public getOffsetCuspParameter(rad: number): [number, number] { @@ -714,7 +717,10 @@ export class Bezier3Curve2 { .add(qc); const ppp = qa.mul(6 * t).addMul(qb, 2); - return p.addMul(pp.normal(), pp.lenSq() / pp.cross(ppp)); + const v = pp.normal(); + const f = pp.lenSq() / pp.cross(ppp); + + return p.addMulVec(v, f); } public getInflectionParameter(): [number, number] { diff --git a/packages/redgeometry/src/primitives/edge.ts b/packages/redgeometry/src/primitives/edge.ts index 3027e96..af888eb 100644 --- a/packages/redgeometry/src/primitives/edge.ts +++ b/packages/redgeometry/src/primitives/edge.ts @@ -346,7 +346,8 @@ export class Edge2 { public normal(): Edge2 { const vn = this.vector().normal(); - return new Edge2(this.p0, this.p0.add(vn)); + const p1 = this.p0.addVec(vn); + return new Edge2(this.p0, p1); } public reverse(): Edge2 { @@ -370,7 +371,9 @@ export class Edge2 { } public translate(v: Vector2): Edge2 { - return new Edge2(this.p0.add(v), this.p1.add(v)); + const p0 = this.p0.addVec(v); + const p1 = this.p1.addVec(v); + return new Edge2(p0, p1); } public vector(): Vector2 { @@ -465,7 +468,8 @@ export class Edge3 { public getNormalAround(v: Vector3): Edge3 { const vn = this.vector().cross(v); - return new Edge3(this.p0, this.p0.add(vn)); + const p1 = this.p0.addVec(vn); + return new Edge3(this.p0, p1); } /** @@ -515,7 +519,9 @@ export class Edge3 { } public translate(v: Vector3): Edge3 { - return new Edge3(this.p0.add(v), this.p1.add(v)); + const p0 = this.p0.addVec(v); + const p1 = this.p1.addVec(v); + return new Edge3(p0, p1); } public vector(): Vector3 { diff --git a/packages/redgeometry/src/primitives/point.ts b/packages/redgeometry/src/primitives/point.ts index 36ae82b..beef8a6 100644 --- a/packages/redgeometry/src/primitives/point.ts +++ b/packages/redgeometry/src/primitives/point.ts @@ -82,22 +82,22 @@ export class Point2 implements Point2Like { return { x: p.x, y: p.y }; } - /** - * Returns the sum of the current point and a vector `v`. - */ - public add(v: Vector2): Point2 { - return new Point2(this.x + v.x, this.y + v.y); - } - /** * Returns the sum of the current point and a vector `v` scaled by `f`. */ - public addMul(v: Vector2, f: number): Point2 { + public addMulVec(v: Vector2, f: number): Point2 { const x = this.x + f * v.x; const y = this.y + f * v.y; return new Point2(x, y); } + /** + * Returns the sum of the current point and a vector `v`. + */ + public addVec(v: Vector2): Point2 { + return new Point2(this.x + v.x, this.y + v.y); + } + public clone(): Point2 { return new Point2(this.x, this.y); } @@ -145,6 +145,13 @@ export class Point2 implements Point2Like { return new Vector2(this.x - p.x, this.y - p.y); } + /** + * Returns the difference of the current point and a vector `v`. + */ + public subVec(v: Vector2): Point2 { + return new Point2(this.x - v.x, this.y - v.y); + } + public toArray(): [number, number] { return [this.x, this.y]; } @@ -196,18 +203,6 @@ export class Point3 implements Point3Like { return new Point3(x / w, y / w, z / w); } - public static max(p1: Point3, p2: Point3): Point3 { - return new Point3(Math.max(p1.x, p2.x), Math.max(p1.y, p2.y), Math.max(p1.z, p2.z)); - } - - public static min(p1: Point3, p2: Point3): Point3 { - return new Point3(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.min(p1.z, p2.z)); - } - - public static round(p: Point3): Point3 { - return new Point3(Math.round(p.x), Math.round(p.y), Math.round(p.z)); - } - public static roundToPrecision(p: Point3, k: number): Point3 { // `k` denotes the reciprocal of the minimum interval that the rounded number is able to represent const x = roundToPrecision(p.x, k); @@ -220,23 +215,23 @@ export class Point3 implements Point3Like { return { x: p.x, y: p.y, z: p.z }; } - /** - * Returns the sum of the current point and a vector `v`. - */ - public add(v: Vector3): Point3 { - return new Point3(this.x + v.x, this.y + v.y, this.z + v.z); - } - /** * Returns the sum of the current point and a vector `v` scaled by `f`. */ - public addMul(v: Vector3, f: number): Point3 { + public addMulVec(v: Vector3, f: number): Point3 { const x = this.x + f * v.x; const y = this.y + f * v.y; const z = this.z + f * v.z; return new Point3(x, y, z); } + /** + * Returns the sum of the current point and a vector `v`. + */ + public addVec(v: Vector3): Point3 { + return new Point3(this.x + v.x, this.y + v.y, this.z + v.z); + } + public clone(): Point3 { return new Point3(this.x, this.y, this.z); } @@ -270,6 +265,13 @@ export class Point3 implements Point3Like { return new Vector3(this.x - v.x, this.y - v.y, this.z - v.z); } + /** + * Returns the difference of the current point and a vector `v`. + */ + public subVec(v: Vector3): Point3 { + return new Point3(this.x - v.x, this.y - v.y, this.z - v.z); + } + public toArray(): [number, number, number] { return [this.x, this.y, this.z]; } diff --git a/packages/redgeometry/src/primitives/polygon.ts b/packages/redgeometry/src/primitives/polygon.ts index 8870e2a..49595a4 100644 --- a/packages/redgeometry/src/primitives/polygon.ts +++ b/packages/redgeometry/src/primitives/polygon.ts @@ -240,8 +240,8 @@ export class Polygon2 { if (area < minArea) { // Update bounding box points[0] = p0; - points[1] = p0.add(v1); - points[2] = p1.add(v1); + points[1] = p0.addVec(v1); + points[2] = p1.addVec(v1); points[3] = p1; minArea = area; } diff --git a/packages/redgeometry/src/primitives/ray.ts b/packages/redgeometry/src/primitives/ray.ts index 979dd0e..46dc5c4 100644 --- a/packages/redgeometry/src/primitives/ray.ts +++ b/packages/redgeometry/src/primitives/ray.ts @@ -102,7 +102,7 @@ export class Ray2 { * Returns the parameterized point on the ray along its direction. */ public getValueAt(t: number): Point2 { - return this.p.addMul(this.v, t); + return this.p.addMulVec(this.v, t); } public normal(): Ray2 { @@ -122,7 +122,8 @@ export class Ray2 { } public translate(v: Vector2): Ray2 { - return new Ray2(this.p.add(v), this.v); + const p = this.p.addVec(v); + return new Ray2(p, this.v); } } @@ -195,7 +196,7 @@ export class Ray3 { * Returns the parameterized point on the ray along its direction. */ public getValueAt(t: number): Point3 { - return this.p.addMul(this.v, t); + return this.p.addMulVec(this.v, t); } public isFinite(): boolean { @@ -215,6 +216,7 @@ export class Ray3 { } public translate(v: Vector3): Ray3 { - return new Ray3(this.p.add(v), this.v); + const p = this.p.addVec(v); + return new Ray3(p, this.v); } }