fix(core): clockwise-positive bend angle for IP4 (right turn when travelling IP1→IP2)

Sign convention approved: a right (clockwise) deflection is positive.
solveIp4 now rotates the IP1→IP2 direction by −θ. Test covers a +10°
right turn with IP4 at (5, 0).

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-22 09:13:54 +09:00
1 parent d0fa9b94eb
commit d8944e9023
2 files changed
+9 -10

No files matched your search

+2 -2
View File
@@ -138,7 +138,7 @@ export interface PierModel {
/**
* Bend point IP4 (spec §4.1-2): the point where the IP1→IP2 line meets the line through IP3 whose
* direction is IP1→IP2 turned by the bend angle. Positive angle = counter-clockwise [확인 필요: 부호 규약].
* direction is IP1→IP2 turned by the bend angle. Positive angle = right (clockwise) turn when travelling IP1→IP2.
* Returns null for a zero angle, where IP4 is not defined.
*/
export function solveIp4(ip1: Vec2, ip2: Vec2, ip3: Vec2, angleDeg: number): Vec2 | null {
@@ -146,7 +146,7 @@ export function solveIp4(ip1: Vec2, ip2: Vec2, ip3: Vec2, angleDeg: number): Vec
const cross = (a: Vec2, b: Vec2) => a.e * b.n - a.n * b.e;
const len = Math.hypot(ip2.e - ip1.e, ip2.n - ip1.n);
const d1: Vec2 = { e: (ip2.e - ip1.e) / len, n: (ip2.n - ip1.n) / len };
const rad = (angleDeg * Math.PI) / 180;
const rad = (-angleDeg * Math.PI) / 180; // clockwise is positive, so the counter-clockwise rotation uses −θ
const d2: Vec2 = { e: d1.e * Math.cos(rad) - d1.n * Math.sin(rad), n: d1.e * Math.sin(rad) + d1.n * Math.cos(rad) };
const t = cross({ e: ip3.e - ip1.e, n: ip3.n - ip1.n }, d2) / cross(d1, d2);
return { e: ip1.e + t * d1.e, n: ip1.n + t * d1.n };