fix(lab): stabilize replay and densify LiDAR overlay

This commit is contained in:
DCCONSTRUCTIONS
2026-08-25 17:51:50 +03:00
parent 15be698097
commit b5080671c9
8 changed files with 520 additions and 52 deletions
@@ -6,15 +6,20 @@ export interface RecordedEvidencePointCloudOverlayData {
pointsXyd: readonly RecordedEvidenceProjectedPoint[];
sourcePointCount: number;
projectedPointCount: number;
projection: "factory-kb4-exact";
projection:
| "factory-kb4-exact"
| "factory-kb4-causal-registered-accumulation";
ariaLabel: string;
}
const DEPTH_BUCKETS = 64;
function depthColor(depthM: number): string {
function depthBucket(depthM: number): number {
const normalized = Math.max(0, Math.min(1, (depthM - 0.5) / 24));
const bucket = Math.round(normalized * (DEPTH_BUCKETS - 1));
return Math.round(normalized * (DEPTH_BUCKETS - 1));
}
function depthColor(bucket: number): string {
const hue = 18 + bucket / (DEPTH_BUCKETS - 1) * 190;
return `hsla(${hue}, 96%, 62%, 0.86)`;
}
@@ -52,16 +57,26 @@ export function RecordedEvidencePointCloudOverlay({
const offsetX = (width - imageWidth * scale) / 2;
const offsetY = (height - imageHeight * scale) / 2;
const radius = Math.max(0.8, Math.min(2.2, scale * 1.45));
const buckets = Array.from(
{ length: DEPTH_BUCKETS },
(): [number, number][] => [],
);
for (const [imageX, imageY, depthM] of overlay.pointsXyd) {
context.beginPath();
context.arc(
const bucket = depthBucket(depthM);
buckets[bucket]!.push([
offsetX + imageX * scale,
offsetY + imageY * scale,
radius,
0,
Math.PI * 2,
);
context.fillStyle = depthColor(depthM);
]);
}
for (let bucket = 0; bucket < buckets.length; bucket += 1) {
const points = buckets[bucket];
if (!points?.length) continue;
context.beginPath();
for (const [x, y] of points) {
context.moveTo(x + radius, y);
context.arc(x, y, radius, 0, Math.PI * 2);
}
context.fillStyle = depthColor(bucket);
context.fill();
}
};