Rujukan Teknikal & Formula
Pelaksanaan Matematik Lengkap
Panduan Pelaksanaan
Halaman ini menyediakan formula siap salin dan kaedah pengiraan langkah demi langkah untuk semua metrik Run Analytics. Gunakan untuk pelaksanaan tersuai, pengesahan, atau pemahaman yang lebih mendalam.
⚠️ Nota Pelaksanaan
- Semua masa perlu ditukar kepada saat untuk pengiraan
- Kadar larian adalah songsang (% lebih tinggi = kadar lebih perlahan)
- Sentiasa sahkan input untuk julat yang munasabah
- Kendali kes tepi (pembahagian dengan sifar, nilai negatif)
Metrik Prestasi Teras
Kelajuan Larian Kritikal (CRS)
Formula:
CRS (m/s) = (D₂ - D₁) / (T₂ - T₁)
Kadar CRS (min/km) = 1000 / CRS (m/s) / 60
🧪 Kalkulator Interaktif - Uji Formula
Kadar CRS per km:
4:15
Langkah pengiraan:
CRS (m/s) = (3600 - 1200) / (864 - 252) = 3.922 m/s
Kadar/km = 1000 / 3.922 = 255 saat = 4:15
CRS (m/s) = (3600 - 1200) / (864 - 252) = 3.922 m/s
Kadar/km = 1000 / 3.922 = 255 saat = 4:15
Pelaksanaan JavaScript:
function calculateCRS(distance1, time1, distance2, time2) {
// Tukar masa kepada saat jika perlu
const t1 = typeof time1 === 'string' ? timeToSeconds(time1) : time1;
const t2 = typeof time2 === 'string' ? timeToSeconds(time2) : time2;
// Kira CRS dalam m/s
const css_ms = (distance2 - distance1) / (t2 - t1);
// Kira kadar setiap kilometer dalam saat
const pace_per_km = 1000 / css_ms;
// Tukar kepada format mm:ss
const minutes = Math.floor(pace_per_km / 60);
const seconds = Math.round(pace_per_km % 60);
return {
css_ms: css_ms,
pace_seconds: pace_per_km,
pace_formatted: `${minutes}:${seconds.toString().padStart(2, '0')}`
};
}
// Contoh penggunaan:
const result = calculateCRS(1200, 252, 3600, 864);
// Pulangkan: { css_ms: 3.922, pace_seconds: 255, pace_formatted: "4:15" }Skor Tekanan Latihan Larian (sTSS)
Formula Lengkap:
sTSS = (IF³) × Tempoh (jam) × 100
IF = NSS / Kelajuan CRS
NSS = Jumlah Jarak / Jumlah Masa (m/min)
🧪 Kalkulator Interaktif - Uji Formula
sTSS Dikira:
35
Langkah pengiraan:
NSS = 5000m / 400min = 200.0 m/min
Kelajuan CRS = 1000 / (255/60) = 235.3 m/min
IF = 200.0 / 235.3 = 0.850
sTSS = 0.850³ × (25/60) × 100 = 26
NSS = 5000m / 400min = 200.0 m/min
Kelajuan CRS = 1000 / (255/60) = 235.3 m/min
IF = 200.0 / 235.3 = 0.850
sTSS = 0.850³ × (25/60) × 100 = 26
Pelaksanaan JavaScript:
function calculateSTSS(distance, timeMinutes, thresholdSpeedMetersPerMin) {
// Kira Halaju Larian Dinormalkan (NSS)
const nss = distance / timeMinutes;
// Kira Faktor Intensiti (IF)
const intensityFactor = nss / thresholdSpeedMetersPerMin;
// Kira jam
const hours = timeMinutes / 60;
// Kira sTSS menggunakan faktor intensiti kuasa tiga
const stss = Math.pow(intensityFactor, 3) * hours * 100;
return Math.round(stss);
}
// Contoh penggunaan:
const stss = calculateSTSS(5000, 25, 235.3);
// Pulangkan: 26
// Pembantu: Tukar Kadar CRS kepada Kelajuan Ambang
function crsPaceToSpeed(crsPacePerKmSeconds) {
// Kelajuan dalam m/min = 1000m / (kadar dalam minit)
return 1000 / (crsPacePerKmSeconds / 60);
}
// Contoh: Kadar CRS 4:15 (255 saat)
const thresholdSpeed = crsPaceToSpeed(255); // Pulangkan: 235.3 m/minNisbah Menegak (VR)
Formula:
Nisbah Menegak (%) = (Ayunan Menegak / Panjang Langkah) * 100
🧪 Kalkulator Interaktif - Uji Formula
Nisbah Menegak (VR):
6.8%
Pengiraan:
VR = (8.5 / 125) * 100 = 6.8%
VR = (8.5 / 125) * 100 = 6.8%
Pelaksanaan JavaScript:
function calculateVerticalRatio(verticalOscillationCm, strideLengthM) {
// Tukar panjang langkah kepada cm
const strideLengthCm = strideLengthM * 100;
return (verticalOscillationCm / strideLengthCm) * 100;
}
// Contoh:
const vr = calculateVerticalRatio(8.5, 1.25);
// Pulangkan: 6.8%Berlari Mekanik Langkah
Kidens (Cadence)
Formula:
Kidens = 60 / Masa Kitaran (saat)
Kidens (SPM) = (Bilangan Langkah / Masa dalam saat) × 60
Kidens (SPM):
180
Pengiraan:
Kidens = (45 / 15) × 60 = 180 SPM
Kidens = (45 / 15) × 60 = 180 SPM
Pelaksanaan JavaScript:
function calculateCadence(strideCount, timeSeconds) {
return (strideCount / timeSeconds) * 60;
}
// Contoh:
const cadence = calculateCadence(45, 15);
// Pulangkan: 180 SPMPanjang Langkah (Stride Length)
Formula:
Panjang Langkah (m) = Jarak / Kiraan Langkah
Panjang Langkah (m) = Halaju / (Kidens / 60)
Pelaksanaan JavaScript:
function calculateStrideLength(distance, strideCount) {
return distance / strideCount;
}
// Contoh:
const strideLength = calculateStrideLength(100, 80);
// Pulangkan: 1.25 m/langkahHalaju daripada Kidens dan Panjang Langkah
Formula:
Halaju (m/s) = (Kidens / 60) × Panjang Langkah
Pelaksanaan JavaScript:
function calculateVelocity(cadence, strideLength) {
return (cadence / 60) * strideLength;
}
// Contoh:
const velocity = calculateVelocity(180, 1.25);
// Pulangkan: 3.75 m/sIndeks Langkah (Stride Index)
Formula:
SI = Halaju (m/s) × Panjang Langkah (m)
Pelaksanaan JavaScript:
function calculateStrideIndex(velocity, strideLength) {
return velocity * strideLength;
}
// Contoh:
const si = calculateStrideIndex(3.75, 1.25);
// Pulangkan: 4.69Carta Pengurusan Prestasi (PMC) untuk Berlari
Pengiraan CTL, ATL, TSB
Formula:
CTL hari ini = CTL semalam + (TSS hari ini - CTL semalam) × (1/42)
ATL hari ini = ATL semalam + (TSS hari ini - ATL semalam) × (1/7)
TSB = CTL semalam - ATL semalam
Pelaksanaan 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 dayPengiraan Lanjutan
CRS daripada Pelbagai Jarak (Kaedah Regresi)
Pelaksanaan JavaScript:
function calculateCRSRegression(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 running 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 = calculateCRSRegression(distances, times);
// Returns: { css: 1.18, anaerobic_capacity: 15.3 }Faktor Keamatan daripada Kadar
Pelaksanaan JavaScript:
function calculateIntensityFactor(actualPaceKm, thresholdPaceKm) {
// Tukar kadar kepada kelajuan (m/s)
const actualSpeed = 1000 / actualPaceKm;
const thresholdSpeed = 1000 / thresholdPaceKm;
return actualSpeed / thresholdSpeed;
}
// Contoh:
const if_value = calculateIntensityFactor(300, 255);
// Pulangkan: 0.850 (berlari pada 85.0% daripada ambang)Analisis Ketekalan Kadar
Pelaksanaan 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 ? "Cemerlang" :
coefficientOfVariation < 10 ? "Baik" :
coefficientOfVariation < 15 ? "Sederhana" : "Berubah-ubah"
};
}
// Example:
const segments = [
{ distance: 100, time: 70 },
{ distance: 100, time: 72 },
{ distance: 100, time: 71 },
// ...
];
const analysis = analyzePaceConsistency(segments);
// Returns: { avgPace: 1.41, stdDev: 0.02, coefficientOfVariation: 1.4, consistency: "Cemerlang" }Pengesanan Keletihan daripada Kiraan Langkah
Pelaksanaan 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 ? "Minima" :
strideCountIncrease < 10 ? "Sederhana" :
strideCountIncrease < 20 ? "Ketara" : "Teruk"
};
}
// Example:
const segments = [
{ strideCount: 14 }, { strideCount: 14 }, { strideCount: 15 },
{ strideCount: 15 }, { strideCount: 16 }, { strideCount: 16 },
{ strideCount: 17 }, { strideCount: 18 }, { strideCount: 18 }
];
const fatigue = detectFatigue(segments);
// Returns: { firstThirdAvg: 14.3, lastThirdAvg: 17.7, percentIncrease: 23.8, fatigueLevel: "Teruk" }Pengesahan Data
Pemeriksaan Kualiti Data Latihan
Pelaksanaan JavaScript:
function validateWorkoutData(workout) {
const issues = [];
// Periksa julat kadar yang munasabah (3:00-10:00 per km)
const avgPace = (workout.totalTime / workout.totalDistance) * 1000;
if (avgPace < 180 || avgPace > 600) {
issues.push(`Kadar purata luar biasa: ${Math.round(avgPace)}s per km`);
}
// Periksa julat kidens yang munasabah (120-220 SPM)
const avgCadence = (workout.totalStrides / workout.totalTime) * 60;
if (avgCadence < 120 || avgCadence > 220) {
issues.push(`Kidens luar biasa: ${Math.round(avgCadence)} SPM`);
}
// Check for missing segments (gaps in time)
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) { // 5 minute gap
issues.push(`Jurang besar dikesan antara segmen ${i} dan ${i+1}`);
}
}
}
return {
isValid: issues.length === 0,
issues
};
}
// Contoh:
const workout = {
totalDistance: 5000,
totalTime: 1275, // 21:15
totalStrides: 3825,
segments: [/* data kilometer */]
};
const validation = validateWorkoutData(workout);
// Pulangkan: { isValid: true, issues: [] }Fungsi Pembantu
Utiliti Penukaran Masa
Pelaksanaan 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"Sumber Pelaksanaan
Semua formula di halaman ini bersedia untuk pengeluaran dan disahkan terhadap kesusasteraan saintifik. Gunakan untuk alat analitik tersuai, pengesahan, atau pemahaman yang lebih mendalam tentang pengiraan prestasi larian.
💡 Amalan Terbaik
- Sahkan input: Semak julat yang munasabah sebelum mengira
- Kendali kes tepi: Pembahagian dengan sifar, nilai negatif, data null
- Bulatkan dengan sesuai: CTL/ATL/TSB kepada 1 perpuluhan, sTSS kepada integer
- Simpan ketepatan: Kekalkan ketepatan penuh dalam pangkalan data, bulatkan untuk paparan
- Uji dengan teliti: Gunakan data yang diketahui baik untuk mengesahkan pengiraan
