Files
dsp-thomann-interface/src/features/dsp408/utils/graph/curve.ts
T

98 lines
2.2 KiB
TypeScript

export function logSpace(xMin: number, xMax: number, steps: number): number[] {
const logMin = Math.log10(xMin);
const logMax = Math.log10(xMax);
const out: number[] = [];
for (let s = 0; s <= steps; s++) {
out.push(Math.pow(10, logMin + ((logMax - logMin) * s) / steps));
}
return out;
}
export type CurvePoint = { x: number; y: number };
export type CurveColors = {
strokeColor: string;
fillAbove: string;
fillAboveFade: string;
fillBelowFade: string;
fillBelow: string;
};
export const DEFAULT_CURVE_COLORS: CurveColors = {
strokeColor: '#e5e7eb',
fillAbove: 'rgba(74, 222, 128, 0.35)',
fillAboveFade: 'rgba(74, 222, 128, 0.08)',
fillBelowFade: 'rgba(248, 113, 113, 0.08)',
fillBelow: 'rgba(248, 113, 113, 0.35)',
};
export type CurveStyle = {
strokeColor?: string;
fillColors?: CurveColors;
/** Draw the area fill under/around the curve. Defaults to true. */
fill?: boolean;
lineWidth?: number;
dimmed?: boolean;
};
/** A single polyline ready to be handed to `drawCurves`. */
export type Curve = {
points: CurvePoint[];
style?: CurveStyle;
};
export function sumCurvePoints(pointArrays: CurvePoint[][]): CurvePoint[] {
if (pointArrays.length === 0) return [];
const length = pointArrays[0].length;
const result: CurvePoint[] = new Array(length);
for (let i = 0; i < length; i++) {
let y = 0;
for (const points of pointArrays) {
y += points[i]?.y ?? 0;
}
result[i] = { x: pointArrays[0][i].x, y };
}
return result;
}
export function sumPhaseCurvePoints(pointArrays: CurvePoint[][]): CurvePoint[] {
if (pointArrays.length === 0) return [];
const length = pointArrays[0].length;
const result: CurvePoint[] = new Array(length);
let previousPhase = 0;
for (let i = 0; i < length; i++) {
let phase = 0;
for (const points of pointArrays) {
phase += points[i]?.y ?? 0;
}
// Keep phase continuous while summing.
while (phase - previousPhase > 180) {
phase -= 360;
}
while (phase - previousPhase < -180) {
phase += 360;
}
// Wrap to [-180, 180].
const wrapped = ((((phase + 180) % 360) + 360) % 360) - 180;
result[i] = {
x: pointArrays[0][i].x,
y: wrapped,
};
previousPhase = phase;
}
return result;
}