Improve phase trail and correlation controls
This commit is contained in:
+50
-12
@@ -29,6 +29,8 @@ const PHASE_RADIUS_TAU_S = 0.085;
|
||||
const PHASE_TRAIL_FADE_MS = 2000;
|
||||
const PHASE_TRAIL_MIN_STEP_MS = 1000 / 45;
|
||||
const PHASE_TRAIL_MIN_DIST_PX = 1.5;
|
||||
const PHASE_TRAIL_MAX_ANGLE_STEP_RAD = (2 * Math.PI) / 180;
|
||||
const PHASE_TRAIL_MAX_POINTS = 1024;
|
||||
const PHASE_SECTORS = [
|
||||
{ startDeg: -30, endDeg: 30, color: 'rgba(72,210,150,0.3)' },
|
||||
{ startDeg: 30, endDeg: 60, color: 'rgba(255,214,120,0.25)' },
|
||||
@@ -517,31 +519,64 @@ function updatePhaseTrail(state, wheel, CONFIG, now) {
|
||||
}
|
||||
const radiusNorm = Math.max(0, Number(state?.smoothRadius) || 0);
|
||||
if (radiusNorm > 0.002 && Number.isFinite(state?.smoothPhase)) {
|
||||
const length = radiusNorm * wheel.radius;
|
||||
const x = wheel.cx + Math.cos(state.smoothPhase) * length;
|
||||
const y = wheel.cy + Math.sin(state.smoothPhase) * length;
|
||||
const color = trailColorForAngle(state.smoothPhase);
|
||||
const phase = wrapAngle(state.smoothPhase);
|
||||
const point = createPhaseTrailPoint(wheel, phase, radiusNorm, now);
|
||||
const last = state.phaseTrail.length ? state.phaseTrail[state.phaseTrail.length - 1] : null;
|
||||
if (!last) {
|
||||
state.phaseTrail.push({ x, y, t: now, color });
|
||||
state.phaseTrail.push(point);
|
||||
} else {
|
||||
const dt = now - last.t;
|
||||
const dx = x - last.x;
|
||||
const dy = y - last.y;
|
||||
const dx = point.x - last.x;
|
||||
const dy = point.y - last.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dt >= PHASE_TRAIL_MIN_STEP_MS || dist2 >= PHASE_TRAIL_MIN_DIST_PX * PHASE_TRAIL_MIN_DIST_PX || last.color !== color) {
|
||||
state.phaseTrail.push({ x, y, t: now, color });
|
||||
if (dt >= PHASE_TRAIL_MIN_STEP_MS || dist2 >= PHASE_TRAIL_MIN_DIST_PX * PHASE_TRAIL_MIN_DIST_PX || last.color !== point.color) {
|
||||
appendPhaseTrailSegment(state.phaseTrail, wheel, last, phase, radiusNorm, now);
|
||||
} else {
|
||||
last.x = x;
|
||||
last.y = y;
|
||||
last.x = point.x;
|
||||
last.y = point.y;
|
||||
last.t = now;
|
||||
last.color = color;
|
||||
last.color = point.color;
|
||||
last.phase = phase;
|
||||
last.radiusNorm = radiusNorm;
|
||||
}
|
||||
}
|
||||
}
|
||||
trimPhaseTrail(state, CONFIG, now);
|
||||
}
|
||||
|
||||
function createPhaseTrailPoint(wheel, phase, radiusNorm, timestamp) {
|
||||
const length = radiusNorm * wheel.radius;
|
||||
return {
|
||||
x: wheel.cx + Math.cos(phase) * length,
|
||||
y: wheel.cy + Math.sin(phase) * length,
|
||||
t: timestamp,
|
||||
color: trailColorForAngle(phase),
|
||||
phase,
|
||||
radiusNorm,
|
||||
};
|
||||
}
|
||||
|
||||
function appendPhaseTrailSegment(trail, wheel, last, phase, radiusNorm, timestamp) {
|
||||
const startPhase = Number.isFinite(last?.phase) ? last.phase : phase;
|
||||
const startRadius = Number.isFinite(last?.radiusNorm) ? last.radiusNorm : radiusNorm;
|
||||
const phaseDelta = wrapAngle(phase - startPhase);
|
||||
const steps = Math.max(1, Math.ceil(Math.abs(phaseDelta) / PHASE_TRAIL_MAX_ANGLE_STEP_RAD));
|
||||
const startTime = Number.isFinite(last?.t) ? last.t : timestamp;
|
||||
|
||||
for (let step = 1; step <= steps; step++) {
|
||||
const fraction = step / steps;
|
||||
const interpolatedPhase = wrapAngle(startPhase + phaseDelta * fraction);
|
||||
const interpolatedRadius = lerp(startRadius, radiusNorm, fraction);
|
||||
const interpolatedTime = lerp(startTime, timestamp, fraction);
|
||||
trail.push(createPhaseTrailPoint(
|
||||
wheel,
|
||||
interpolatedPhase,
|
||||
interpolatedRadius,
|
||||
interpolatedTime,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
function trimPhaseTrail(state, CONFIG, now) {
|
||||
if (!state.phaseTrail) state.phaseTrail = [];
|
||||
if (!CONFIG?.PHASE_TRAIL_ENABLED) {
|
||||
@@ -557,6 +592,9 @@ function trimPhaseTrail(state, CONFIG, now) {
|
||||
}
|
||||
}
|
||||
state.phaseTrail.length = write;
|
||||
if (state.phaseTrail.length > PHASE_TRAIL_MAX_POINTS) {
|
||||
state.phaseTrail.splice(0, state.phaseTrail.length - PHASE_TRAIL_MAX_POINTS);
|
||||
}
|
||||
}
|
||||
|
||||
function drawPhaseTrail(g, wheel, state, CONFIG, now) {
|
||||
|
||||
Reference in New Issue
Block a user