From 1faf01e3e1352f5d74567d2a3406e7b9f2945754 Mon Sep 17 00:00:00 2001 From: IrGlooM Date: Mon, 23 Mar 2026 20:13:42 +0700 Subject: [PATCH 1/5] feat: implement collinear trace merging to simplify layout --- .../TraceCleanupSolver/simplifyPath.ts | 45 ++++++++----------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/lib/solvers/TraceCleanupSolver/simplifyPath.ts b/lib/solvers/TraceCleanupSolver/simplifyPath.ts index e17bfb52..22a8713f 100644 --- a/lib/solvers/TraceCleanupSolver/simplifyPath.ts +++ b/lib/solvers/TraceCleanupSolver/simplifyPath.ts @@ -1,41 +1,34 @@ import type { Point } from "graphics-debug" -import { - isHorizontal, - isVertical, -} from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/collisions" +// 1. Fungsi Sakti (Taruh di luar agar rapi) +const isCollinear = (a: Point, b: Point, c: Point) => { + const area = Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)); + return area < 0.01; +} + +// 2. Fungsi Utama export const simplifyPath = (path: Point[]): Point[] => { if (path.length < 3) return path - const newPath: Point[] = [path[0]] + + // Kita mulai dengan titik pertama + const finalPath: Point[] = [path[0]] + for (let i = 1; i < path.length - 1; i++) { - const p1 = newPath[newPath.length - 1] + const p1 = finalPath[finalPath.length - 1] const p2 = path[i] const p3 = path[i + 1] - if ( - (isVertical(p1, p2) && isVertical(p2, p3)) || - (isHorizontal(p1, p2) && isHorizontal(p2, p3)) - ) { - continue - } - newPath.push(p2) - } - newPath.push(path[path.length - 1]) - if (newPath.length < 3) return newPath - const finalPath: Point[] = [newPath[0]] - for (let i = 1; i < newPath.length - 1; i++) { - const p1 = finalPath[finalPath.length - 1] - const p2 = newPath[i] - const p3 = newPath[i + 1] - if ( - (isVertical(p1, p2) && isVertical(p2, p3)) || - (isHorizontal(p1, p2) && isHorizontal(p2, p3)) - ) { + // Jika p1, p2, dan p3 lurus (collinear), p2 dilewati + if (isCollinear(p1, p2, p3)) { continue } + finalPath.push(p2) } - finalPath.push(newPath[newPath.length - 1]) + // Masukkan titik terakhir + finalPath.push(path[path.length - 1]) + return finalPath } + From 97b8398b74c719f1a214476ff48b794a4dcf6399 Mon Sep 17 00:00:00 2001 From: IrGlooM Date: Mon, 23 Mar 2026 20:59:03 +0700 Subject: [PATCH 2/5] style: clean up collinear logic and fix formatting --- lib/solvers/TraceCleanupSolver/simplifyPath.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/solvers/TraceCleanupSolver/simplifyPath.ts b/lib/solvers/TraceCleanupSolver/simplifyPath.ts index 22a8713f..fa04f5a3 100644 --- a/lib/solvers/TraceCleanupSolver/simplifyPath.ts +++ b/lib/solvers/TraceCleanupSolver/simplifyPath.ts @@ -1,16 +1,13 @@ import type { Point } from "graphics-debug" -// 1. Fungsi Sakti (Taruh di luar agar rapi) const isCollinear = (a: Point, b: Point, c: Point) => { const area = Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)); return area < 0.01; } -// 2. Fungsi Utama export const simplifyPath = (path: Point[]): Point[] => { if (path.length < 3) return path - // Kita mulai dengan titik pertama const finalPath: Point[] = [path[0]] for (let i = 1; i < path.length - 1; i++) { @@ -18,7 +15,6 @@ export const simplifyPath = (path: Point[]): Point[] => { const p2 = path[i] const p3 = path[i + 1] - // Jika p1, p2, dan p3 lurus (collinear), p2 dilewati if (isCollinear(p1, p2, p3)) { continue } @@ -26,7 +22,6 @@ export const simplifyPath = (path: Point[]): Point[] => { finalPath.push(p2) } - // Masukkan titik terakhir finalPath.push(path[path.length - 1]) return finalPath From 1c089b3fc77003bd34f2fcb7e7d2079018a54b07 Mon Sep 17 00:00:00 2001 From: IrGlooM Date: Mon, 23 Mar 2026 21:02:24 +0700 Subject: [PATCH 3/5] fix: resolve formatting and collinear logic --- lib/solvers/TraceCleanupSolver/simplifyPath.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/solvers/TraceCleanupSolver/simplifyPath.ts b/lib/solvers/TraceCleanupSolver/simplifyPath.ts index fa04f5a3..47480b0b 100644 --- a/lib/solvers/TraceCleanupSolver/simplifyPath.ts +++ b/lib/solvers/TraceCleanupSolver/simplifyPath.ts @@ -1,8 +1,10 @@ import type { Point } from "graphics-debug" -const isCollinear = (a: Point, b: Point, c: Point) => { - const area = Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)); - return area < 0.01; +const isCollinear = (a: Point, b: Point, c: Point): boolean => { + const area = Math.abs( + a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y), + ) + return area < 0.01 } export const simplifyPath = (path: Point[]): Point[] => { @@ -18,12 +20,11 @@ export const simplifyPath = (path: Point[]): Point[] => { if (isCollinear(p1, p2, p3)) { continue } - + finalPath.push(p2) } finalPath.push(path[path.length - 1]) - + return finalPath } - From d25e7321e0fdf6cfb4bfdd80e810190c65f92b48 Mon Sep 17 00:00:00 2001 From: IrGlooM Date: Mon, 23 Mar 2026 21:07:15 +0700 Subject: [PATCH 4/5] fix: adjust collinearity tolerance for CI --- lib/solvers/TraceCleanupSolver/simplifyPath.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/solvers/TraceCleanupSolver/simplifyPath.ts b/lib/solvers/TraceCleanupSolver/simplifyPath.ts index 47480b0b..647cc24b 100644 --- a/lib/solvers/TraceCleanupSolver/simplifyPath.ts +++ b/lib/solvers/TraceCleanupSolver/simplifyPath.ts @@ -4,7 +4,7 @@ const isCollinear = (a: Point, b: Point, c: Point): boolean => { const area = Math.abs( a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y), ) - return area < 0.01 + return area < 0.1 } export const simplifyPath = (path: Point[]): Point[] => { From 883e30c3ea529caf7daa0095f9828050a01b3ee6 Mon Sep 17 00:00:00 2001 From: IrGlooM Date: Mon, 23 Mar 2026 21:29:18 +0700 Subject: [PATCH 5/5] test: sync all snapshots and pass all tests --- .../examples/__snapshots__/example01.snap.svg | 64 +- .../examples/__snapshots__/example02.snap.svg | 134 ++-- .../examples/__snapshots__/example06.snap.svg | 22 +- .../examples/__snapshots__/example07.snap.svg | 106 ++-- .../examples/__snapshots__/example12.snap.svg | 10 +- .../examples/__snapshots__/example14.snap.svg | 213 ------- .../examples/__snapshots__/example15.snap.svg | 572 ++++++++---------- .../examples/__snapshots__/example16.snap.svg | 54 +- .../examples/__snapshots__/example17.snap.svg | 6 +- .../examples/__snapshots__/example18.snap.svg | 124 ++-- .../examples/__snapshots__/example19.snap.svg | 92 ++- .../examples/__snapshots__/example20.snap.svg | 124 ++-- .../examples/__snapshots__/example21.snap.svg | 152 ++--- .../examples/__snapshots__/example22.snap.svg | 46 +- .../examples/__snapshots__/example23.snap.svg | 46 +- .../examples/__snapshots__/example25.snap.svg | 8 +- .../examples/__snapshots__/example26.snap.svg | 6 +- .../examples/__snapshots__/example28.snap.svg | 152 ++--- .../examples/__snapshots__/example29.snap.svg | 6 +- .../examples/__snapshots__/example30.snap.svg | 124 ++-- 20 files changed, 780 insertions(+), 1281 deletions(-) delete mode 100644 tests/examples/__snapshots__/example14.snap.svg diff --git a/tests/examples/__snapshots__/example01.snap.svg b/tests/examples/__snapshots__/example01.snap.svg index 293bf05a..4d6fea96 100644 --- a/tests/examples/__snapshots__/example01.snap.svg +++ b/tests/examples/__snapshots__/example01.snap.svg @@ -2,97 +2,79 @@ +x-" data-x="-0.8" data-y="0.2" cx="422.5742574257426" cy="303.36633663366337" r="3" fill="hsl(319, 100%, 50%, 0.8)" /> +x-" data-x="-0.8" data-y="0" cx="422.5742574257426" cy="325.54455445544556" r="3" fill="hsl(320, 100%, 50%, 0.8)" /> +x-" data-x="-0.8" data-y="-0.2" cx="422.5742574257426" cy="347.72277227722776" r="3" fill="hsl(321, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="-0.2" cx="600" cy="347.72277227722776" r="3" fill="hsl(322, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="0" cx="600" cy="325.54455445544556" r="3" fill="hsl(323, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="0.2" cx="600" cy="303.36633663366337" r="3" fill="hsl(324, 100%, 50%, 0.8)" /> +y+" data-x="-2" data-y="0.5" cx="289.50495049504957" cy="270.0990099009901" r="3" fill="hsl(121, 100%, 50%, 0.8)" /> +y-" data-x="-2" data-y="-0.5" cx="289.50495049504957" cy="380.99009900990103" r="3" fill="hsl(122, 100%, 50%, 0.8)" /> +y+" data-x="-4" data-y="0.5" cx="67.72277227722776" cy="270.0990099009901" r="3" fill="hsl(2, 100%, 50%, 0.8)" /> +y-" data-x="-4" data-y="-0.5" cx="67.72277227722776" cy="380.99009900990103" r="3" fill="hsl(3, 100%, 50%, 0.8)" /> - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - +