Teknikal na Sanggunian at mga Pormula
Kumpletong Matematikong Implementasyon
Gabay sa Implementasyon
Ang pahinang ito ay nagbibigay ng mga pormula na maaaring kopyahin at hakbang-hakbang na pamamaraan sa pagkalkula para sa lahat ng Run Analytics metrics. Gamitin ang mga ito para sa custom na implementasyon, beripikasyon, o mas malalim na pag-unawa.
⚠️ Mga Tala sa Implementasyon
- Ang lahat ng oras ay dapat i-convert sa segundo para sa mga kalkulasyon
- Ang pace sa pagtakbo ay kabaligtaran (mas mataas na % = mas mabagal na pace)
- Laging i-validate ang mga input para sa makatwirang saklaw
- Pangasiwaan ang mga edge case (dibisyon sa zero, negatibong halaga)
Pangunahing Sukatan ng Pagganap
Critical Run Speed (CRS)
Pormula:
CRS (m/s) = (D₂ - D₁) / (T₂ - T₁)
CRS Pace/100m (segundo) = (T₄₀₀ - T₂₀₀) / 2
🧪 Interactive na Kalkulador - Subukan ang Pormula
CRS Pace bawat 100m:
1:49
Mga hakbang sa kalkulasyon:
CRS (m/s) = (400 - 200) / (368 - 150) = 0.917 m/s
Pace/100m = 100 / 0.917 = 109 segundo = 1:49
CRS (m/s) = (400 - 200) / (368 - 150) = 0.917 m/s
Pace/100m = 100 / 0.917 = 109 segundo = 1:49
Implementasyon sa JavaScript:
function calculateCRS(distance1, time1, distance2, time2) {
// I-convert ang oras sa segundo kung kinakailangan
const t1 = typeof time1 === 'string' ? timeToSeconds(time1) : time1;
const t2 = typeof time2 === 'string' ? timeToSeconds(time2) : time2;
// Kalkulahin ang CRS sa m/s
const css_ms = (distance2 - distance1) / (t2 - t1);
// Kalkulahin ang pace bawat 100m sa segundo
const pace_per_100m = 100 / css_ms;
// I-convert sa format na 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')}`
};
}
// Halimbawa ng paggamit:
const result = calculateCRS(200, 150, 400, 368);
// Ibinabalik: { css_ms: 0.917, pace_seconds: 109, pace_formatted: "1:49" }
Run Training Stress Score (sTSS)
Kumpletong Pormula:
sTSS = (IF³) × Tagal (oras) × 100
IF = NSS / FTP
NSS = Kabuuang Distansya / Kabuuang Oras (m/min)
🧪 Interactive na Kalkulador - Subukan ang Pormula
Nakalkuladong sTSS:
55
Mga hakbang sa kalkulasyon:
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
Implementasyon sa JavaScript:
function calculateSTSS(distance, timeMinutes, ftpMetersPerMin) {
// Kalkulahin ang Normalized Run Speed
const nss = distance / timeMinutes;
// Kalkulahin ang Intensity Factor
const intensityFactor = nss / ftpMetersPerMin;
// Kalkulahin ang oras
const hours = timeMinutes / 60;
// Kalkulahin ang sTSS gamit ang cubed intensity factor
const stss = Math.pow(intensityFactor, 3) * hours * 100;
return Math.round(stss);
}
// Halimbawa ng paggamit:
const stss = calculateSTSS(3000, 55, 64.5);
// Ibinabalik: 55
// Helper: I-convert ang CRS sa FTP
function cssToFTP(cssPacePer100mSeconds) {
// FTP sa m/min = 100m / (pace sa minuto)
return 100 / (cssPacePer100mSeconds / 60);
}
// Halimbawa: CRS na 1:33 (93 segundo)
const ftp = cssToFTP(93); // Ibinabalik: 64.5 m/min
Kahusayan sa Pagtakbo
Pormula:
Kahusayan sa Pagtakbo = Oras bawat Kilometro (segundo) + Bilang ng Hakbang
Kahusayan sa Pagtakbo₂₅ = (Oras × 25/Haba ng Track) + (Hakbang × 25/Haba ng Track)
🧪 Interactive na Kalkulador - Subukan ang Pormula
Iskor ng Kahusayan sa Pagtakbo:
35
Kalkulasyon:
Kahusayan sa Pagtakbo = 20s + 15 hakbang = 35
Kahusayan sa Pagtakbo = 20s + 15 hakbang = 35
Implementasyon sa JavaScript:
function calculateRunning Efficiency(timeSeconds, strideCount) {
return timeSeconds + strideCount;
}
function calculateNormalizedRunning Efficiency(timeSeconds, strideCount, trackLength) {
const normalizedTime = timeSeconds * (25 / trackLength);
const normalizedStrides = strideCount * (25 / trackLength);
return normalizedTime + normalizedStrides;
}
// Halimbawa:
const swolf = calculateRunning Efficiency(20, 15);
// Ibinabalik: 35
const swolf50m = calculateNormalizedRunning Efficiency(40, 30, 50);
// Ibinabalik: 35 (normalized sa 25m)
Mekanika ng Hakbang
Stride Rate (SR)
Pormula:
SR = 60 / Oras ng Cycle (segundo)
SR = (Bilang ng Hakbang / Oras sa segundo) × 60
🧪 Interactive na Kalkulador - Subukan ang Pormula
Stride Rate (SPM):
72
Kalkulasyon:
SR = (30 / 25) × 60 = 72 SPM
SR = (30 / 25) × 60 = 72 SPM
Implementasyon sa JavaScript:
function calculateStrideRate(strideCount, timeSeconds) {
return (strideCount / timeSeconds) * 60;
}
// Halimbawa:
const sr = calculateStrideRate(30, 25);
// Ibinabalik: 72 SPM
Distansya bawat Hakbang (DPS)
Pormula:
DPS = Distansya / Bilang ng Hakbang
DPS = Distansya / (SR / 60)
Implementasyon sa JavaScript:
function calculateDPS(distance, strideCount, pushoffDistance = 0) {
const effectiveDistance = distance - pushoffDistance;
return effectiveDistance / strideCount;
}
// Halimbawa (25m track, 5m push-off):
const dps = calculateDPS(25, 12, 5);
// Ibinabalik: 1.67 m/hakbang
// Para sa maraming segment:
const dps100m = calculateDPS(100, 48, 4 * 5);
// Ibinabalik: 1.67 m/hakbang (4 segment × 5m push-off)
Bilis mula sa SR at DPS
Pormula:
Bilis (m/s) = (SR / 60) × DPS
Implementasyon sa JavaScript:
function calculateVelocity(strideRate, dps) {
return (strideRate / 60) * dps;
}
// Halimbawa:
const velocity = calculateVelocity(70, 1.6);
// Ibinabalik: 1.87 m/s
Stride Index (SI)
Pormula:
SI = Bilis (m/s) × DPS (m/hakbang)
Implementasyon sa JavaScript:
function calculateStrideIndex(velocity, dps) {
return velocity * dps;
}
// Halimbawa:
const si = calculateStrideIndex(1.5, 1.7);
// Ibinabalik: 2.55
Performance Management Chart (PMC)
Mga Kalkulasyon ng CTL, ATL, TSB
Mga Pormula:
CTL ngayon = CTL kahapon + (TSS ngayon - CTL kahapon) × (1/42)
ATL ngayon = ATL kahapon + (TSS ngayon - ATL kahapon) × (1/7)
TSB = CTL kahapon - ATL kahapon
Implementasyon sa 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;
}
// Kalkulahin ang PMC para sa serye ng mga workout
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;
}
// Halimbawa ng paggamit:
const workouts = [
{ date: '2025-01-01', tss: 50 },
{ date: '2025-01-02', tss: 60 },
{ date: '2025-01-03', tss: 45 },
// ... higit pang mga workout
];
const pmc = calculatePMC(workouts);
// Ibinabalik ang array na may CTL, ATL, TSB para sa bawat araw
Mga Advanced na Kalkulasyon
CRS mula sa Maraming Distansya (Pamamaraang Regression)
Implementasyon sa 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)
};
}
// Halimbawa na may maraming test distance:
const distances = [100, 200, 400, 800];
const times = [65, 150, 340, 720]; // sa segundo
const result = calculateCRSRegression(distances, times);
// Ibinabalik: { css: 1.18, anaerobic_capacity: 15.3 }
Intensity Factor mula sa Pace
Implementasyon sa JavaScript:
function calculateIntensityFactor(actualPace100m, thresholdPace100m) {
// I-convert ang pace sa bilis (m/s)
const actualSpeed = 100 / actualPace100m;
const thresholdSpeed = 100 / thresholdPace100m;
return actualSpeed / thresholdSpeed;
}
// Halimbawa:
const if_value = calculateIntensityFactor(110, 93);
// Ibinabalik: 0.845 (tumatakbo sa 84.5% ng threshold)
Pagsusuri ng Consistency ng Pace
Implementasyon sa 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 ? "Napakahusay" :
coefficientOfVariation < 10 ? "Mahusay" :
coefficientOfVariation < 15 ? "Katamtaman" : "Pabagu-bago"
};
}
// Halimbawa:
const segments = [
{ distance: 100, time: 70 },
{ distance: 100, time: 72 },
{ distance: 100, time: 71 },
// ...
];
const analysis = analyzePaceConsistency(segments);
// Ibinabalik: { avgPace: 1.41, stdDev: 0.02, coefficientOfVariation: 1.4, consistency: "Napakahusay" }
Pagtuklas ng Pagod mula sa Bilang ng Hakbang
Implementasyon sa 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 ? "Kaunti" :
strideCountIncrease < 10 ? "Katamtaman" :
strideCountIncrease < 20 ? "Makabuluhan" : "Matindi"
};
}
// Halimbawa:
const segments = [
{ strideCount: 14 }, { strideCount: 14 }, { strideCount: 15 },
{ strideCount: 15 }, { strideCount: 16 }, { strideCount: 16 },
{ strideCount: 17 }, { strideCount: 18 }, { strideCount: 18 }
];
const fatigue = detectFatigue(segments);
// Ibinabalik: { firstThirdAvg: 14.3, lastThirdAvg: 17.7, percentIncrease: 23.8, fatigueLevel: "Matindi" }
Pagpapatunay ng Data
Pagsusuri ng Kalidad ng Data ng Workout
Implementasyon sa JavaScript:
function validateWorkoutData(workout) {
const issues = [];
// Suriin ang makatwirang saklaw ng pace (1:00-5:00 bawat 100m)
const avgPace = (workout.totalTime / workout.totalDistance) * 100;
if (avgPace < 60 || avgPace > 300) {
issues.push(`Hindi pangkaraniwang average pace: ${Math.round(avgPace)}s bawat 100m`);
}
// Suriin ang makatwirang bilang ng hakbang (10-50 bawat 25m)
const avgStridesPer25m = (workout.totalStrides / workout.totalDistance) * 25;
if (avgStridesPer25m < 10 || avgStridesPer25m > 50) {
issues.push(`Hindi pangkaraniwang bilang ng hakbang: ${Math.round(avgStridesPer25m)} bawat 25m`);
}
// Suriin ang makatwirang stride rate (30-150 SPM)
const avgSR = calculateStrideRate(workout.totalStrides, workout.totalTime);
if (avgSR < 30 || avgSR > 150) {
issues.push(`Hindi pangkaraniwang stride rate: ${Math.round(avgSR)} SPM`);
}
// Suriin ang mga nawawalang segment (mga puwang sa oras)
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 minutong puwang
issues.push(`Malaking puwang na natukoy sa pagitan ng segment ${i} at ${i+1}`);
}
}
}
return {
isValid: issues.length === 0,
issues
};
}
// Halimbawa:
const workout = {
totalDistance: 2000,
totalTime: 1800, // 30 minuto
totalStrides: 800,
segments: [/* data ng kilometro */]
};
const validation = validateWorkoutData(workout);
// Ibinabalik: { isValid: true, issues: [] }
Mga Helper Function
Mga Utility para sa Konbersyon ng Oras
Implementasyon sa JavaScript:
// I-convert ang mm:ss sa segundo
function timeToSeconds(timeString) {
const parts = timeString.split(':');
return parseInt(parts[0]) * 60 + parseInt(parts[1]);
}
// I-convert ang segundo sa mm:ss
function secondsToTime(seconds) {
const minutes = Math.floor(seconds / 60);
const secs = Math.round(seconds % 60);
return `${minutes}:${secs.toString().padStart(2, '0')}`;
}
// I-convert ang segundo sa 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')}`;
}
// Mga halimbawa:
timeToSeconds("1:33"); // Ibinabalik: 93
secondsToTime(93); // Ibinabalik: "1:33"
secondsToTimeDetailed(3665); // Ibinabalik: "1:01:05"
Mga Mapagkukunan para sa Implementasyon
Ang lahat ng pormula sa pahinang ito ay handang gamitin sa produksyon at napatunayan laban sa siyentipikong literatura. Gamitin ang mga ito para sa custom na analytics tool, beripikasyon, o mas malalim na pag-unawa ng mga kalkulasyon sa pagganap sa pagtakbo.
💡 Pinakamahusay na Gawi
- I-validate ang mga input: Suriin ang makatwirang saklaw bago magkalkula
- Pangasiwaan ang mga edge case: Dibisyon sa zero, negatibong halaga, null na data
- I-round nang naaayon: CTL/ATL/TSB sa 1 decimal, sTSS sa integer
- Mag-imbak ng precision: Panatilihin ang buong precision sa database, i-round para sa display
- Subukan nang lubusan: Gamitin ang kilalang mabuting data upang beripikahin ang mga kalkulasyon