Riferimento Tecnico e Formule
Implementazione Matematica Completa
Guida all'Implementazione
Questa pagina fornisce formule pronte per copia-incolla, oltre a metodi di calcolo passo dopo passo per tutte le metriche di Swim Analytics. Utilizzale per implementazioni personalizzate, verifica o comprensione approfondita.
⚠️ Note di Implementazione
- Tutti i tempi devono essere convertiti in secondi per i calcoli
- Il ritmo di nuoto è inverso (percentuale maggiore = ritmo più lento)
- Valida sempre gli input per intervalli ragionevoli
- Gestisci i casi limite (divisione per zero, valori negativi)
Vuoi evitare calcoli manuali? Leggi il nostroGuida al carico di allenamentooppure utilizza l'app gratuita Swim Analytics.
Metriche di Prestazione Principali
Critical Swim Speed (CSS)
Formula:
CSS (m/s) = (D₂ - D₁) / (T₂ - T₁)
CSS Ritmo/100m (secondi) = (T₄₀₀ - T₂₀₀) / 2
🧪 Calcolatore Interattivo - Testa la Formula
Ritmo CSS per 100m:
1:49
Passi del calcolo:
CSS (m/s) = (400 - 200) / (368 - 150) = 0,917 m/s
Ritmo/100m = 100 / 0,917 = 109 secondi = 1:49
CSS (m/s) = (400 - 200) / (368 - 150) = 0,917 m/s
Ritmo/100m = 100 / 0,917 = 109 secondi = 1:49
Implementazione in JavaScript:
function calculateCSS(distance1, time1, distance2, time2) {
// Convert times to seconds if needed
const t1 = typeof time1 === 'string' ? timeToSeconds(time1) : time1;
const t2 = typeof time2 === 'string' ? timeToSeconds(time2) : time2;
// Calculate CSS in m/s
const css_ms = (distance2 - distance1) / (t2 - t1);
// Calculate pace per 100m in seconds
const pace_per_100m = 100 / css_ms;
// Convert to mm:ss format
const minutes = Math.floor(pace_per_100m / 60);
const seconds = Math.round(pace_per_100m % 60);
return {
css_ms: css_ms,
pace_seconds: pace_per_100m,
pace_formatted: `${minutes}:${seconds.toString().padStart(2, '0')}`
};
}
// Example usage:
const result = calculateCSS(200, 150, 400, 368);
// Returns: { css_ms: 0.917, pace_seconds: 109, pace_formatted: "1:49" }Swim Training Stress Score (sTSS)
Formula Completa:
sTSS = (IF³) × Durata (ore) × 100
IF = NSS / FTP
NSS = Distanza Totale / Tempo Totale (m/min)
🧪 Calcolatore Interattivo - Testa la Formula
sTSS Calcolato:
55
Passi del calcolo:
NSS = 3000m / 55min = 54,5 m/min
FTP = 100 / (93/60) = 64,5 m/min
IF = 54,5 / 64,5 = 0,845
sTSS = 0,845³ × (55/60) × 100 = 55
NSS = 3000m / 55min = 54,5 m/min
FTP = 100 / (93/60) = 64,5 m/min
IF = 54,5 / 64,5 = 0,845
sTSS = 0,845³ × (55/60) × 100 = 55
Implementazione in JavaScript:
function calculateSTSS(distance, timeMinutes, ftpMetersPerMin) {
// Calculate Normalized Swim Speed
const nss = distance / timeMinutes;
// Calculate Intensity Factor
const intensityFactor = nss / ftpMetersPerMin;
// Calculate hours
const hours = timeMinutes / 60;
// Calculate sTSS using cubed intensity factor
const stss = Math.pow(intensityFactor, 3) * hours * 100;
return Math.round(stss);
}
// Example usage:
const stss = calculateSTSS(3000, 55, 64.5);
// Returns: 55
// Helper: Convert CSS to FTP
function cssToFTP(cssPacePer100mSeconds) {
// FTP in m/min = 100m / (pace in minutes)
return 100 / (cssPacePer100mSeconds / 60);
}
// Example: CSS of 1:33 (93 seconds)
const ftp = cssToFTP(93); // Returns: 64.5 m/minSWOLF
Formula:
SWOLF = Tempo della Vasca (secondi) + Conteggio Bracciate
SWOLF₂₅ = (Tempo × 25/Lunghezza Vasca) + (Bracciate × 25/Lunghezza Vasca)
🧪 Calcolatore Interattivo - Testa la Formula
Punteggio SWOLF:
35
Calcolo:
SWOLF = 20s + 15 bracciate = 35
SWOLF = 20s + 15 bracciate = 35
Implementazione in JavaScript:
function calculateSWOLF(timeSeconds, strokeCount) {
return timeSeconds + strokeCount;
}
function calculateNormalizedSWOLF(timeSeconds, strokeCount, poolLength) {
const normalizedTime = timeSeconds * (25 / poolLength);
const normalizedStrokes = strokeCount * (25 / poolLength);
return normalizedTime + normalizedStrokes;
}
// Example:
const swolf = calculateSWOLF(20, 15);
// Returns: 35
const swolf50m = calculateNormalizedSWOLF(40, 30, 50);
// Returns: 35 (normalized to 25m)Meccanica della Bracciata
Stroke Rate (SR)
Formula:
SR = 60 / Tempo di Ciclo (secondi)
SR = (Numero di Bracciate / Tempo in secondi) × 60
🧪 Calcolatore Interattivo - Testa la Formula
Stroke Rate (SPM):
72
Calcolo:
SR = (30 / 25) × 60 = 72 SPM
SR = (30 / 25) × 60 = 72 SPM
Implementazione in JavaScript:
function calculateStrokeRate(strokeCount, timeSeconds) {
return (strokeCount / timeSeconds) * 60;
}
// Example:
const sr = calculateStrokeRate(30, 25);
// Returns: 72 SPMDistance Per Stroke (DPS)
Formula:
DPS = Distanza / Conteggio Bracciate
DPS = Distanza / (SR / 60)
Implementazione in JavaScript:
function calculateDPS(distance, strokeCount, pushoffDistance = 0) {
const effectiveDistance = distance - pushoffDistance;
return effectiveDistance / strokeCount;
}
// Example (25m pool, 5m push-off):
const dps = calculateDPS(25, 12, 5);
// Returns: 1.67 m/stroke
// For multiple laps:
const dps100m = calculateDPS(100, 48, 4 * 5);
// Returns: 1.67 m/stroke (4 laps × 5m push-off)Velocità da SR e DPS
Formula:
Velocità (m/s) = (SR / 60) × DPS
Implementazione in JavaScript:
function calculateVelocity(strokeRate, dps) {
return (strokeRate / 60) * dps;
}
// Example:
const velocity = calculateVelocity(70, 1.6);
// Returns: 1.87 m/sStroke Index (SI)
Formula:
SI = Velocità (m/s) × DPS (m/bracciata)
Implementazione in JavaScript:
function calculateStrokeIndex(velocity, dps) {
return velocity * dps;
}
// Example:
const si = calculateStrokeIndex(1.5, 1.7);
// Returns: 2.55Grafico di Gestione della Prestazione (PMC)
Calcoli di CTL, ATL, TSB
Formule:
CTL oggi = CTL ieri + (TSS oggi - CTL ieri) × (1/42)
ATL oggi = ATL ieri + (TSS oggi - ATL ieri) × (1/7)
TSB = CTL ieri - ATL ieri
Implementazione in JavaScript:
function updateCTL(previousCTL, todayTSS) {
return previousCTL + (todayTSS - previousCTL) * (1/42);
}
function updateATL(previousATL, todayTSS) {
return previousATL + (todayTSS - previousATL) * (1/7);
}
function calculateTSB(yesterdayCTL, yesterdayATL) {
return yesterdayCTL - yesterdayATL;
}
// Calculate PMC for series of workouts
function calculatePMC(workouts) {
let ctl = 0, atl = 0;
const results = [];
workouts.forEach(workout => {
ctl = updateCTL(ctl, workout.tss);
atl = updateATL(atl, workout.tss);
const tsb = calculateTSB(ctl, atl);
results.push({
date: workout.date,
tss: workout.tss,
ctl: Math.round(ctl * 10) / 10,
atl: Math.round(atl * 10) / 10,
tsb: Math.round(tsb * 10) / 10
});
});
return results;
}
// Example usage:
const workouts = [
{ date: '2025-01-01', tss: 50 },
{ date: '2025-01-02', tss: 60 },
{ date: '2025-01-03', tss: 45 },
// ... more workouts
];
const pmc = calculatePMC(workouts);
// Returns array with CTL, ATL, TSB for each dayCalcoli Avanzati
CSS da Multiple Distanze (Metodo di Regressione)
Implementazione in JavaScript:
function calculateCSSRegression(distances, times) {
// Linear regression: distance = a + b*time
const n = distances.length;
const sumX = times.reduce((a, b) => a + b, 0);
const sumY = distances.reduce((a, b) => a + b, 0);
const sumXY = times.reduce((sum, x, i) => sum + x * distances[i], 0);
const sumXX = times.reduce((sum, x) => sum + x * x, 0);
const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
const intercept = (sumY - slope * sumX) / n;
return {
css: slope, // Critical swimming velocity (m/s)
anaerobic_capacity: intercept // Anaerobic distance capacity (m)
};
}
// Example with multiple test distances:
const distances = [100, 200, 400, 800];
const times = [65, 150, 340, 720]; // in seconds
const result = calculateCSSRegression(distances, times);
// Returns: { css: 1.18, anaerobic_capacity: 15.3 }Fattore di Intensità dal Ritmo
Implementazione in JavaScript:
function calculateIntensityFactor(actualPace100m, thresholdPace100m) {
// Convert pace to speed (m/s)
const actualSpeed = 100 / actualPace100m;
const thresholdSpeed = 100 / thresholdPace100m;
return actualSpeed / thresholdSpeed;
}
// Example:
const if_value = calculateIntensityFactor(110, 93);
// Returns: 0.845 (swimming at 84.5% of threshold)Analisi della Consistenza del Ritmo
Implementazione in JavaScript:
function analyzePaceConsistency(laps) {
const paces = laps.map(lap => lap.distance / lap.time);
const avgPace = paces.reduce((a, b) => a + b) / paces.length;
const variance = paces.reduce((sum, pace) =>
sum + Math.pow(pace - avgPace, 2), 0) / paces.length;
const stdDev = Math.sqrt(variance);
const coefficientOfVariation = (stdDev / avgPace) * 100;
return {
avgPace,
stdDev,
coefficientOfVariation,
consistency: coefficientOfVariation < 5 ? "Eccellente" :
coefficientOfVariation < 10 ? "Buona" :
coefficientOfVariation < 15 ? "Moderata" : "Variabile"
};
}
// Example:
const laps = [
{ distance: 100, time: 70 },
{ distance: 100, time: 72 },
{ distance: 100, time: 71 },
// ...
];
const analysis = analyzePaceConsistency(laps);
// Returns: { avgPace: 1.41, stdDev: 0.02, coefficientOfVariation: 1.4, consistency: "Eccellente" }Rilevamento della Fatica tramite Conteggio Bracciate
Implementazione in JavaScript:
function detectFatigue(laps) {
const firstThird = laps.slice(0, Math.floor(laps.length/3));
const lastThird = laps.slice(-Math.floor(laps.length/3));
const firstThirdAvg = firstThird.reduce((sum, lap) =>
sum + lap.strokeCount, 0) / firstThird.length;
const lastThirdAvg = lastThird.reduce((sum, lap) =>
sum + lap.strokeCount, 0) / lastThird.length;
const strokeCountIncrease = ((lastThirdAvg - firstThirdAvg) / firstThirdAvg) * 100;
return {
firstThirdAvg: Math.round(firstThirdAvg * 10) / 10,
lastThirdAvg: Math.round(lastThirdAvg * 10) / 10,
percentIncrease: Math.round(strokeCountIncrease * 10) / 10,
fatigueLevel: strokeCountIncrease < 5 ? "Minima" :
strokeCountIncrease < 10 ? "Moderata" :
strokeCountIncrease < 20 ? "Significativa" : "Severa"
};
}
// Example:
const laps = [
{ strokeCount: 14 }, { strokeCount: 14 }, { strokeCount: 15 },
{ strokeCount: 15 }, { strokeCount: 16 }, { strokeCount: 16 },
{ strokeCount: 17 }, { strokeCount: 18 }, { strokeCount: 18 }
];
const fatigue = detectFatigue(laps);
// Returns: { firstThirdAvg: 14.3, lastThirdAvg: 17.7, percentIncrease: 23.8, fatigueLevel: "Severa" }Validazione dei Dati
Verifica della Qualità dei Dati di Allenamento
Implementazione in JavaScript:
function validateWorkoutData(workout) {
const issues = [];
// Check for reasonable pace ranges (1:00-5:00 per 100m)
const avgPace = (workout.totalTime / workout.totalDistance) * 100;
if (avgPace < 60 || avgPace > 300) {
issues.push(`Ritmo medio insolito: ${Math.round(avgPace)}s per 100m`);
}
// Check for reasonable stroke counts (10-50 per 25m)
const avgStrokesPer25m = (workout.totalStrokes / workout.totalDistance) * 25;
if (avgStrokesPer25m < 10 || avgStrokesPer25m > 50) {
issues.push(`Conteggio bracciate insolito: ${Math.round(avgStrokesPer25m)} per 25m`);
}
// Check for reasonable stroke rate (30-150 SPM)
const avgSR = calculateStrokeRate(workout.totalStrokes, workout.totalTime);
if (avgSR < 30 || avgSR > 150) {
issues.push(`Frequenza di bracciata insolita: ${Math.round(avgSR)} SPM`);
}
// Check for missing laps (gaps in time)
if (workout.laps && workout.laps.length > 1) {
for (let i = 1; i < workout.laps.length; i++) {
const gap = workout.laps[i].startTime -
(workout.laps[i-1].startTime + workout.laps[i-1].duration);
if (gap > 300) { // 5 minute gap
issues.push(`Lacuna ampia rilevata tra vasche ${i} e ${i+1}`);
}
}
}
return {
isValid: issues.length === 0,
issues
};
}
// Example:
const workout = {
totalDistance: 2000,
totalTime: 1800, // 30 minutes
totalStrokes: 800,
laps: [/* lap data */]
};
const validation = validateWorkoutData(workout);
// Returns: { isValid: true, issues: [] }Funzioni Ausiliarie
Utilità di Conversione del Tempo
Implementazione in JavaScript:
// Convert mm:ss to seconds
function timeToSeconds(timeString) {
const parts = timeString.split(':');
return parseInt(parts[0]) * 60 + parseInt(parts[1]);
}
// Convert seconds to mm:ss
function secondsToTime(seconds) {
const minutes = Math.floor(seconds / 60);
const secs = Math.round(seconds % 60);
return `${minutes}:${secs.toString().padStart(2, '0')}`;
}
// Convert seconds to hh:mm:ss
function secondsToTimeDetailed(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = Math.round(seconds % 60);
return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}
// Examples:
timeToSeconds("1:33"); // Returns: 93
secondsToTime(93); // Returns: "1:33"
secondsToTimeDetailed(3665); // Returns: "1:01:05"Risorse per l'Implementazione
Tutte le formule in questa pagina sono pronte per la produzione e validate rispetto alla letteratura scientifica. Utilizzale per strumenti di analisi personalizzati, verifica o comprensione approfondita dei calcoli di prestazione nel nuoto.
💡 Migliori Pratiche
- Valida gli input: Verifica intervalli ragionevoli prima di calcolare
- Gestisci i casi limite: Divisione per zero, valori negativi, dati nulli
- Arrotonda appropriatamente: CTL/ATL/TSB a 1 decimale, sTSS a intero
- Conserva la precisione: Mantieni precisione completa nel database, arrotonda per la visualizzazione
- Testa esaustivamente: Usa dati noti e corretti per verificare i calcoli
