From 0b4a3bca7bdf50b8463a6edc4e2572f340fc82f0 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 16 Jan 2023 14:06:36 +0100 Subject: [PATCH 1/7] intersection done --- src/intersection.class.ts | 52 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/intersection.class.ts b/src/intersection.class.ts index ab7e5249d82..a68fed1dcbb 100644 --- a/src/intersection.class.ts +++ b/src/intersection.class.ts @@ -1,4 +1,3 @@ -//@ts-nocheck import { Point } from './point.class'; /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ @@ -22,21 +21,20 @@ const isContainedInInterval = (T: Point, A: Point, B: Point) => { }; export class Intersection { - declare points: Point[]; + points: Point[] = []; declare status?: IntersectionType; constructor(status?: IntersectionType) { this.status = status; - this.points = []; } /** - * + * Used to verify if a point is alredy in the collection * @param {Point} point * @returns */ - contains(point) { + private includes(point: Point) { return this.points.some((p) => p.eq(point)); } @@ -46,10 +44,10 @@ export class Intersection { * @return {Intersection} thisArg * @chainable */ - private append(...points) { + private append(...points: Point[]) { this.points = this.points.concat( points.filter((point) => { - return !this.contains(point); + return !this.includes(point); }) ); return this; @@ -66,7 +64,7 @@ export class Intersection { * @param {boolean} [bInfinite=true] check segment intersection by passing `false` * @return {Intersection} */ - static intersectLineLine(a1, a2, b1, b2, aInfinite = true, bInfinite = true) { + static intersectLineLine(a1: Point, a2: Point, b1: Point, b2: Point, aInfinite = true, bInfinite = true) { let result; const uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x), ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x), @@ -78,12 +76,12 @@ export class Intersection { (aInfinite || (0 <= ua && ua <= 1)) && (bInfinite || (0 <= ub && ub <= 1)) ) { - result = new Intersection('Intersection'); + result = new this('Intersection'); result.append( new Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)) ); } else { - result = new Intersection(); + result = new this(); } } else { if (uaT === 0 || ubT === 0) { @@ -94,9 +92,9 @@ export class Intersection { isContainedInInterval(a2, b1, b2) || isContainedInInterval(b1, a1, a2) || isContainedInInterval(b2, a1, a2); - result = new Intersection(segmentsCoincide ? 'Coincident' : undefined); + result = new this(segmentsCoincide ? 'Coincident' : undefined); } else { - result = new Intersection('Parallel'); + result = new this('Parallel'); } } return result; @@ -112,8 +110,8 @@ export class Intersection { * @param {Point} l2 other point on line * @return {Intersection} */ - static intersectSegmentLine(s1, s2, l1, l2) { - return Intersection.intersectLineLine(s1, s2, l1, l2, false, true); + static intersectSegmentLine(s1: Point, s2: Point, l1: Point, l2: Point) { + return this.intersectLineLine(s1, s2, l1, l2, false, true); } /** @@ -126,8 +124,8 @@ export class Intersection { * @param {Point} b2 other boundary point of segment * @return {Intersection} */ - static intersectSegmentSegment(a1, a2, b1, b2) { - return Intersection.intersectLineLine(a1, a2, b1, b2, false, false); + static intersectSegmentSegment(a1: Point, a2: Point, b1: Point, b2: Point) { + return this.intersectLineLine(a1, a2, b1, b2, false, false); } /** @@ -143,14 +141,14 @@ export class Intersection { * @param {boolean} [infinite=true] check segment intersection by passing `false` * @return {Intersection} */ - static intersectLinePolygon(a1, a2, points, infinite = true) { - const result = new Intersection(); + static intersectLinePolygon(a1: Point, a2: Point, points: Point[], infinite = true) { + const result = new this(); const length = points.length; for (let i = 0, b1, b2, inter; i < length; i++) { b1 = points[i]; b2 = points[(i + 1) % length]; - inter = Intersection.intersectLineLine(a1, a2, b1, b2, infinite, false); + inter = this.intersectLineLine(a1, a2, b1, b2, infinite, false); if (inter.status === 'Coincident') { return inter; } @@ -173,8 +171,8 @@ export class Intersection { * @param {Point[]} points polygon points * @return {Intersection} */ - static intersectSegmentPolygon(a1, a2, points) { - return Intersection.intersectLinePolygon(a1, a2, points, false); + static intersectSegmentPolygon(a1: Point, a2: Point, points: Point[]) { + return this.intersectLinePolygon(a1, a2, points, false); } /** @@ -187,15 +185,15 @@ export class Intersection { * @param {Point[]} points2 * @return {Intersection} */ - static intersectPolygonPolygon(points1, points2) { - const result = new Intersection(), + static intersectPolygonPolygon(points1: Point[], points2: Point[]) { + const result = new this(), length = points1.length; const coincidences = []; for (let i = 0; i < length; i++) { const a1 = points1[i], a2 = points1[(i + 1) % length], - inter = Intersection.intersectSegmentPolygon(a1, a2, points2); + inter = this.intersectSegmentPolygon(a1, a2, points2); if (inter.status === 'Coincident') { coincidences.push(inter); result.append(a1, a2); @@ -205,7 +203,7 @@ export class Intersection { } if (coincidences.length > 0 && coincidences.length === points1.length) { - return new Intersection('Coincident'); + return new this('Coincident'); } else if (result.points.length > 0) { result.status = 'Intersection'; } @@ -222,13 +220,13 @@ export class Intersection { * @param {Point} r2 bottom right point of rect * @return {Intersection} */ - static intersectPolygonRectangle(points, r1, r2) { + static intersectPolygonRectangle(points: Point[], r1: Point, r2: Point) { const min = r1.min(r2), max = r1.max(r2), topRight = new Point(max.x, min.y), bottomLeft = new Point(min.x, max.y); - return Intersection.intersectPolygonPolygon(points, [ + return this.intersectPolygonPolygon(points, [ min, topRight, max, From 5b0dd0b05b28c08e76745a0f385870e074266223 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 16 Jan 2023 14:13:05 +0100 Subject: [PATCH 2/7] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 033098f5ca6..4e1dc4c7425 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [next] +- chore(TS): Intersection class, finalize TS [#8603](https://github.com/fabricjs/fabric.js/pull/8603) - chore(TS): Followup for interactivy and controls migration to TS [#8404](https://github.com/fabricjs/fabric.js/pull/8404) - refactor(IText): Fixes Draggable Text for retina and viewport transform #8534 - chore(TS): refactor canvas init, fix `_initRetinaScaling` regression #8520 From 452793a77ec0beccab25edc3af7ab740897d4f44 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 16 Jan 2023 14:16:26 +0100 Subject: [PATCH 3/7] use class name that gets minified --- src/intersection.class.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/intersection.class.ts b/src/intersection.class.ts index a68fed1dcbb..13a45cc23db 100644 --- a/src/intersection.class.ts +++ b/src/intersection.class.ts @@ -76,12 +76,12 @@ export class Intersection { (aInfinite || (0 <= ua && ua <= 1)) && (bInfinite || (0 <= ub && ub <= 1)) ) { - result = new this('Intersection'); + result = new Intersection('Intersection'); result.append( new Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)) ); } else { - result = new this(); + result = new Intersection(); } } else { if (uaT === 0 || ubT === 0) { @@ -92,9 +92,9 @@ export class Intersection { isContainedInInterval(a2, b1, b2) || isContainedInInterval(b1, a1, a2) || isContainedInInterval(b2, a1, a2); - result = new this(segmentsCoincide ? 'Coincident' : undefined); + result = new Intersection(segmentsCoincide ? 'Coincident' : undefined); } else { - result = new this('Parallel'); + result = new Intersection('Parallel'); } } return result; @@ -111,7 +111,7 @@ export class Intersection { * @return {Intersection} */ static intersectSegmentLine(s1: Point, s2: Point, l1: Point, l2: Point) { - return this.intersectLineLine(s1, s2, l1, l2, false, true); + return Intersection.intersectLineLine(s1, s2, l1, l2, false, true); } /** @@ -125,7 +125,7 @@ export class Intersection { * @return {Intersection} */ static intersectSegmentSegment(a1: Point, a2: Point, b1: Point, b2: Point) { - return this.intersectLineLine(a1, a2, b1, b2, false, false); + return Intersection.intersectLineLine(a1, a2, b1, b2, false, false); } /** @@ -142,13 +142,13 @@ export class Intersection { * @return {Intersection} */ static intersectLinePolygon(a1: Point, a2: Point, points: Point[], infinite = true) { - const result = new this(); + const result = new Intersection(); const length = points.length; for (let i = 0, b1, b2, inter; i < length; i++) { b1 = points[i]; b2 = points[(i + 1) % length]; - inter = this.intersectLineLine(a1, a2, b1, b2, infinite, false); + inter = Intersection.intersectLineLine(a1, a2, b1, b2, infinite, false); if (inter.status === 'Coincident') { return inter; } @@ -172,7 +172,7 @@ export class Intersection { * @return {Intersection} */ static intersectSegmentPolygon(a1: Point, a2: Point, points: Point[]) { - return this.intersectLinePolygon(a1, a2, points, false); + return Intersection.intersectLinePolygon(a1, a2, points, false); } /** @@ -186,14 +186,14 @@ export class Intersection { * @return {Intersection} */ static intersectPolygonPolygon(points1: Point[], points2: Point[]) { - const result = new this(), + const result = new Intersection(), length = points1.length; const coincidences = []; for (let i = 0; i < length; i++) { const a1 = points1[i], a2 = points1[(i + 1) % length], - inter = this.intersectSegmentPolygon(a1, a2, points2); + inter = Intersection.intersectSegmentPolygon(a1, a2, points2); if (inter.status === 'Coincident') { coincidences.push(inter); result.append(a1, a2); @@ -203,7 +203,7 @@ export class Intersection { } if (coincidences.length > 0 && coincidences.length === points1.length) { - return new this('Coincident'); + return new Intersection('Coincident'); } else if (result.points.length > 0) { result.status = 'Intersection'; } @@ -226,7 +226,7 @@ export class Intersection { topRight = new Point(max.x, min.y), bottomLeft = new Point(min.x, max.y); - return this.intersectPolygonPolygon(points, [ + return Intersection.intersectPolygonPolygon(points, [ min, topRight, max, From 16cb5d8d64f007986a3a2a8cedc985211c4819c9 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 16 Jan 2023 14:25:31 +0100 Subject: [PATCH 4/7] factor out reused variables --- src/intersection.class.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/intersection.class.ts b/src/intersection.class.ts index 13a45cc23db..f5bcff2bc85 100644 --- a/src/intersection.class.ts +++ b/src/intersection.class.ts @@ -1,3 +1,4 @@ +import { result } from 'lodash'; import { Point } from './point.class'; /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ @@ -21,20 +22,21 @@ const isContainedInInterval = (T: Point, A: Point, B: Point) => { }; export class Intersection { - points: Point[] = []; + declare points: Point[]; declare status?: IntersectionType; constructor(status?: IntersectionType) { this.status = status; + this.points = []; } /** * Used to verify if a point is alredy in the collection * @param {Point} point - * @returns + * @returns {boolean} */ - private includes(point: Point) { + private includes(point: Point): boolean { return this.points.some((p) => p.eq(point)); } @@ -44,7 +46,7 @@ export class Intersection { * @return {Intersection} thisArg * @chainable */ - private append(...points: Point[]) { + private append(...points: Point[]): Intersection { this.points = this.points.concat( points.filter((point) => { return !this.includes(point); @@ -64,11 +66,12 @@ export class Intersection { * @param {boolean} [bInfinite=true] check segment intersection by passing `false` * @return {Intersection} */ - static intersectLineLine(a1: Point, a2: Point, b1: Point, b2: Point, aInfinite = true, bInfinite = true) { - let result; - const uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x), - ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x), - uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y); + static intersectLineLine(a1: Point, a2: Point, b1: Point, b2: Point, aInfinite = true, bInfinite = true): Intersection { + const b2xb1x = b2.x - b1.x, a1yb1y = a1.y - b1.y, b2yb1y = b2.y - b1.y, + a1xb1x = a1.x - b1.x, a2ya1y = a2.y - a1.y, a2xa1x = a2.x - a1.x, + uaT = b2xb1x * a1yb1y - b2yb1y * a1xb1x, + ubT = a2xa1x * a1yb1y - a2ya1y * a1xb1x, + uB = b2yb1y * a2xa1x - b2xb1x * a2ya1y; if (uB !== 0) { const ua = uaT / uB, ub = ubT / uB; @@ -76,12 +79,13 @@ export class Intersection { (aInfinite || (0 <= ua && ua <= 1)) && (bInfinite || (0 <= ub && ub <= 1)) ) { - result = new Intersection('Intersection'); + const result = new Intersection('Intersection'); result.append( - new Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)) + new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y) ); + return result; } else { - result = new Intersection(); + return new Intersection(); } } else { if (uaT === 0 || ubT === 0) { @@ -92,12 +96,11 @@ export class Intersection { isContainedInInterval(a2, b1, b2) || isContainedInInterval(b1, a1, a2) || isContainedInInterval(b2, a1, a2); - result = new Intersection(segmentsCoincide ? 'Coincident' : undefined); + return new Intersection(segmentsCoincide ? 'Coincident' : undefined); } else { - result = new Intersection('Parallel'); + return new Intersection('Parallel'); } } - return result; } /** From 6067561262d44f83208f5b89b40b3237cd2867a6 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 16 Jan 2023 14:28:02 +0100 Subject: [PATCH 5/7] more types --- src/intersection.class.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/intersection.class.ts b/src/intersection.class.ts index f5bcff2bc85..d02ebf2d55f 100644 --- a/src/intersection.class.ts +++ b/src/intersection.class.ts @@ -113,7 +113,7 @@ export class Intersection { * @param {Point} l2 other point on line * @return {Intersection} */ - static intersectSegmentLine(s1: Point, s2: Point, l1: Point, l2: Point) { + static intersectSegmentLine(s1: Point, s2: Point, l1: Point, l2: Point): Intersection { return Intersection.intersectLineLine(s1, s2, l1, l2, false, true); } @@ -127,7 +127,7 @@ export class Intersection { * @param {Point} b2 other boundary point of segment * @return {Intersection} */ - static intersectSegmentSegment(a1: Point, a2: Point, b1: Point, b2: Point) { + static intersectSegmentSegment(a1: Point, a2: Point, b1: Point, b2: Point): Intersection { return Intersection.intersectLineLine(a1, a2, b1, b2, false, false); } @@ -144,7 +144,7 @@ export class Intersection { * @param {boolean} [infinite=true] check segment intersection by passing `false` * @return {Intersection} */ - static intersectLinePolygon(a1: Point, a2: Point, points: Point[], infinite = true) { + static intersectLinePolygon(a1: Point, a2: Point, points: Point[], infinite = true): Intersection { const result = new Intersection(); const length = points.length; @@ -174,7 +174,7 @@ export class Intersection { * @param {Point[]} points polygon points * @return {Intersection} */ - static intersectSegmentPolygon(a1: Point, a2: Point, points: Point[]) { + static intersectSegmentPolygon(a1: Point, a2: Point, points: Point[]): Intersection { return Intersection.intersectLinePolygon(a1, a2, points, false); } @@ -188,7 +188,7 @@ export class Intersection { * @param {Point[]} points2 * @return {Intersection} */ - static intersectPolygonPolygon(points1: Point[], points2: Point[]) { + static intersectPolygonPolygon(points1: Point[], points2: Point[]): Intersection { const result = new Intersection(), length = points1.length; const coincidences = []; @@ -223,7 +223,7 @@ export class Intersection { * @param {Point} r2 bottom right point of rect * @return {Intersection} */ - static intersectPolygonRectangle(points: Point[], r1: Point, r2: Point) { + static intersectPolygonRectangle(points: Point[], r1: Point, r2: Point): Intersection { const min = r1.min(r2), max = r1.max(r2), topRight = new Point(max.x, min.y), From 30ca709703695b8abbf3cbb0148aeaae910aff36 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 16 Jan 2023 14:33:12 +0100 Subject: [PATCH 6/7] prettier --- src/intersection.class.ts | 59 +++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/src/intersection.class.ts b/src/intersection.class.ts index d02ebf2d55f..ff3de3d0144 100644 --- a/src/intersection.class.ts +++ b/src/intersection.class.ts @@ -66,9 +66,20 @@ export class Intersection { * @param {boolean} [bInfinite=true] check segment intersection by passing `false` * @return {Intersection} */ - static intersectLineLine(a1: Point, a2: Point, b1: Point, b2: Point, aInfinite = true, bInfinite = true): Intersection { - const b2xb1x = b2.x - b1.x, a1yb1y = a1.y - b1.y, b2yb1y = b2.y - b1.y, - a1xb1x = a1.x - b1.x, a2ya1y = a2.y - a1.y, a2xa1x = a2.x - a1.x, + static intersectLineLine( + a1: Point, + a2: Point, + b1: Point, + b2: Point, + aInfinite = true, + bInfinite = true + ): Intersection { + const b2xb1x = b2.x - b1.x, + a1yb1y = a1.y - b1.y, + b2yb1y = b2.y - b1.y, + a1xb1x = a1.x - b1.x, + a2ya1y = a2.y - a1.y, + a2xa1x = a2.x - a1.x, uaT = b2xb1x * a1yb1y - b2yb1y * a1xb1x, ubT = a2xa1x * a1yb1y - a2ya1y * a1xb1x, uB = b2yb1y * a2xa1x - b2xb1x * a2ya1y; @@ -80,9 +91,7 @@ export class Intersection { (bInfinite || (0 <= ub && ub <= 1)) ) { const result = new Intersection('Intersection'); - result.append( - new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y) - ); + result.append(new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y)); return result; } else { return new Intersection(); @@ -113,7 +122,12 @@ export class Intersection { * @param {Point} l2 other point on line * @return {Intersection} */ - static intersectSegmentLine(s1: Point, s2: Point, l1: Point, l2: Point): Intersection { + static intersectSegmentLine( + s1: Point, + s2: Point, + l1: Point, + l2: Point + ): Intersection { return Intersection.intersectLineLine(s1, s2, l1, l2, false, true); } @@ -127,7 +141,12 @@ export class Intersection { * @param {Point} b2 other boundary point of segment * @return {Intersection} */ - static intersectSegmentSegment(a1: Point, a2: Point, b1: Point, b2: Point): Intersection { + static intersectSegmentSegment( + a1: Point, + a2: Point, + b1: Point, + b2: Point + ): Intersection { return Intersection.intersectLineLine(a1, a2, b1, b2, false, false); } @@ -144,7 +163,12 @@ export class Intersection { * @param {boolean} [infinite=true] check segment intersection by passing `false` * @return {Intersection} */ - static intersectLinePolygon(a1: Point, a2: Point, points: Point[], infinite = true): Intersection { + static intersectLinePolygon( + a1: Point, + a2: Point, + points: Point[], + infinite = true + ): Intersection { const result = new Intersection(); const length = points.length; @@ -174,7 +198,11 @@ export class Intersection { * @param {Point[]} points polygon points * @return {Intersection} */ - static intersectSegmentPolygon(a1: Point, a2: Point, points: Point[]): Intersection { + static intersectSegmentPolygon( + a1: Point, + a2: Point, + points: Point[] + ): Intersection { return Intersection.intersectLinePolygon(a1, a2, points, false); } @@ -188,7 +216,10 @@ export class Intersection { * @param {Point[]} points2 * @return {Intersection} */ - static intersectPolygonPolygon(points1: Point[], points2: Point[]): Intersection { + static intersectPolygonPolygon( + points1: Point[], + points2: Point[] + ): Intersection { const result = new Intersection(), length = points1.length; const coincidences = []; @@ -223,7 +254,11 @@ export class Intersection { * @param {Point} r2 bottom right point of rect * @return {Intersection} */ - static intersectPolygonRectangle(points: Point[], r1: Point, r2: Point): Intersection { + static intersectPolygonRectangle( + points: Point[], + r1: Point, + r2: Point + ): Intersection { const min = r1.min(r2), max = r1.max(r2), topRight = new Point(max.x, min.y), From 83cdd7ab15a129fa48aa3ca3813e5b1ee17424b4 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 16 Jan 2023 15:03:47 +0100 Subject: [PATCH 7/7] less --- src/intersection.class.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/intersection.class.ts b/src/intersection.class.ts index ff3de3d0144..b131e02806a 100644 --- a/src/intersection.class.ts +++ b/src/intersection.class.ts @@ -1,4 +1,3 @@ -import { result } from 'lodash'; import { Point } from './point.class'; /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ @@ -90,9 +89,9 @@ export class Intersection { (aInfinite || (0 <= ua && ua <= 1)) && (bInfinite || (0 <= ub && ub <= 1)) ) { - const result = new Intersection('Intersection'); - result.append(new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y)); - return result; + return new Intersection('Intersection').append( + new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y) + ); } else { return new Intersection(); }