Files
tono/frontend/src/angleMeasureGeometry.js

78 lines
2.5 KiB
JavaScript

function clamp01(value) {
return Math.max(0, Math.min(1, Number(value) || 0));
}
export function round3(value) {
return Number.parseFloat(Number(value).toFixed(3));
}
export function getAngleLabelBasePosition(x1, y1, xm, ym, x2, y2) {
const va = { x: Number(x1) - Number(xm), y: Number(y1) - Number(ym) };
const vb = { x: Number(x2) - Number(xm), y: Number(y2) - Number(ym) };
const lenA = Math.hypot(va.x, va.y);
const lenB = Math.hypot(vb.x, vb.y);
if (lenA <= 1e-6 || lenB <= 1e-6) {
return { x: clamp01(xm), y: clamp01(Number(ym) - 0.14) };
}
const unit = {
x: (va.x / lenA) + (vb.x / lenB),
y: (va.y / lenA) + (vb.y / lenB),
};
const unitLength = Math.hypot(unit.x, unit.y);
const bisector = unitLength <= 1e-6
? { x: 0, y: -1 }
: { x: unit.x / unitLength, y: unit.y / unitLength };
return {
x: clamp01(Number(xm) + bisector.x * 0.14),
y: clamp01(Number(ym) + bisector.y * 0.14),
};
}
export function getAngleLabelPosition(points, labelDx = 0, labelDy = 0) {
const base = getAngleLabelBasePosition(points.x1, points.y1, points.xm, points.ym, points.x2, points.y2);
return {
x: clamp01(base.x + (Number(labelDx) || 0)),
y: clamp01(base.y + (Number(labelDy) || 0)),
};
}
export function moveAngleWidget(points, dx, dy) {
const nextDx = Number(dx) || 0;
const nextDy = Number(dy) || 0;
const xs = [points.x1, points.xm, points.x2];
const ys = [points.y1, points.ym, points.y2];
const minX = Math.min(...xs);
const maxX = Math.max(...xs);
const minY = Math.min(...ys);
const maxY = Math.max(...ys);
const clampedDx = Math.max(-minX, Math.min(1 - maxX, nextDx));
const clampedDy = Math.max(-minY, Math.min(1 - maxY, nextDy));
return {
x1: round3(clamp01(points.x1 + clampedDx)),
y1: round3(clamp01(points.y1 + clampedDy)),
xm: round3(clamp01(points.xm + clampedDx)),
ym: round3(clamp01(points.ym + clampedDy)),
x2: round3(clamp01(points.x2 + clampedDx)),
y2: round3(clamp01(points.y2 + clampedDy)),
};
}
export function measureAngleDegrees(x1, y1, xm, ym, x2, y2) {
const ax = Number(x1) - Number(xm);
const ay = Number(y1) - Number(ym);
const bx = Number(x2) - Number(xm);
const by = Number(y2) - Number(ym);
const lenA = Math.hypot(ax, ay);
const lenB = Math.hypot(bx, by);
if (lenA <= 1e-12 || lenB <= 1e-12) return 0;
const cosTheta = ((ax * bx) + (ay * by)) / (lenA * lenB);
const clamped = Math.max(-1, Math.min(1, cosTheta));
return Math.acos(clamped) * (180 / Math.PI);
}