Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 18x 18x 18x 1x 1x 12x 12x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x | 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);
}
|