Skip to content

Commit dada28f

Browse files
committed
Create lerp
1 parent 2a218d9 commit dada28f

File tree

3 files changed

+128
-1
lines changed

3 files changed

+128
-1
lines changed

src/Robocode/Header.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
#include <algorithm>
44
#include <array>
5-
#include <cassert>
65
#include <cmath>
76
#include <complex>
87
#include <cstdint>
@@ -12,11 +11,13 @@
1211
#include <memory>
1312
#include <numbers>
1413
#include <numeric>
14+
#include <optional>
1515
#include <span>
1616
#include <stdexcept>
1717
#include <string>
1818
#include <utility>
1919
#include <vector>
2020

2121
#include <Robocode/Assert.h>
22+
#include <Robocode/Lerp.h>
2223
#include <Robocode/Math.h>

src/Robocode/Lerp.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#include <Robocode/Lerp.h>
2+
3+
Lerp::Lerp(const double v, const std::span<const double> x, const std::optional<double> z)
4+
{
5+
if (x.empty())
6+
{
7+
throw std::invalid_argument("Vector x must be non-empty!");
8+
}
9+
10+
config.s = x.size();
11+
config.z = z;
12+
13+
if (v <= x.front())
14+
{
15+
config.u = -1;
16+
return;
17+
}
18+
19+
if (v >= x.back())
20+
{
21+
config.u = +1;
22+
return;
23+
}
24+
25+
auto b = std::lower_bound(x.begin(), x.end(), v);
26+
27+
if (b == x.begin())
28+
{
29+
config.u = -1;
30+
return;
31+
}
32+
33+
if (b == x.end())
34+
{
35+
config.u = +1;
36+
return;
37+
}
38+
39+
ptrdiff_t d = std::distance(x.begin(), b);
40+
ptrdiff_t i = d - 1;
41+
ptrdiff_t j = i + 1;
42+
43+
double x0 = x[i];
44+
double x1 = x[j];
45+
double t = (v - x0) / (x1 - x0);
46+
47+
config.i = i;
48+
config.j = j;
49+
config.t = t;
50+
}
51+
52+
Lerp::Lerp(const Lerp& other) :
53+
config(other.config)
54+
{
55+
}
56+
57+
Lerp& Lerp::operator=(const Lerp& other)
58+
{
59+
if (this != &other)
60+
{
61+
config = other.config;
62+
}
63+
64+
return *this;
65+
}
66+
67+
double Lerp::operator()(const std::span<const double> y) const
68+
{
69+
const auto& [i, j, s, t, u, z] = config;
70+
71+
if (y.size() != s)
72+
{
73+
throw std::invalid_argument("Vectors x and y must be the same size!");
74+
}
75+
76+
if (u < 0)
77+
{
78+
return z.value_or(y.front());
79+
}
80+
else if (u > 0)
81+
{
82+
return z.value_or(y.back());
83+
}
84+
else
85+
{
86+
double y0 = y[i];
87+
double y1 = y[j];
88+
89+
// y0 + t * (y1 - y0)
90+
return std::lerp(y0, y1, t);
91+
}
92+
}

src/Robocode/Lerp.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#include <algorithm>
4+
#include <cmath>
5+
#include <cstdint>
6+
#include <iterator>
7+
#include <optional>
8+
#include <span>
9+
10+
class Lerp final
11+
{
12+
13+
public:
14+
15+
Lerp(){};
16+
Lerp(const double v, const std::span<const double> x, const std::optional<double> z = std::nullopt);
17+
Lerp(const Lerp& other);
18+
Lerp& operator=(const Lerp& other);
19+
20+
double operator()(const std::span<const double> y) const;
21+
22+
private:
23+
24+
struct
25+
{
26+
ptrdiff_t i, j;
27+
size_t s;
28+
double t;
29+
int u;
30+
std::optional<double> z;
31+
}
32+
config;
33+
34+
};

0 commit comments

Comments
 (0)