RIT VEXU Core API
Loading...
Searching...
No Matches
math_util.h
1#pragma once
2
3#include <algorithm>
4#include <cmath>
5
6#include "math/geometry/translation2d.h"
7
8// we might not have std::clamp
9#ifndef __cpp_lib_clamp
10namespace core {
11template <typename T>
12T clamp(T value, T low, T high) {
13 return std::max(low, std::min(high, value));
14}
15} // namespace core
16#else
17// if we do then use it instead
18namespace core {
19using std::clamp;
20}
21#endif
22
29double lerp(double a, double b, double t) {
30 return a * (1.0 - t) + b * t;
31}
32
39double sign(double x) {
40 if (x < 0) {
41 return -1;
42 }
43 return 1;
44}
45
46double wrap_angle_deg(double input) {
47 double angle = fmod(input, 360);
48 if (angle < 0) {
49 angle += 360;
50 }
51
52 return angle;
53}
54double wrap_angle_rad(double input) {
55 double angle = fmod(input, M_TWOPI);
56 if (angle < 0) {
57 angle += M_TWOPI;
58 }
59
60 return angle;
61}
62
63/*
64Calculates the variance of a set of numbers (needed for linear regression)
65https://en.wikipedia.org/wiki/Variance
66@param values the values for which the variance is taken
67@param mean the average of values
68*/
69double variance(std::vector<double> const& values, double mean) {
70 double total = 0.0;
71 for (int i = 0; i < values.size(); i++) {
72 total += (values[i] - mean) * (values[i] - mean);
73 }
74 return total / (values.size() - 1);
75}
76
77/*
78Calculates the average of a vector of doubles
79@param values the list of values for which the average is taken
80*/
81double mean(std::vector<double> const& values) {
82 double total = 0;
83 for (int i = 0; i < values.size(); i++) {
84 total += values[i];
85 }
86 return total / (double)values.size();
87}
88
89/*
90Calculates the covariance of a set of points (needed for linear regression)
91https://en.wikipedia.org/wiki/Covariance
92
93@param points the points for which the covariance is taken
94@param meanx the mean value of all x coordinates in points
95@param meany the mean value of all y coordinates in points
96*/
97double covariance(std::vector<std::pair<double, double>> const& points,
98 double meanx, double meany) {
99 double covar = 0.0;
100 for (int i = 0; i < points.size(); i++) {
101 covar += (points[i].first - meanx) * (points[i].second - meany);
102 }
103 return covar;
104}
105
106/*
107Calculates the slope and y intercept of the line of best fit for the data
108@param points the points for the data
109*/
110std::pair<double, double> calculate_linear_regression(
111 std::vector<std::pair<double, double>> const& points) {
112 // Purely for convenience and the ability to reuse mean() and variance() - can be easily rewritten to avoid allocating
113 // these if the code is repeatedly called
114 std::vector<double> xs(points.size(), 0.0);
115 std::vector<double> ys(points.size(), 0.0);
116 for (int i = 0; i < points.size(); i++) {
117 xs[i] = points[i].first;
118 ys[i] = points[i].second;
119 }
120
121 double meanx = mean(xs);
122 double meany = mean(ys);
123
124 double slope = covariance(points, meanx, meany) / variance(xs, meanx);
125 double y_intercept = meany - slope * meanx;
126
127 return std::pair<double, double>(slope, y_intercept);
128}
129
130double estimate_path_length(const std::vector<Translation2d>& points) {
131 double dist = 0;
132
133 for (Translation2d p : points) {
134 static Translation2d last_p = p;
135
136 // Ignore the first point
137 if (p == last_p) {
138 continue;
139 }
140
141 dist += p.distance(last_p);
142 last_p = p;
143 }
144
145 return dist;
146}
Definition translation2d.h:22
double distance(const Translation2d &other) const
Definition translation2d.cpp:79