running-tools

A collection of tools for runners and their coaches
git clone https://git.ashermorgan.net/running-tools/
Log | Files | Refs | README

commit e4436e7e7951ecb5b60731401729bc7d87f1eb68
parent 87bd0b11a131c418c66a3a7901cb33aa73f674cf
Author: ashermorgan <59518073+ashermorgan@users.noreply.github.com>
Date:   Sun, 22 Aug 2021 11:50:02 -0700

Add race prediction utilities

Diffstat:
Asrc/utils/races.js | 46++++++++++++++++++++++++++++++++++++++++++++++
Atests/unit/races.spec.js | 27+++++++++++++++++++++++++++
2 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/src/utils/races.js b/src/utils/races.js @@ -0,0 +1,46 @@ +/** + * Predict a race time using Pete Riegel's Formula + * https://en.wikipedia.org/wiki/Peter_Riegel + * @param {Number} d1 The distance of the input race (in meters) + * @param {Number} t1 The finish time of the input race (in seconds) + * @param {Number} d2 The distance of the output race (in meters) + * @param {Number} c The value of the exponent in the equation + * @returns {Number} The predicted time for the output race (in seconds) + */ +function RiegelFormula(d1, t1, d2, c = 1.06) { + return t1 * ((d2 / d1) ** c); +} + +/** + * Predict a race time using Dave Cameron's Formula + * https://www.cs.uml.edu/~phoffman/cammod.html + * @param {Number} d1 The distance of the input race (in meters) + * @param {Number} t1 The finish time of the input race (in seconds) + * @param {Number} d2 The distance of the output race (in meters) + * @returns {Number} The predicted time for the output race (in seconds) + */ +function CameronFormula(d1, t1, d2) { + const a = 13.49681 - (0.000030363 * d1) + (835.7114 / (d1 ** 0.7905)); + const b = 13.49681 - (0.000030363 * d2) + (835.7114 / (d2 ** 0.7905)); + return (t1 / d1) * (a / b) * d2; +} + +/** + * Predict a race time by averaging the results of different formulas + * @param {Number} d1 The distance of the input race (in meters) + * @param {Number} t1 The finish time of the input race (in seconds) + * @param {Number} d2 The distance of the output race (in meters) + * @param {Number} c The value of the exponent in Pete Riegel's Formula + * @returns {Number} The predicted time for the output race (in seconds) + */ +function AverageFormula(d1, t1, d2, c = 1.06) { + const riegel = RiegelFormula(d1, t1, d2, c); + const cameron = CameronFormula(d1, t1, d2); + return (riegel + cameron) / 2; +} + +export default { + RiegelFormula, + CameronFormula, + AverageFormula, +}; diff --git a/tests/unit/races.spec.js b/tests/unit/races.spec.js @@ -0,0 +1,27 @@ +import { expect } from 'chai'; +import raceUtils from '@/utils/races'; + +describe('utils/races.js', () => { + describe('RiegelFormula method', () => { + it('Predictions should be approximately correct', () => { + const result = raceUtils.RiegelFormula(400, 60, 800); + expect(result).to.be.closeTo(125, 0.5); + }); + }); + + describe('CameronFormula method', () => { + it('Predictions should be approximately correct', () => { + const result = raceUtils.CameronFormula(800, 115, 1500); + expect(result).to.be.closeTo(238.48, 0.5); + }); + }); + + describe('AverageFormula method', () => { + it('Predictions should be correct', () => { + const result = raceUtils.AverageFormula(5000, 20 * 60, 10000); + const riegel = raceUtils.RiegelFormula(5000, 20 * 60, 10000); + const cameron = raceUtils.CameronFormula(5000, 20 * 60, 10000); + expect(result).to.equal((riegel + cameron) / 2); + }); + }); +});