Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(math): Flesh out vector2d operators #207

Merged
merged 1 commit into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/math/example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ set(EXTRA_COMPONENT_DIRS

set(
COMPONENTS
"main esptool_py format math"
"main esptool_py logger math"
CACHE STRING
"List of components to include"
)
Expand Down
58 changes: 43 additions & 15 deletions components/math/example/main/math_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@

#include "bezier.hpp"
#include "fast_math.hpp"
#include "format.hpp"
#include "gaussian.hpp"
#include "logger.hpp"
#include "range_mapper.hpp"
#include "vector2d.hpp"

using namespace std::chrono_literals;

extern "C" void app_main(void) {
fmt::print("bezier:\n");
espp::Logger logger({.tag = "math_example", .level = espp::Logger::Verbosity::INFO});
logger.info("=== bezier ===");
{
//! [bezier example]
using Bezier = espp::Bezier<espp::Vector2f>;
Expand All @@ -35,7 +36,7 @@ extern "C" void app_main(void) {
//! [bezier example]
}

fmt::print("fast_math:\n");
logger.info("=== fast math ===");
{
//! [fast_ln example]
float x = 3.0f;
Expand Down Expand Up @@ -73,7 +74,7 @@ extern "C" void app_main(void) {
//! [fast_cos example]
}

fmt::print("Gaussian:\n");
logger.info("=== gaussian ===");
{
//! [gaussian example]
std::array<float, 4> gammas = {
Expand Down Expand Up @@ -111,7 +112,7 @@ extern "C" void app_main(void) {
//! [gaussian example]
}

fmt::print("RangeMapper:\n");
logger.info("=== range mapper ===");
{
//! [range_mapper example]
// Default will have output range [-1, 1]
Expand Down Expand Up @@ -164,26 +165,52 @@ extern "C" void app_main(void) {
//! [range_mapper example]
}

fmt::print("Vector2d:\n");
logger.info("=== vector2d ===");
{
//! [vector2d example]
fmt::print("--- uint8_t vector ---\n");
espp::Vector2u8 v8(2, 3);
fmt::print("original: {}\n", v8);
auto v8_2 = v8;
v8 = uint8_t(2) * v8; // NOTE: need explicit cast to avoid ambiguity with auto type
v8 /= 2;
v8 += espp::Vector2u8(0, 1);
v8 -= espp::Vector2u8(0, 1);
fmt::print("should be same: {}, {}\n", v8, v8_2);
// for good measure, print all the comparisons
fmt::print(" v == v2: {}\n", v8 == v8_2);
fmt::print(" v != v2: {}\n", v8 != v8_2);
fmt::print(" v < v2: {}\n", v8 < v8_2);
fmt::print(" v <= v2: {}\n", v8 <= v8_2);
fmt::print(" v > v2: {}\n", v8 > v8_2);
fmt::print(" v >= v2: {}\n", v8 >= v8_2);
fmt::print("magnitude: {}\n", v8.magnitude());
fmt::print("normalized: {}\n", v8.normalized());

fmt::print("--- float vector ---\n");
espp::Vector2f v(1, 1);
fmt::print("original: {}\n", v);
auto v2 = v;
v = 2.0f * v;
v /= 2.0f;
v += espp::Vector2f(0, 1);
v -= espp::Vector2f(0, 1);
auto v2 = v;
fmt::print("should be same: {}\n", v);
fmt::print("should be same: {}\n", v2);
fmt::print("should be same: {}, {}\n", v, v2);
// for good measure, print all the comparisons
fmt::print(" v == v2: {}\n", v == v2);
fmt::print(" v != v2: {}\n", v != v2);
fmt::print(" v < v2: {}\n", v < v2);
fmt::print(" v <= v2: {}\n", v <= v2);
fmt::print(" v > v2: {}\n", v > v2);
fmt::print(" v >= v2: {}\n", v >= v2);
fmt::print("magnitude: {}\n", v.magnitude());
fmt::print("normalized: {}\n", v.normalized());
fmt::print("norm mag: {}\n", v.normalized().magnitude());
fmt::print("rotated pi/2: {}\n", v.rotated(M_PI_2));
//! [vector2d example]
}

fmt::print("Lerp:\n");
logger.info("=== Linear Interpolation ===");
{
//! [lerp example]
// simple lerp
Expand All @@ -206,27 +233,28 @@ extern "C" void app_main(void) {
//! [lerp example]
}

fmt::print("Piecewise Linear:\n");
logger.info("=== Piecewise Linear Interpolation ===");
{
//! [piecewise linear example]
std::vector<std::pair<float, float>> points = {
// clang-format off
// battery voltage (mV), battery percent (%)
{3500, 0},
{3750, 25},
{3700, 30},
{4000, 50},
{4250, 75},
{4350, 75},
{4500, 100},
// clang-format on
};
fmt::print("points: {}\n", points);
for (int i = 3000; i < 5000; i += 100) {
float percent = espp::piecewise_linear(points, (float)i);
fmt::print("battery voltage: {} mV -> {}%\n", i, percent);
fmt::print("battery voltage: {} mV -> {:.2f} %\n", i, percent);
}
//! [piecewise linear example]
}

fmt::print("Math example complete!\n");
logger.info("Math example complete!");

while (true) {
std::this_thread::sleep_for(1s);
Expand Down
43 changes: 30 additions & 13 deletions components/math/include/vector2d.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,32 @@ template <typename T> class Vector2d {
*/
void y(T v) { y_ = v; }

/**
* @brief Spaceship operator for comparing two vectors.
* @param other The vector to compare against.
* @return -1 if this vector is less than \p other, 0 if they are equal, 1 if
* this vector is greater than \p other.
*/
int operator<=>(const Vector2d &other) const {
if (x_ < other.x_) {
return -1;
} else if (x_ > other.x_) {
return 1;
} else if (y_ < other.y_) {
return -1;
} else if (y_ > other.y_) {
return 1;
}
return 0;
}

/**
* @brief Equality operator for comparing two vectors.
* @param other The vector to compare against.
* @return True if the vectors are equal, false otherwise.
*/
bool operator==(const Vector2d &other) const { return x_ == other.x_ && y_ == other.y_; }

/**
* @brief Index operator for vector elements.
* @note Returns a mutable reference to the element.
Expand Down Expand Up @@ -253,23 +279,14 @@ typedef Vector2d<int> Vector2i; ///< Typedef for integer 2D vectors.
typedef Vector2d<uint8_t> Vector2u8; ///< Typedef for 8 bit integer 2D vectors.

/**
* @brief Operator overload for scaling a vector v by a floating point value f.
* @brief Operator overload for scaling a vector v by a factor f.
* @param f Scaling factor.
* @param v Vector to be scaled.
* @return Scaled vector (v*f).
*/
[[maybe_unused]] static Vector2f operator*(float f, const Vector2f &v) {
return espp::Vector2f(v.x() * f, v.y() * f);
}

/**
* @brief Compare if two vectors are equal.
* @param lhs Left hand side vector
* @param rhs Right hand side vector
* @return True if their x and y are equal, false otherwise.
*/
[[maybe_unused]] static bool operator==(const Vector2f &lhs, const Vector2f &rhs) {
return lhs.x() == rhs.x() && lhs.y() == rhs.y();
[[maybe_unused]] static auto operator*(auto f, const auto &v) {
// swap the order so we can use the templated operator* function
return v * f;
}

} // namespace espp
Expand Down
Loading