summaryrefslogtreecommitdiff
path: root/ride/ride.go
diff options
context:
space:
mode:
Diffstat (limited to 'ride/ride.go')
-rw-r--r--ride/ride.go40
1 files changed, 40 insertions, 0 deletions
diff --git a/ride/ride.go b/ride/ride.go
index f5a92a5..9ce260f 100644
--- a/ride/ride.go
+++ b/ride/ride.go
@@ -3,6 +3,7 @@ package ride
import (
"errors"
"io"
+ "math"
"os"
"time"
@@ -91,6 +92,45 @@ func (r *Ride) ScoreFromKm(start, end float64) float64 {
return Score(r.points, i, j)
}
+func (r *Ride) DifficultyScore() float64 {
+ points := r.points
+ if len(points) < 2 {
+ return 0
+ }
+ last := points[len(points)-1]
+ if last.DistanceM <= 0 {
+ return 0
+ }
+ score := 0.0
+ i := 0
+ for start := 0.0; start < last.DistanceM; start += 100 {
+ end := math.Min(start+100, last.DistanceM)
+ for i < len(points)-1 && points[i+1].DistanceM <= start {
+ i++
+ }
+ startElevation := interpolateElevation(points, i, start)
+ for i < len(points)-1 && points[i+1].DistanceM < end {
+ i++
+ }
+ endElevation := interpolateElevation(points, i, end)
+ slope := (endElevation - startElevation) / (end - start)
+ if slope > 0 {
+ score += (end - start) / 1000 * (slope * 100) * (slope * 100)
+ }
+ }
+ return score
+}
+
+func interpolateElevation(points []Point, i int, distance float64) float64 {
+ if i+1 >= len(points) {
+ return points[i].ElevationM
+ }
+ start := points[i]
+ end := points[i+1]
+ t := (distance - start.DistanceM) / (end.DistanceM - start.DistanceM)
+ return start.ElevationM + t*(end.ElevationM-start.ElevationM)
+}
+
func (r *Ride) ClimbFromDist(startDist, endDist float64) Climb {
start, end := 0, 0
for i, p := range r.points {