Műszaki Referencia & Képletek

Teljes Matematikai Megvalósítás

Megvalósítási Útmutató

Ez az oldal másolható képleteket és lépésről lépésre történő számítási módszereket tartalmaz az összes Swim Analytics mérőszámhoz. Használja ezeket egyedi megvalósításokhoz, ellenőrzéshez vagy mélyebb megértéshez.

⚠️ Megvalósítási Megjegyzések

  • Minden időt másodpercre kell konvertálni a számításokhoz
  • Az úszási tempó fordított (magasabb % = lassabb tempó)
  • Mindig érvényesítse a bemeneteket ésszerű tartományokra
  • Kezelje a szélső eseteket (nullával való osztás, negatív értékek)

Alapvető Teljesítmény Mérőszámok

Kritikus Úszósebesség (CSS)

Képlet:

CSS (m/s) = (D₂ - D₁) / (T₂ - T₁)
CSS Tempó/100m (másodperc) = (T₄₀₀ - T₂₀₀) / 2

🧪 Interaktív Számológép - Tesztelje a Képletet

CSS Tempó / 100m:
1:49
Számítási lépések:
CSS (m/s) = (400 - 200) / (368 - 150) = 0.917 m/s
Tempó/100m = 100 / 0.917 = 109 másodperc = 1:49

JavaScript Megvalósítás:

function calculateCSS(distance1, time1, distance2, time2) {
  // Idők másodpercre konvertálása, ha szükséges
  const t1 = typeof time1 === 'string' ? timeToSeconds(time1) : time1;
  const t2 = typeof time2 === 'string' ? timeToSeconds(time2) : time2;

  // CSS kiszámítása m/s-ban
  const css_ms = (distance2 - distance1) / (t2 - t1);

  // Tempó kiszámítása 100 méterre, másodpercben
  const pace_per_100m = 100 / css_ms;

  // Konvertálás pp:mp formátumra
  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')}`
  };
}

// Példa használat:
const result = calculateCSS(200, 150, 400, 368);
// Visszatérési érték: { css_ms: 0.917, pace_seconds: 109, pace_formatted: "1:49" }

Úszás Edzési Stressz Pontszám (sTSS)

Teljes Képlet:

sTSS = (IF³) × Időtartam (óra) × 100
IF = NSS / FTP
NSS = Teljes Táv / Teljes Idő (m/perc)

🧪 Interaktív Számológép - Tesztelje a Képletet

Számított sTSS:
55
Számítási lépések:
NSS = 3000m / 55perc = 54.5 m/perc
FTP = 100 / (93/60) = 64.5 m/perc
IF = 54.5 / 64.5 = 0.845
sTSS = 0.845³ × (55/60) × 100 = 55

JavaScript Megvalósítás:

function calculateSTSS(distance, timeMinutes, ftpMetersPerMin) {
  // Normalizált Úszósebesség (NSS) kiszámítása
  const nss = distance / timeMinutes;

  // Intenzitási Faktor (IF) kiszámítása
  const intensityFactor = nss / ftpMetersPerMin;

  // Órák kiszámítása
  const hours = timeMinutes / 60;

  // sTSS kiszámítása köbös intenzitási faktorral
  const stss = Math.pow(intensityFactor, 3) * hours * 100;

  return Math.round(stss);
}

// Példa használat:
const stss = calculateSTSS(3000, 55, 64.5);
// Visszatérési érték: 55

// Segéd: CSS konvertálása FTP-re
function cssToFTP(cssPacePer100mSeconds) {
  // FTP m/perc-ben = 100m / (tempó percekben)
  return 100 / (cssPacePer100mSeconds / 60);
}

// Példa: 1:33 (93 másodperc) CSS
const ftp = cssToFTP(93); // Visszatérési érték: 64.5 m/perc

SWOLF

Képlet:

SWOLF = Omgangstid (másodperc) + Csapásszám
SWOLF₂₅ = (Idő × 25/Medencehossz) + (Csapás × 25/Medencehossz)

🧪 Interaktív Számológép - Tesztelje a Képletet

SWOLF Pontszám:
35
Számítás:
SWOLF = 20s + 15 csapás = 35

JavaScript Megvalósítás:

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;
}

// Példa:
const swolf = calculateSWOLF(20, 15);
// Visszatérési érték: 35

const swolf50m = calculateNormalizedSWOLF(40, 30, 50);
// Visszatérési érték: 35 (25m-re normalizálva)

Úszómechanika

Csapásfrekvencia (SR)

Képlet:

SR = 60 / Ciklusidő (másodperc)
SR = (Csapásszám / Idő másodpercben) × 60

🧪 Interaktív Számológép - Tesztelje a Képletet

Csapásfrekvencia (SPM):
72
Számítás:
SR = (30 / 25) × 60 = 72 SPM

JavaScript Megvalósítás:

function calculateStrokeRate(strokeCount, timeSeconds) {
  return (strokeCount / timeSeconds) * 60;
}

// Példa:
const sr = calculateStrokeRate(30, 25);
// Visszatérési érték: 72 SPM

Távolság Csapásonként (DPS)

Képlet:

DPS = Távolság / Csapásszám
DPS = Távolság / (SR / 60)

JavaScript Megvalósítás:

function calculateDPS(distance, strokeCount, pushoffDistance = 0) {
  const effectiveDistance = distance - pushoffDistance;
  return effectiveDistance / strokeCount;
}

// Példa (25m medence, 5m elrugaszkodás):
const dps = calculateDPS(25, 12, 5);
// Visszatérési érték: 1.67 m/csapás

