Import source: web/src/lib/geometry

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:20:19 +03:30
parent 25222a10b5
commit 2b7d4d293b
+48
View File
@@ -0,0 +1,48 @@
/**
* Arc geometry for the circular visualizations.
* Angles are in degrees, 0° at 12 o'clock, increasing clockwise.
*/
export interface Point {
x: number;
y: number;
}
export function polar(cx: number, cy: number, r: number, angleDeg: number): Point {
const a = ((angleDeg - 90) * Math.PI) / 180;
return { x: cx + r * Math.cos(a), y: cy + r * Math.sin(a) };
}
/**
* SVG path for a clockwise arc from startDeg to endDeg at radius r.
* Handles sweeps up to a full circle.
*/
export function arcPath(
cx: number,
cy: number,
r: number,
startDeg: number,
endDeg: number,
): string {
const sweep = Math.min(endDeg - startDeg, 359.999);
if (sweep <= 0) return "";
const from = polar(cx, cy, r, startDeg);
const to = polar(cx, cy, r, startDeg + sweep);
const largeArc = sweep > 180 ? 1 : 0;
return `M ${from.x.toFixed(3)} ${from.y.toFixed(3)} A ${r} ${r} 0 ${largeArc} 1 ${to.x.toFixed(3)} ${to.y.toFixed(3)}`;
}
/** Circumference helper for dash-based arc animation. */
export function circumference(r: number): number {
return 2 * Math.PI * r;
}
/**
* Maps latency to a 0..1 scale, logarithmic so both 2ms pings and
* 800ms page loads read meaningfully. 1ms → 0, 2500ms → 1.
*/
export function latencyScale(ms: number): number {
if (ms <= 1) return 0;
const v = Math.log10(ms) / Math.log10(2500);
return Math.min(1, Math.max(0, v));
}