المرجع التقني والصيغ
التنفيذ الرياضي الكامل
دليل التنفيذ
توفر هذه الصفحة صيغاً جاهزة للنسخ واللصق، بالإضافة إلى طرق الحساب خطوة بخطوة لجميع مقاييس SwimAnalytics. استخدمها للتطبيقات المخصصة، أو التحقق، أو الفهم الأعمق.
⚠️ ملاحظات التنفيذ
- يجب تحويل جميع الأوقات إلى ثوانٍ للحسابات
- سرعة السباحة معكوسة (نسبة مئوية أكبر = سرعة أبطأ)
- تحقق دائماً من المدخلات للنطاقات المعقولة
- تعامل مع الحالات الحدية (القسمة على صفر، القيم السلبية)
مقاييس الأداء الرئيسية
السرعة الحرجة للسباحة (CSS)
الصيغة:
CSS (m/s) = (D₂ - D₁) / (T₂ - T₁)
CSS السرعة/100م (ثواني) = (T₄₀₀ - T₂₀₀) / 2
🧪 حاسبة تفاعلية - اختبر الصيغة
سرعة CSS لكل 100م:
1:49
خطوات الحساب:
CSS (m/s) = (400 - 200) / (368 - 150) = 0.917 m/s
السرعة/100م = 100 / 0.917 = 109 ثانية = 1:49
CSS (m/s) = (400 - 200) / (368 - 150) = 0.917 m/s
السرعة/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 = 3000م / 55دقيقة = 54.5 م/دقيقة
FTP = 100 / (93/60) = 64.5 م/دقيقة
IF = 54.5 / 64.5 = 0.845
sTSS = 0.845³ × (55/60) × 100 = 55
NSS = 3000م / 55دقيقة = 54.5 م/دقيقة
FTP = 100 / (93/60) = 64.5 م/دقيقة
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/min
SWOLF
الصيغة:
SWOLF = وقت الطول (ثواني) + عدد الضربات
SWOLF₂₅ = (الوقت × 25/طول المسبح) + (الضربات × 25/طول المسبح)
🧪 حاسبة تفاعلية - اختبر الصيغة
نقاط SWOLF:
35
الحساب:
SWOLF = 20ث + 15 ضربة = 35
SWOLF = 20ث + 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
الصيغة:
السرعة (م/ث) = (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 = السرعة (م/ث) × DPS (م/ضربة)
التنفيذ في JavaScript:
function calculateStrokeIndex(velocity, dps) {
return velocity * dps;
}
// Example:
const si = calculateStrokeIndex(1.5, 1.7);
// Returns: 2.55
مخطط إدارة الأداء (PMC)
حسابات CTL، ATL، TSB
الصيغ:
CTL اليوم = CTL الأمس + (TSS اليوم - CTL الأمس) × (1/42)
ATL اليوم = ATL الأمس + (TSS اليوم - ATL الأمس) × (1/7)
TSB = CTL الأمس - ATL الأمس
التنفيذ في 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 ? "ممتاز" :
coefficientOfVariation < 10 ? "جيد" :
coefficientOfVariation < 15 ? "معتدل" : "متغير"
};
}
// 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: "ممتاز" }
كشف الإجهاد من خلال عدد الضربات
التنفيذ في 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 ? "الحد الأدنى" :
strokeCountIncrease < 10 ? "معتدل" :
strokeCountIncrease < 20 ? "كبير" : "شديد"
};
}
// 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: "شديد" }
التحقق من صحة البيانات
التحقق من جودة بيانات التدريب
التنفيذ في 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(`سرعة متوسطة غير عادية: ${Math.round(avgPace)}ث لكل 100م`);
}
// 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(`فجوة كبيرة مكتشفة بين الطولين ${i} و ${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 لمنزلة عشرية واحدة، sTSS لعدد صحيح
- احفظ الدقة: احتفظ بالدقة الكاملة في قاعدة البيانات، دور للعرض
- اختبر بشكل شامل: استخدم بيانات معروفة وصحيحة للتحقق من الحسابات