// Több kör esetén:
const dps100m = calculateDPS(100, 48, 4 * 5);
// Visszatérési érték: 1.67 m/csapás (4 kör × 5m elrugaszkodás)

Sebesség SR és DPS alapján

Képlet:

Sebesség (m/s) = (SR / 60) × DPS

JavaScript Megvalósítás:

function calculateVelocity(strokeRate, dps) {
  return (strokeRate / 60) * dps;
}

// Példa:
const velocity = calculateVelocity(70, 1.6);
// Visszatérési érték: 1.87 m/s

Csapás Index (SI)

Képlet:

SI = Sebesség (m/s) × DPS (m/csapás)

JavaScript Megvalósítás:

function calculateStrokeIndex(velocity, dps) {
  return velocity * dps;
}

// Példa:
const si = calculateStrokeIndex(1.5, 1.7);
// Visszatérési érték: 2.55

Performance Management Chart (PMC)

CTL, ATL, TSB Számítások

Képletek:

CTL ma = CTL tegnap + (TSS ma - CTL tegnap) × (1/42)
ATL ma = ATL tegnap + (TSS ma - ATL tegnap) × (1/7)
TSB = CTL tegnap - ATL tegnap

JavaScript Megvalósítás:

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;
}

// PMC kiszámítása edzéssorozathoz
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;
}

// Példa használat:
const workouts = [
  { date: '2025-01-01', tss: 50 },
  { date: '2025-01-02', tss: 60 },
  { date: '2025-01-03', tss: 45 },
  // ... további edzések
];

const pmc = calculatePMC(workouts);
// Visszatérési érték: tömb CTL, ATL, TSB értékekkel minden napra

Haladó Számítások

CSS Több Távból (Regressziós Módszer)

JavaScript Megvalósítás:

function calculateCSSRegression(distances, times) {
  // Lineáris regresszió: távolság = a + b*idő
  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, // Kritikus úszósebesség (m/s)
    anaerobic_capacity: intercept // Anaerob kapacitás (m)
  };
}

// Példa több teszttávval:
const distances = [100, 200, 400, 800];
const times = [65, 150, 340, 720]; // másodpercben
const result = calculateCSSRegression(distances, times);
// Visszatérési érték: { css: 1.18, anaerobic_capacity: 15.3 }

Intenzitási Faktor Tempóból

JavaScript Megvalósítás:

function calculateIntensityFactor(actualPace100m, thresholdPace100m) {
  // Tempó konvertálása sebességre (m/s)
  const actualSpeed = 100 / actualPace100m;
  const thresholdSpeed = 100 / thresholdPace100m;
  return actualSpeed / thresholdSpeed;
}

// Példa:
const if_value = calculateIntensityFactor(110, 93);
// Visszatérési érték: 0.845 (küszöbérték 84.5%-án úszva)

Tempó Következetesség Elemzés

JavaScript Megvalósítás:

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 ? "Kiváló" :
                 coefficientOfVariation < 10 ? "Jó" :
                 coefficientOfVariation < 15 ? "Közepes" : "Változó"
  };
}

// Példa:
const laps = [
  { distance: 100, time: 70 },
  { distance: 100, time: 72 },
  { distance: 100, time: 71 },
  // ...
];
const analysis = analyzePaceConsistency(laps);
// Visszatérési érték: { avgPace: 1.41, stdDev: 0.02, coefficientOfVariation: 1.4, consistency: "Kiváló" }

Fáradtság Észlelés Csapásszámból

JavaScript Megvalósítás:

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 ? "Minimális" :
                  strokeCountIncrease < 10 ? "Mérsékelt" :
                  strokeCountIncrease < 20 ? "Jelentős" : "Súlyos"
  };
}

// Példa:
const laps = [
  { strokeCount: 14 }, { strokeCount: 14 }, { strokeCount: 15 },
  { strokeCount: 15 }, { strokeCount: 16 }, { strokeCount: 16 },
  { strokeCount: 17 }, { strokeCount: 18 }, { strokeCount: 18 }
];
const fatigue = detectFatigue(laps);
// Visszatérési érték: { firstThirdAvg: 14.3, lastThirdAvg: 17.7, percentIncrease: 23.8, fatigueLevel: "Súlyos" }

Adat Validálás

Edzésadat Minőségellenőrzés

JavaScript Megvalósítás:

function validateWorkoutData(workout) {
  const issues = [];

  // Ésszerű tempótartományok ellenőrzése (1:00-5:00 / 100m)
  const avgPace = (workout.totalTime / workout.totalDistance) * 100;
  if (avgPace < 60 || avgPace > 300) {
    issues.push(`Szokatlan átlagtempó: ${Math.round(avgPace)}s / 100m`);
  }

  // Ésszerű csapásszám ellenőrzése (10-50 / 25m)
  const avgStrokesPer25m = (workout.totalStrokes / workout.totalDistance) * 25;
  if (avgStrokesPer25m < 10 || avgStrokesPer25m > 50) {
    issues.push(`Szokatlan csapásszám: ${Math.round(avgStrokesPer25m)} / 25m`);
  }

  // Ésszerű csapásfrekvencia ellenőrzése (30-150 SPM)
  const avgSR = calculateStrokeRate(workout.totalStrokes, workout.totalTime);
  if (avgSR < 30 || avgSR > 150) {
    issues.push(`Szokatlan csapásfrekvencia: ${Math.round(avgSR)} SPM`);
  }

  // Hiányzó körök ellenőrzése (időhézagok)
  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 perc hézag
        issues.push(`Nagy hézag észlelve a(z) ${i}. és ${i+1}. kör között`);
      }
    }
  }

  return {
    isValid: issues.length === 0,
    issues: issues
  };
}