feat: started vector library

main
Sara 2024-11-15 11:21:59 +01:00
parent af97656cc7
commit f32cc23afd
2 changed files with 202 additions and 0 deletions

101
src/math/vector.cpp Normal file
View File

@ -0,0 +1,101 @@
#include "vector.hpp"
#include <cmath>
#include <algorithm>
#define VECTOR_EPSILON 0.00001f
Vecf::Vecf(float x, float y)
: x{x}, y{y} {}
Vecf::Vecf(Vecf const &&src)
: x{src.x}, y{src.y} {}
Vecf::Vecf(std::initializer_list<float> members)
: x{*members.begin()}
, y{*(members.begin() + 1)} {}
Vecf &Vecf::operator=(Vecf const &src) {
this->x = src.x;
this->y = src.y;
return *this;
}
Vecf &Vecf::operator=(std::initializer_list<float> list) {
this->x = *list.begin();
this->y = *(list.begin() + 1);
return *this;
}
Vecf::operator SDL_FPoint() {
return (SDL_FPoint){this->x, this->y};
}
float Vecf::sqr_distance(Vecf const &from, Vecf const &to) {
float const xdif = std::fabs(to.x - from.x);
float const ydif = std::fabs(to.y - from.y);
return xdif * xdif + ydif * ydif;
}
float Vecf::distance(Vecf const &from, Vecf const &to) {
return std::sqrt(Vecf::sqr_distance(from, to));
}
bool Vecf::equals_approximate(Vecf const &lhs, Vecf const &rhs) {
return std::fabs(lhs.x - rhs.x) < VECTOR_EPSILON && std::fabs(lhs.y - rhs.y) < VECTOR_EPSILON;
}
float Vecf::dot(Vecf const &lhs, Vecf const &rhs) {
return (lhs.x*rhs.x) + (lhs.y*rhs.y);
}
float Vecf::angle_between(Vecf const &lhs, Vecf const &rhs) {
return Vecf::dot(lhs, rhs) / (lhs.magnitude() * rhs.magnitude());
}
Vecf Vecf::lerp(Vecf const &from, Vecf const &to, float t) {
return from + ((to - from) * std::clamp(t, 0.f, 1.f));
}
Vecf Vecf::move_towards(Vecf const &from, Vecf const &to, float delta) {
return Vecf::lerp(from, to, delta / Vecf::distance(from, to));
}
float Vecf::magnitude() const {
return std::sqrt(this->x * this->x + this->y * this->y);
}
float Vecf::sqr_magnitude() const {
return this->x * this->x + this->y * this->y;
}
Vecf Vecf::perpendicular() const {
return {this->y, -this->x};
}
Vecf Vecf::rotate(float t) const {
return{
cosf(t) * this->x - sinf(t) * this->y,
sinf(t) * this->x + cosf(t) * this->y
};
}
Vecf Vecf::normalized() const {
return *this / this->magnitude();
}
Vecf Vecf::reciprocal() const {
return {1.f / this->x, 1.f / this->y};
}
bool Vecf::is_nan() const {
return std::isnan(this->x) || std::isnan(this->y);
}
void Vecf::scale(float x, float y) {
this->x *= x;
this->y *= y;
}
void Vecf::scale(Vecf const &factors) {
this->scale(factors.x, factors.y);
}

101
src/math/vector.hpp Normal file
View File

@ -0,0 +1,101 @@
#ifndef VECTOR_MATH_HPP
#define VECTOR_MATH_HPP
#include <SDL2/SDL_rect.h>
#include <initializer_list>
struct Vecf {
Vecf() = default;
Vecf(float x, float y);
Vecf(std::initializer_list<float> members);
Vecf(Vecf const &&src);
Vecf(Vecf const &src);
~Vecf() = default;
Vecf &operator=(Vecf const &src);
Vecf &operator=(std::initializer_list<float> list);
operator SDL_FPoint();
//! squared distance between two vectors as points. Use for comparing distances efficiently.
static float sqr_distance(Vecf const &from, Vecf const &to);
//! distance between two vectors as points
static float distance(Vecf const &from, Vecf const &to);
//! compare based on an epsilon
static bool equals_approximate(Vecf const &lhs, Vecf const &rhs);
//! scalar member-wise multiplication product
static float dot(Vecf const &lhs, Vecf const &rhs);
//! unsigned angle difference in radians between lhs and rhs
static float angle_between(Vecf const &lhs, Vecf const &rhs);
//! interpolate linearly between two points
static Vecf lerp(Vecf const &from, Vecf const &to, float t);
//! move towards a point by a set unit distance
static Vecf move_towards(Vecf const &from, Vecf const &to, float delta);
//! magnitude (a.k.a length or absolute) of this vector
float magnitude() const;
//! square of the magnitude, use for comparing lengths of vectors efficiently
float sqr_magnitude() const;
//! vector perpendicular to this one
Vecf perpendicular() const;
//! rotate vector by t Radians
Vecf rotate(float t) const;
//! vector pointing in the same direction with a length of 1. Or, vector divided by it's magnitude
Vecf normalized() const;
//! reverse scale of vector
Vecf reciprocal() const;
//! returns true if either the x or y element is NaN
bool is_nan() const;
//! scale vector member-wise
void scale(float x, float y);
//! scale vector member-wise
void scale(Vecf const &factors);
float x{0.f}, y{0.f};
};
static inline
Vecf operator-(Vecf const &v) {
return {-v.x, -v.y};
}
static inline
bool operator==(Vecf const &lhs, Vecf const &rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y;
}
static inline
Vecf operator+(Vecf const &lhs, Vecf const &rhs) {
return Vecf(lhs.x + rhs.x, lhs.y + rhs.y);
}
static inline
Vecf operator-(Vecf const &lhs, Vecf const &rhs) {
return Vecf(lhs.x - rhs.x, lhs.y - rhs.y);
}
static inline
Vecf operator*(Vecf const &v, float f) {
return Vecf(v.x * f, v.y * f);
}
static inline
Vecf operator/(Vecf const &v, float f) {
return Vecf(v.x / f, v.y / f);
}
static inline
Vecf &operator+=(Vecf &lhs, Vecf const &rhs) {
return lhs = lhs + rhs;
}
static inline
Vecf &operator-=(Vecf &lhs, Vecf const &rhs) {
return lhs = lhs - rhs;
}
static inline
Vecf &operator*=(Vecf &lhs, float rhs) {
return (lhs = lhs * rhs);
}
static inline
Vecf &operator/=(Vecf &lhs, float rhs) {
return lhs = lhs * rhs;
}
#endif // !VECTOR_MATH_HPP