/** * @param \Runalyze\Data\Laps\Lap $Lap * @param array $AdditionalData */ protected function addVDOTToDataFrom(Lap $Lap, array &$AdditionalData) { $VDOT = new Calculation\JD\VDOT(); $VDOT->fromPaceAndHR($Lap->distance()->kilometer(), $Lap->duration()->seconds(), $Lap->HRavg()->inPercent() / 100); if ($VDOT->value() > 0) { $AdditionalData[Activity\Entity::VDOT] = $VDOT->value(); } }
/** * Calculate VDOT by heart rate * @param float $distance [optional] * @return float */ public function calculateVDOTbyHeartRate($distance = null) { if (is_null($distance)) { $distance = $this->Activity->distance(); } $VDOT = new JD\VDOT(); $VDOT->fromPaceAndHR($distance, $this->Activity->duration(), $this->Activity->hrAvg() / Configuration::Data()->HRmax()); return $VDOT->value(); }
/** * Constructor * @param array $data */ public function __construct(array $data) { $this->Data = $data; $this->Activity = new Activity\Object($data); $this->Shape = $this->loadShape($data['time']); VDOT::setPrecision(2); VDOTCorrector::setGlobalFactor(Configuration::Data()->vdotFactor()); }
/** * Init calculations */ protected function runCalculations() { foreach ($this->Distances as $km) { $Prognosis = $this->PrognosisObject->inSeconds($km); $PB = new PersonalBest($km, DB::getInstance(), false); $PB->lookupWithDetails(); $VDOTprognosis = new VDOT(); $VDOTprognosis->fromPace($km, $Prognosis); $VDOTpb = new VDOT(); $VDOTpb->fromPace($km, $PB->seconds()); $PacePrognosis = new Pace($Prognosis, $km, Pace::MIN_PER_KM); $PacePB = new Pace($PB->seconds(), $km, Pace::MIN_PER_KM); $DateWithLink = Ajax::trainingLink($PB->activityId(), date('d.m.Y', $PB->timestamp()), true); $this->Prognoses[] = array('distance' => Distance::format($km, $km <= 3), 'prognosis' => Duration::format($Prognosis), 'prognosis-pace' => $PacePrognosis->valueWithAppendix(), 'prognosis-vdot' => $VDOTprognosis->uncorrectedValue(), 'diff' => !$PB->exists() ? '-' : ($PB->seconds() > $Prognosis ? '+ ' : '- ') . Duration::format(abs(round($PB->seconds() - $Prognosis))), 'diff-class' => $PB->seconds() > $Prognosis ? 'plus' : 'minus', 'pb' => $PB->seconds() > 0 ? Duration::format($PB->seconds()) : '-', 'pb-pace' => $PB->seconds() > 0 ? $PacePB->valueWithAppendix() : '-', 'pb-vdot' => $PB->seconds() > 0 ? $VDOTpb->uncorrectedValue() : '-', 'pb-date' => $PB->seconds() > 0 ? $DateWithLink : '-'); } }
/** * Apply * @param \Runalyze\Calculation\JD\VDOT $value */ public function applyTo(VDOT $value) { $value->multiply($this->Factor); }
/** * Get fieldset for paces * @return \FormularFieldset */ public function getFieldsetPaces() { $Table = '<table class="fullwidth zebra-style"> <thead> <tr> <th>' . __('Name') . '</th> <th class="small">' . __('Pace') . '</th> <th class="small">' . __('Description') . '</th> </tr> </thead> <tbody>'; $VDOT = new VDOT(Configuration::Data()->vdot()); foreach ($this->getArrayForPaces() as $Pace) { $Table .= '<tr> <td class="b">' . $Pace['short'] . '</td> <td class=""><em>' . Duration::format($VDOT->paceAt($Pace['limit-low'] / 100)) . '</em> - <em>' . Duration::format($VDOT->paceAt($Pace['limit-high'] / 100)) . '</em>/km</td> <td class="">' . $Pace['description'] . '</td> </tr>'; } $Table .= ' </tbody> </table>'; $Fieldset = new FormularFieldset(__('Training paces')); $Fieldset->addBlock($Table); $Fieldset->addInfo(__('These paces are based on Jack Daniels\' recommendation.')); return $Fieldset; }
/** * Guess heart rate * @param float $distance * @param int $seconds * @return float */ protected function guessHR($distance, $seconds) { if (self::$VDOTshape <= 0 || $seconds == 0) { return 0.5; } $Shape = new VDOT(self::$VDOTshape); $speed = 60 * 1000 * $distance / $seconds; $hr = VDOT::HRat($speed / $Shape->speed()); return $hr; }
/** * Display with corrector */ protected function displayWithElevation() { if ($this->Context->hasRoute() && ($this->Context->route()->elevationUp() > 0 || $this->Context->route()->elevationDown())) { $up = $this->Context->route()->elevationUp(); $down = $this->Context->route()->elevationDown(); } else { $up = $this->Context->activity()->elevation(); $down = $up; } $Modifier = new Elevation\DistanceModifier($this->Context->activity()->distance(), $up, $down, Configuration::Vdot()); $VDOT = new JD\VDOT(0, new JD\VDOTCorrector(Configuration::Data()->vdotFactor())); $VDOT->fromPaceAndHR($Modifier->correctedDistance(), $this->Context->activity()->duration(), $this->Context->activity()->hrAvg() / Configuration::Data()->HRmax()); $Fieldset = new FormularFieldset(__('Correction: considering elevation')); $Fieldset->setHtmlCode(' <p class="warning small ' . (Configuration::Vdot()->useElevationCorrection() ? 'hide' : '') . '"> ' . __('This correction method is currently unused.') . ' </p> <div class="w50"> <label>' . __('Up/Down') . '</label> <span class="as-input">+' . $up . '/-' . $down . ' m</span> </div> <div class="w50 double-height-right"> <label>⇒ ' . __('VDOT') . '</label> <span class="as-input ' . (!Configuration::Vdot()->useElevationCorrection() ? '' : 'highlight') . '">' . $VDOT->value() . '</span> </div> <div class="w50"> <label>' . __('Influence') . '</label> <span class="as-input">' . sprintf("%+d", 1000 * $Modifier->additionalDistance()) . 'm = ' . Distance::format($Modifier->correctedDistance(), false, 3) . '</span> </div> '); $Fieldset->display(); }
/** * Get fieldset for paces * @return \FormularFieldset */ public function getFieldsetPaces() { $Table = '<table class="fullwidth zebra-style"> <thead> <tr> <th>' . __('Name') . '</th> <th class="small">' . __('Pace') . '</th> <th class="small">' . __('Description') . '</th> </tr> </thead> <tbody>'; $VDOT = new VDOT(Configuration::Data()->vdot()); $PaceObject = new Runalyze\Activity\Pace(0, 1, SportFactory::getSpeedUnitFor(Configuration::General()->runningSport())); foreach ($this->getArrayForPaces() as $Pace) { $Table .= '<tr> <td class="b">' . $Pace['short'] . '</td> <td class=""><em>' . $PaceObject->setTime($VDOT->paceAt($Pace['limit-high'] / 100))->value() . '</em> - <em>' . $PaceObject->setTime($VDOT->paceAt($Pace['limit-low'] / 100))->value() . '</em>' . $PaceObject->appendix() . '</td> <td class="">' . $Pace['description'] . '</td> </tr>'; } $Table .= ' </tbody> </table>'; $Fieldset = new FormularFieldset(__('Training paces')); $Fieldset->addBlock($Table); $Fieldset->addInfo(__('These paces are based on Jack Daniels\' recommendation.')); return $Fieldset; }
/** * Calculate prognosis for given VDOT * @see \Runalyze\Calculation\JD\VDOT::formula * @param $VDOTtoReach VDOT * @param $km Distance [km] * @return int Time [s] */ public static function prognosisFor($VDOTtoReach, $km = 5) { if ($VDOTtoReach == 0) { return 0; } $Bisection = new Bisection($VDOTtoReach, round(2 * 60 * $km), round(10 * 60 * $km), function ($seconds) use($km) { return VDOT::formula($km, $seconds); }); return $Bisection->findValue(); }
/** * Init calculations */ protected function runCalculations() { if (!$this->PrognosisObject->isValid()) { return; } foreach ($this->Distances as $km) { $Prognosis = $this->PrognosisObject->inSeconds($km); $PB = new PersonalBest($km, DB::getInstance(), false); $PB->lookupWithDetails(); $VDOTprognosis = new VDOT(); $VDOTprognosis->fromPace($km, $Prognosis); $VDOTpb = new VDOT(); $VDOTpb->fromPace($km, $PB->seconds()); $PacePrognosis = new Pace($Prognosis, $km, SportFactory::getSpeedUnitFor(Configuration::General()->runningSport())); $PacePB = new Pace($PB->seconds(), $km, SportFactory::getSpeedUnitFor(Configuration::General()->runningSport())); $DateWithLink = Ajax::trainingLink($PB->activityId(), date('d.m.Y', $PB->timestamp()), true); $this->Prognoses[] = array('distance' => (new Distance($km))->stringAuto(), 'prognosis' => Duration::format($Prognosis), 'prognosis-pace' => $PacePrognosis->valueWithAppendix(), 'prognosis-vdot' => $VDOTprognosis->uncorrectedValue(), 'diff' => !$PB->exists() ? '-' : ($PB->seconds() > $Prognosis ? '+ ' : '- ') . Duration::format(abs(round($PB->seconds() - $Prognosis))), 'diff-class' => $PB->seconds() > $Prognosis ? 'plus' : 'minus', 'pb' => $PB->seconds() > 0 ? Duration::format($PB->seconds()) : '-', 'pb-pace' => $PB->seconds() > 0 ? $PacePB->valueWithAppendix() : '-', 'pb-vdot' => $PB->seconds() > 0 ? $VDOTpb->uncorrectedValue() : '-', 'pb-date' => $PB->seconds() > 0 ? $DateWithLink : '-'); } }
<?php use Runalyze\Calculation\JD\VDOT; use Runalyze\Configuration; use Runalyze\Activity\Duration; $VDOT = new VDOT(); ?> <table id="jd-tables-prognosis" class="zebra-style c" style="width: 700px;"> <thead> <tr> <th>VDOT</th> <?php foreach (array_keys($this->Paces) as $key) { ?> <th><?php echo $key; ?> </th> <?php } ?> </tr> </thead> <tbody> <?php foreach ($this->Range as $value) { ?> <?php $VDOT->setValue($value); ?>