Referensi Teknis & Rumus
Implementasi Matematis Lengkap
Panduan Implementasi
Halaman ini menyediakan rumus siap pakai dan metode kalkulasi langkah demi langkah untuk semua metrik Run Analytics. Gunakan untuk implementasi kustom, verifikasi, atau pemahaman yang lebih mendalam.
⚠️ Catatan Implementasi
- Semua waktu harus dikonversi ke detik untuk kalkulasi
- Kecepatan lari bersifat terbalik (% lebih tinggi = kecepatan lebih lambat)
- Selalu validasi input untuk rentang yang wajar
- Tangani kasus ekstrem (pembagian dengan nol, nilai negatif)
Metrik Performa Inti
Kecepatan Lari Kritis (CRS)
Rumus:
CRS (m/s) = (D₂ - D₁) / (T₂ - T₁)
CRS Pace/100m (detik) = (T₄₀₀ - T₂₀₀) / 2
🧪 Kalkulator Interaktif - Uji Rumus
Pace CRS per 100m:
1:49
Langkah kalkulasi:
CRS (m/s) = (400 - 200) / (368 - 150) = 0.917 m/s
Pace/100m = 100 / 0.917 = 109 detik = 1:49
CRS (m/s) = (400 - 200) / (368 - 150) = 0.917 m/s
Pace/100m = 100 / 0.917 = 109 detik = 1:49
Implementasi JavaScript:
function calculateCRS(distance1, time1, distance2, time2) {
// Konversi waktu ke detik jika diperlukan
const t1 = typeof time1 === 'string' ? timeToSeconds(time1) : time1;
const t2 = typeof time2 === 'string' ? timeToSeconds(time2) : time2;
// Hitung CRS dalam m/s
const css_ms = (distance2 - distance1) / (t2 - t1);
// Hitung pace per 100m dalam detik
const pace_per_100m = 100 / css_ms;
// Konversi ke format mm:ss
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')}`
};
}
// Contoh penggunaan:
const result = calculateCRS(200, 150, 400, 368);
// Mengembalikan: { css_ms: 0.917, pace_seconds: 109, pace_formatted: "1:49" }
Skor Stres Latihan Lari (sTSS)
Rumus Lengkap:
sTSS = (IF³) × Durasi (jam) × 100
IF = NSS / FTP
NSS = Jarak Total / Waktu Total (m/menit)
🧪 Kalkulator Interaktif - Uji Rumus
sTSS Terhitung:
55
Langkah kalkulasi:
NSS = 3000m / 55menit = 54.5 m/menit
FTP = 100 / (93/60) = 64.5 m/menit
IF = 54.5 / 64.5 = 0.845
sTSS = 0.845³ × (55/60) × 100 = 55
NSS = 3000m / 55menit = 54.5 m/menit
FTP = 100 / (93/60) = 64.5 m/menit
IF = 54.5 / 64.5 = 0.845
sTSS = 0.845³ × (55/60) × 100 = 55
Implementasi JavaScript:
function calculateSTSS(distance, timeMinutes, ftpMetersPerMin) {
// Hitung Kecepatan Lari Normalisasi
const nss = distance / timeMinutes;
// Hitung Faktor Intensitas
const intensityFactor = nss / ftpMetersPerMin;
// Hitung jam
const hours = timeMinutes / 60;
// Hitung sTSS menggunakan faktor intensitas pangkat tiga
const stss = Math.pow(intensityFactor, 3) * hours * 100;
return Math.round(stss);
}
// Contoh penggunaan:
const stss = calculateSTSS(3000, 55, 64.5);
// Mengembalikan: 55
// Helper: Konversi CRS ke FTP
function cssToFTP(cssPacePer100mSeconds) {
// FTP dalam m/menit = 100m / (pace dalam menit)
return 100 / (cssPacePer100mSeconds / 60);
}
// Contoh: CRS 1:33 (93 detik)
const ftp = cssToFTP(93); // Mengembalikan: 64.5 m/menit
Efisiensi Lari
Rumus:
Efisiensi Lari = Waktu Kilometer (detik) + Jumlah Langkah
Efisiensi Lari₂₅ = (Waktu × 25/Panjang Lintasan) + (Langkah × 25/Panjang Lintasan)
🧪 Kalkulator Interaktif - Uji Rumus
Skor Efisiensi Lari:
35
Kalkulasi:
Efisiensi Lari = 20d + 15 langkah = 35
Efisiensi Lari = 20d + 15 langkah = 35
Implementasi JavaScript:
function calculateRunningEfficiency(timeSeconds, strideCount) {
return timeSeconds + strideCount;
}
function calculateNormalizedRunningEfficiency(timeSeconds, strideCount, trackLength) {
const normalizedTime = timeSeconds * (25 / trackLength);
const normalizedStrides = strideCount * (25 / trackLength);
return normalizedTime + normalizedStrides;
}
// Contoh:
const swolf = calculateRunningEfficiency(20, 15);
// Mengembalikan: 35
const swolf50m = calculateNormalizedRunningEfficiency(40, 30, 50);
// Mengembalikan: 35 (dinormalisasi ke 25m)
Mekanika Langkah
Laju Langkah (SR)
Rumus:
SR = 60 / Waktu Siklus (detik)
SR = (Jumlah Langkah / Waktu dalam detik) × 60
🧪 Kalkulator Interaktif - Uji Rumus
Laju Langkah (SPM):
72
Kalkulasi:
SR = (30 / 25) × 60 = 72 SPM
SR = (30 / 25) × 60 = 72 SPM
Implementasi JavaScript:
function calculateStrideRate(strideCount, timeSeconds) {
return (strideCount / timeSeconds) * 60;
}
// Contoh:
const sr = calculateStrideRate(30, 25);
// Mengembalikan: 72 SPM
Jarak Per Langkah (DPS)
Rumus:
DPS = Jarak / Jumlah Langkah
DPS = Jarak / (SR / 60)
Implementasi JavaScript:
function calculateDPS(distance, strideCount, pushoffDistance = 0) {
const effectiveDistance = distance - pushoffDistance;
return effectiveDistance / strideCount;
}
// Contoh (lintasan 25m, tolakan 5m):
const dps = calculateDPS(25, 12, 5);
// Mengembalikan: 1.67 m/langkah
// Untuk beberapa segmen:
const dps100m = calculateDPS(100, 48, 4 * 5);
// Mengembalikan: 1.67 m/langkah (4 segmen × 5m tolakan)
Kecepatan dari SR dan DPS
Rumus:
Kecepatan (m/s) = (SR / 60) × DPS
Implementasi JavaScript:
function calculateVelocity(strideRate, dps) {
return (strideRate / 60) * dps;
}
// Contoh:
const velocity = calculateVelocity(70, 1.6);
// Mengembalikan: 1.87 m/s
Indeks Langkah (SI)
Rumus:
SI = Kecepatan (m/s) × DPS (m/langkah)
Implementasi JavaScript:
function calculateStrideIndex(velocity, dps) {
return velocity * dps;
}
// Contoh:
const si = calculateStrideIndex(1.5, 1.7);
// Mengembalikan: 2.55
Grafik Manajemen Performa (PMC)
Kalkulasi CTL, ATL, TSB
Rumus:
CTL hari ini = CTL kemarin + (TSS hari ini - CTL kemarin) × (1/42)
ATL hari ini = ATL kemarin + (TSS hari ini - ATL kemarin) × (1/7)
TSB = CTL kemarin - ATL kemarin
Implementasi 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;
}
// Hitung PMC untuk serangkaian latihan
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;
}
// Contoh penggunaan:
const workouts = [
{ date: '2025-01-01', tss: 50 },
{ date: '2025-01-02', tss: 60 },
{ date: '2025-01-03', tss: 45 },
// ... latihan lainnya
];
const pmc = calculatePMC(workouts);
// Mengembalikan array dengan CTL, ATL, TSB untuk setiap hari
Kalkulasi Lanjutan
CRS dari Berbagai Jarak (Metode Regresi)
Implementasi JavaScript:
function calculateCRSRegression(distances, times) {
// Regresi linear: jarak = a + b*waktu
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, // Kecepatan lari kritis (m/s)
anaerobic_capacity: intercept // Kapasitas jarak anaerobik (m)
};
}
// Contoh dengan berbagai jarak tes:
const distances = [100, 200, 400, 800];
const times = [65, 150, 340, 720]; // dalam detik
const result = calculateCRSRegression(distances, times);
// Mengembalikan: { css: 1.18, anaerobic_capacity: 15.3 }
Faktor Intensitas dari Pace
Implementasi JavaScript:
function calculateIntensityFactor(actualPace100m, thresholdPace100m) {
// Konversi pace ke kecepatan (m/s)
const actualSpeed = 100 / actualPace100m;
const thresholdSpeed = 100 / thresholdPace100m;
return actualSpeed / thresholdSpeed;
}
// Contoh:
const if_value = calculateIntensityFactor(110, 93);
// Mengembalikan: 0.845 (berlari pada 84.5% dari ambang)
Analisis Konsistensi Pace
Implementasi JavaScript:
function analyzePaceConsistency(segments) {
const paces = segments.map(kilometer => kilometer.distance / kilometer.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 ? "Sangat Baik" :
coefficientOfVariation < 10 ? "Baik" :
coefficientOfVariation < 15 ? "Sedang" : "Bervariasi"
};
}
// Contoh:
const segments = [
{ distance: 100, time: 70 },
{ distance: 100, time: 72 },
{ distance: 100, time: 71 },
// ...
];
const analysis = analyzePaceConsistency(segments);
// Mengembalikan: { avgPace: 1.41, stdDev: 0.02, coefficientOfVariation: 1.4, consistency: "Sangat Baik" }
Deteksi Kelelahan dari Jumlah Langkah
Implementasi JavaScript:
function detectFatigue(segments) {
const firstThird = segments.slice(0, Math.floor(segments.length/3));
const lastThird = segments.slice(-Math.floor(segments.length/3));
const firstThirdAvg = firstThird.reduce((sum, kilometer) =>
sum + kilometer.strideCount, 0) / firstThird.length;
const lastThirdAvg = lastThird.reduce((sum, kilometer) =>
sum + kilometer.strideCount, 0) / lastThird.length;
const strideCountIncrease = ((lastThirdAvg - firstThirdAvg) / firstThirdAvg) * 100;
return {
firstThirdAvg: Math.round(firstThirdAvg * 10) / 10,
lastThirdAvg: Math.round(lastThirdAvg * 10) / 10,
percentIncrease: Math.round(strideCountIncrease * 10) / 10,
fatigueLevel: strideCountIncrease < 5 ? "Minimal" :
strideCountIncrease < 10 ? "Sedang" :
strideCountIncrease < 20 ? "Signifikan" : "Parah"
};
}
// Contoh:
const segments = [
{ strideCount: 14 }, { strideCount: 14 }, { strideCount: 15 },
{ strideCount: 15 }, { strideCount: 16 }, { strideCount: 16 },
{ strideCount: 17 }, { strideCount: 18 }, { strideCount: 18 }
];
const fatigue = detectFatigue(segments);
// Mengembalikan: { firstThirdAvg: 14.3, lastThirdAvg: 17.7, percentIncrease: 23.8, fatigueLevel: "Parah" }
Validasi Data
Pemeriksaan Kualitas Data Latihan
Implementasi JavaScript:
function validateWorkoutData(workout) {
const issues = [];
// Periksa rentang pace yang wajar (1:00-5:00 per 100m)
const avgPace = (workout.totalTime / workout.totalDistance) * 100;
if (avgPace < 60 || avgPace > 300) {
issues.push(`Pace rata-rata tidak biasa: ${Math.round(avgPace)}d per 100m`);
}
// Periksa jumlah langkah yang wajar (10-50 per 25m)
const avgStridesPer25m = (workout.totalStrides / workout.totalDistance) * 25;
if (avgStridesPer25m < 10 || avgStridesPer25m > 50) {
issues.push(`Jumlah langkah tidak biasa: ${Math.round(avgStridesPer25m)} per 25m`);
}
// Periksa laju langkah yang wajar (30-150 SPM)
const avgSR = calculateStrideRate(workout.totalStrides, workout.totalTime);
if (avgSR < 30 || avgSR > 150) {
issues.push(`Laju langkah tidak biasa: ${Math.round(avgSR)} SPM`);
}
// Periksa segmen yang hilang (celah waktu)
if (workout.segments && workout.segments.length > 1) {
for (let i = 1; i < workout.segments.length; i++) {
const gap = workout.segments[i].startTime -
(workout.segments[i-1].startTime + workout.segments[i-1].duration);
if (gap > 300) { // celah 5 menit
issues.push(`Celah besar terdeteksi antara segmen ${i} dan ${i+1}`);
}
}
}
return {
isValid: issues.length === 0,
issues
};
}
// Contoh:
const workout = {
totalDistance: 2000,
totalTime: 1800, // 30 menit
totalStrides: 800,
segments: [/* data kilometer */]
};
const validation = validateWorkoutData(workout);
// Mengembalikan: { isValid: true, issues: [] }
Fungsi Pembantu
Utilitas Konversi Waktu
Implementasi JavaScript:
// Konversi mm:ss ke detik
function timeToSeconds(timeString) {
const parts = timeString.split(':');
return parseInt(parts[0]) * 60 + parseInt(parts[1]);
}
// Konversi detik ke mm:ss
function secondsToTime(seconds) {
const minutes = Math.floor(seconds / 60);
const secs = Math.round(seconds % 60);
return `${minutes}:${secs.toString().padStart(2, '0')}`;
}
// Konversi detik ke 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')}`;
}
// Contoh:
timeToSeconds("1:33"); // Mengembalikan: 93
secondsToTime(93); // Mengembalikan: "1:33"
secondsToTimeDetailed(3665); // Mengembalikan: "1:01:05"
Sumber Implementasi
Semua rumus di halaman ini siap digunakan dan telah divalidasi terhadap literatur ilmiah. Gunakan untuk alat analitik kustom, verifikasi, atau pemahaman yang lebih mendalam tentang kalkulasi performa lari.
💡 Praktik Terbaik
- Validasi input: Periksa rentang yang wajar sebelum menghitung
- Tangani kasus ekstrem: Pembagian dengan nol, nilai negatif, data null
- Pembulatan yang tepat: CTL/ATL/TSB ke 1 desimal, sTSS ke bilangan bulat
- Simpan presisi: Pertahankan presisi penuh di database, bulatkan untuk tampilan
- Uji secara menyeluruh: Gunakan data yang sudah diverifikasi untuk memvalidasi kalkulasi