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:
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);
+ });
+ });
+});