Техническа Справка и Формули
Пълна Математическа Имплементация
Ръководство за Имплементация
Тази страница предоставя готови за копиране формули и стъпка по стъпка методи за изчисление на всички метрики на Swim Analytics. Използвайте ги за персонализирани имплементации, верификация или по-задълбочено разбиране.
⚠️ Бележки за Имплементация
- Всички времена трябва да се конвертират в секунди за изчисленията
- Темпът при плуване е обратен (по-висок % = по-бавен темп)
- Винаги валидирайте входните данни за разумни диапазони
- Обработвайте гранични случаи (деление на нула, отрицателни стойности)
Искате ли да избегнете ръчните изчисления? Прочетете нашитеРъководство за тренировъчно натоварванеили използвайте безплатното приложение Swim Analytics.
Основни Метрики за Представяне
Критична скорост на плуване (CSS)
Формула:
CSS (m/s) = (D₂ - D₁) / (T₂ - T₁)
CSS Ritmo/100m (segundos) = (T₄₀₀ - T₂₀₀) / 2
🧪 Интерактивен Калкулатор - Тествайте Формулата
Темпо на CSS за 100 м:
1:49
Стъпки на изчислението:
CSS (м/с) = (400 - 200) / (368 - 150) = 0.917 м/с
Темп/100м = 100 / 0.917 = 109 секунди = 1:49
CSS (м/с) = (400 - 200) / (368 - 150) = 0.917 м/с
Темп/100м = 100 / 0.917 = 109 секунди = 1:49
Внедряване в 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" }Оценка на Тренировъчния Стрес при Плуване (sTSS)
Пълна Формула:
sTSS = (IF³) × Продължителност (часове) × 100
IF = NSS / FTP
NSS = Обща Дистанция / Общо Време (м/мин)
🧪 Интерактивен калкулатор - Тествайте формулата
Изчислен sTSS:
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
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
Внедряване в 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
Формула:
SWOLF = Време за дължина (секунди) + Брой загребвания
SWOLF₂₅ = (Време × 25/Дължина на басейна) + (Загребвания × 25/Дължина на басейна)
🧪 Интерактивен калкулатор - Тествайте формулата
SWOLF резултат:
35
Изчисление:
SWOLF = 20s + 15 загребвания = 35
SWOLF = 20s + 15 загребвания = 35
Внедряване в 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)Механика на Гребането
Честота на ударите (SR)
Формула:
SR = 60 / Време на цикъл (секунди)
SR = (Брой загребвания / Време в секунди) × 60
🧪 Интерактивен калкулатор - Тествайте формулата
Честота на ударите (SPM):
72
Изчисление:
SR = (30 / 25) × 60 = 72 SPM
SR = (30 / 25) × 60 = 72 SPM
Внедряване в JavaScript:
function calculateStrokeRate(strokeCount, timeSeconds) {
return (strokeCount / timeSeconds) * 60;
}
// Example:
const sr = calculateStrokeRate(30, 25);
// Returns: 72 SPMРазстояние на ход (DPS)
Формула:
DPS = Разстояние / Брой загребвания
DPS = Разстояние / (SR / 60)
Внедряване в 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)Скорост от SR и DPS
Формула:
Скорост (m/s) = (SR / 60) × DPS
Внедряване в JavaScript:
function calculateVelocity(strokeRate, dps) {
return (strokeRate / 60) * dps;
}
// Example:
const velocity = calculateVelocity(70, 1.6);
// Returns: 1.87 m/sИндекс на инсулт (SI)
Формула:
SI = Скорост (m/s) × DPS (m/загребване)
Внедряване в JavaScript:
function calculateStrokeIndex(velocity, dps) {
return velocity * dps;
}
// Example:
const si = calculateStrokeIndex(1.5, 1.7);
// Returns: 2.55Графика за Управление на Представянето (PMC)
CTL, ATL, TSB изчисления
Формули:
CTL hoy = CTL ayer + (TSS hoy - CTL ayer) × (1/42)
ATL hoy = ATL ayer + (TSS hoy - ATL ayer) × (1/7)
TSB = CTL ayer - ATL ayer
Внедряване в 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 dayРазширени изчисления
CSS от множество разстояния (метод на регресия)
Внедряване в 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 }Коефициент на интензитет от ритъм
Внедряване в 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)Анализ на последователността на ритъма
Внедряване в 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 ? "Excelente" :
coefficientOfVariation < 10 ? "Buena" :
coefficientOfVariation < 15 ? "Moderada" : "Variable"
};
}
// 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: "Excelente" }Откриване на умора чрез броене на удари
Внедряване в 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 ? "Mínima" :
strokeCountIncrease < 10 ? "Moderada" :
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" }Валидиране на данни
Проверка на качеството на данните за обучение
Внедряване в 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 promedio inusual: ${Math.round(avgPace)}s por 100m`);
}
// Check for reasonable stroke counts (10-50 per 25m)
const avgStrokesPer25m = (workout.totalStrokes / workout.totalDistance) * 25;
if (avgStrokesPer25m < 10 || avgStrokesPer25m > 50) {
issues.push(`Необичаен брой загребвания: ${Math.round(avgStrokesPer25m)} за 25м`);
}
// Check for reasonable stroke rate (30-150 SPM)
const avgSR = calculateStrokeRate(workout.totalStrokes, workout.totalTime);
if (avgSR < 30 || avgSR > 150) {
issues.push(`Необичайна честота на загребвания: ${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(`Hueco grande detectado entre largos ${i} y ${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: [] }Помощни функции
Помощни програми за преобразуване на време
Внедряване в 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"Ресурси за внедряване
Всички формули на тази страница са готови за производство и са валидирани спрямо научна литература. Използвайте ги за персонализирани инструменти за анализ, проверка или по-задълбочено разбиране на изчисленията на ефективността при плуване.
💡 Най-добри практики
- Проверка на записите:Проверете разумните диапазони, преди да изчислите
- Обработвайте гранични случаи:Деление на нула, отрицателни стойности, нулеви данни
- Закръглете по подходящ начин:CTL/ATL/TSB е 1 десетичен знак, sTSS е ентеро
- Съхранява прецизност:Поддържайте пълна прецизност в базата данни, кръгла за показване
- Тествайте внимателно:Използвайте известни и правилни данни, за да проверите изчисленията
