task(CAD-4): otrack computeTrackPoint with angle projection, divide/measure path point tools on defpoints in one undo transaction
This commit is contained in:
@@ -494,3 +494,44 @@ export class SnapEngine {
|
||||
export function fromOffset(base: { x: number; y: number }, dx: number, dy: number): { x: number; y: number } {
|
||||
return { x: base.x + dx, y: base.y + dy };
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────
|
||||
// Task CAD-4: OTRACK — Objekt-Fang-Tracking. computeTrackPoint
|
||||
// projiziert den Cursor auf Tracking-Linien durch den Basispunkt
|
||||
// (Default 0/90/180/270°, optional erweiterte Winkel) und liefert
|
||||
// den nächstgelegenen Track-Punkt. Reine Funktion (UI-testbar).
|
||||
// ───────────────────────────────────────────────────
|
||||
|
||||
export function computeTrackPoint(
|
||||
base: { x: number; y: number },
|
||||
cursor: { x: number; y: number },
|
||||
angles?: number[],
|
||||
): { x: number; y: number } | null {
|
||||
const dx = cursor.x - base.x;
|
||||
const dy = cursor.y - base.y;
|
||||
if (dx === 0 && dy === 0) return null;
|
||||
const angs = angles ?? [0, 90, 180, 270];
|
||||
let best: { x: number; y: number } | null = null;
|
||||
let bestDist = Infinity;
|
||||
for (const a of angs) {
|
||||
const rad = (a * Math.PI) / 180;
|
||||
const dxc = Math.cos(rad);
|
||||
const dyc = Math.sin(rad);
|
||||
let pt: { x: number; y: number };
|
||||
if (Math.abs(dxc) >= Math.abs(dyc)) {
|
||||
if (dxc === 0) continue;
|
||||
const t = dx / dxc;
|
||||
pt = { x: cursor.x, y: base.y + t * dyc };
|
||||
} else {
|
||||
if (dyc === 0) continue;
|
||||
const t = dy / dyc;
|
||||
pt = { x: base.x + t * dxc, y: cursor.y };
|
||||
}
|
||||
const dist = Math.hypot(pt.x - cursor.x, pt.y - cursor.y);
|
||||
if (dist < bestDist) {
|
||||
bestDist = dist;
|
||||
best = pt;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user