27template <
typename T>
class Vec2 {
31 using Real = std::conditional_t<std::is_floating_point_v<T>, T,
float>;
54 return std::atan2(
static_cast<Real>(
y - other.
y),
static_cast<Real>(
x - other.
x));
63 if (
x == 0 &&
y == 0) {
66 return std::atan2(
static_cast<Real>(
y),
static_cast<Real>(
x));
77 requires std::floating_point<T>
88 return std::hypot(
static_cast<Real>(
x - other.
x),
static_cast<Real>(
y - other.
y));
101 const auto seg_x =
static_cast<Real>(end.
x - start.x);
102 const auto seg_y =
static_cast<Real>(end.
y - start.y);
103 const auto rel_x =
static_cast<Real>(
x - start.x);
104 const auto rel_y =
static_cast<Real>(
y - start.y);
106 const Real length_sq = (seg_x * seg_x) + (seg_y * seg_y);
108 ? std::clamp(((rel_x * seg_x) + (rel_y * seg_y)) / length_sq,
Real(0),
Real(1))
111 return std::hypot(rel_x - (seg_x * t), rel_y - (seg_y * t));
121 return (
x * other.
x) + (
y * other.
y);
131 return (
x * other.
y) - (
y * other.
x);
140 return std::sqrt(
static_cast<Real>((
x *
x) + (
y *
y)));
149 requires std::floating_point<T>
152 if (length == T(0)) {
153 return Vec2(T(0), T(0));
156 return Vec2(
x / length,
y / length);
166 return Vec2(
x + other.
x,
y + other.
y);
176 return Vec2(
x - other.
x,
y - other.
y);
186 return Vec2(
x * scalar,
y * scalar);
196 return Vec2(
x / scalar,
y / scalar);
206 return Vec2(
x % scalar,
y % scalar);
288template <
typename T>
class Vec3 {
292 using Real = std::conditional_t<std::is_floating_point_v<T>, T,
float>;
318 if (magnitudes ==
Real(0)) {
323 const auto ratio =
static_cast<Real>(
dot(other)) / magnitudes;
324 return std::acos(std::clamp(ratio,
Real(-1),
Real(1)));
333 return std::sqrt(
static_cast<Real>((
x - other.
x) * (
x - other.
x)
334 + (
y - other.
y) * (
y - other.
y) + (
z - other.
z) * (
z - other.
z)));
344 return (
x * other.
x) + (
y * other.
y) + (
z * other.
z);
354 return Vec3((
y * other.
z) - (
z * other.
y), (
z * other.
x) - (
x * other.
z),
355 (
x * other.
y) - (
y * other.
x));
364 return std::sqrt(
static_cast<Real>((
x *
x) + (
y *
y) + (
z *
z)));
374 return Vec3(
x + other.
x,
y + other.
y,
z + other.
z);
384 return Vec3(
x - other.
x,
y - other.
y,
z - other.
z);
394 return Vec3(
x * scalar,
y * scalar,
z * scalar);
404 return Vec3(
x / scalar,
y / scalar,
z / scalar);
414 return Vec3(
x % scalar,
y % scalar,
z % scalar);
504template <
typename T>
class Quad {
532 Quad(T x, T y, T width, T height)
534 ,
size(width, height)
651 const T push_x = left < right ? -left : right;
652 const T push_y = up < down ? -up : down;
654 if (std::min(left, right) < std::min(up, down)) {
740template <
typename T>
using Polygon = std::vector<Vec2<T>>;
755 for (std::size_t i = 0; i < polygon.size(); ++i) {
756 area +=
static_cast<Real
>(polygon[i].cross(polygon[(i + 1) % polygon.size()]));
758 return area / Real(2);
768 if (polygon.empty()) {
774 for (
const auto& p : polygon) {
775 lo = { std::min(lo.
x, p.x), std::min(lo.
y, p.y) };
776 hi = { std::max(hi.
x, p.x), std::max(hi.
y, p.y) };
778 return { lo, hi - lo };
789 template <
typename T>
793 const T d1 = (b - a).cross(point - a);
794 const T d2 = (c - b).cross(point - b);
795 const T d3 = (a - c).cross(point - c);
796 const bool has_neg = d1 < 0 || d2 < 0 || d3 < 0;
797 const bool has_pos = d1 > 0 || d2 > 0 || d3 > 0;
798 return !(has_neg && has_pos);
826 float direction = 0.0F,
float cone = 0.0F);
834 const std::vector<Polygonf>& occluders,
float direction = 0.0F,
float cone = 0.0F);
843 const std::vector<Polygonf>& occluders,
const std::vector<Quadf>& occluder_bounds,
844 float direction = 0.0F,
float cone = 0.0F);
Quad operator-(const Quad< T > &quad) const
Subtract another rectangle's position and size from this one.
bool collides_top(const Quad &other) const
Quad operator+(const Quad< T > &quad) const
Add another rectangle's position and size to this one.
Quad operator/(const T scalar) const
Divide the rectangle by a scalar.
Vec2< T >::Real distance_to(const Vec2< T > &point) const
Get the distance from a point to the edge of the rectangle.
Quad()
Default constructor for the Quad class.
bool collides(const Quad &other) const
Check if a rectangle is inside the rectangle.
Quad(const Vec2< T > &position, const Vec2< T > &size)
Constructor for the Quad class.
bool collides_left(const Quad &other) const
Vec2< T > get_center() const
Get center of the rectangle.
bool collides_bottom(const Quad &other) const
Quad(T x, T y, T width, T height)
Constructor for the Quad class.
Vec2< T > size
The size of the rectangle.
Vec2< T > position
The position of the rectangle.
void set_size(T width, T height)
Set the size of the rectangle.
bool collides_right(const Quad &other) const
Quad operator*(const T scalar) const
Multiply the rectangle by a scalar.
Vec2< T > closest_point(const Vec2< T > &point) const
Get the point in or on the rectangle closest to another point.
Vec2< T > get_push_out(const Quad &other) const
Get the smallest move that pushes this rectangle out of another. Useful to stop a moving box from ent...
bool contains(const Vec2< T > &point) const
Check if a point is inside the rectangle. The left and top edges are inside, the right and bottom edg...
bool contains(T x, T y) const
Check if coordinates are inside the rectangle. The left and top edges are inside, the right and botto...
void set_position(T x, T y)
Set the position of the rectangle.
T cross(const Vec2 &other) const
Calculate the cross product of two vectors.
bool operator==(const Vec2 &other) const =default
Equality operator for the Vec2 class.
Real angle() const
Calculate the angle of the vector.
Vec2 operator+(const Vec2 &other) const
Addition operator for the Vec2 class.
Vec2 operator/(const T scalar) const
Division operator for the Vec2 class.
Vec2 & operator-=(const Vec2 &other)
Subtraction assignment operator for the Vec2 class.
Vec2()=default
Default constructor for the Vec2 class.
Vec2 operator%(const T scalar) const
Modulo the Vec2 object by a scalar.
Vec2 & operator%=(const T scalar)
Modulo assignment operator for the Vec2 class.
T y
The y component of the vector.
T x
The x component of the vector.
std::conditional_t< std::is_floating_point_v< T >, T, float > Real
Type used for lengths and angles. Integer vectors use float so results are not truncated.
Vec2 operator*(const T scalar) const
Multiplication operator for the Vec2 class.
Real magnitude() const
Calculate the magnitude of the vector.
Vec2 & operator/=(const T scalar)
Division assignment operator for the Vec2 class.
Vec2(T x, T y)
Constructor for the Vec2 class.
Vec2 & operator*=(const T scalar)
Multiplication assignment operator for the Vec2 class.
Real angle(const Vec2 &other) const
Get angle of two vectors.
Real distance_to_segment(const Vec2 &start, const Vec2 &end) const
Get the distance from this point to the nearest point on a line segment. Useful for beams,...
Vec2 normalized() const
Get a vector with the same direction and a length of one.
Vec2 operator-(const Vec2 &other) const
Subtraction operator for the Vec2 class.
Real distance(const Vec2 &other) const
Get distance between two vectors.
Vec2 & operator+=(const Vec2 &other)
Addition assignment operator for the Vec2 class.
T dot(const Vec2 &other) const
Calculate the dot product of two vectors.
static Vec2 from_angle(T angle, T length=T(1))
Create a vector pointing at an angle.
T z
The z component of the vector.
Vec3()=default
Default constructor for the Vec3 class.
Vec3(T x, T y, T z)
Constructor for the Vec3 class.
Real angle(const Vec3 &other) const
Get angle between two vectors (in 3D space).
Real magnitude() const
Calculate the magnitude of the vector.
Vec3 operator/(const T scalar) const
Division operator for the Vec3 class.
T x
The x component of the vector.
Vec3 cross(const Vec3 &other) const
Calculate the cross product of two vectors.
Vec3 & operator-=(const Vec3 &other)
Subtraction assignment operator for the Vec3 class.
T dot(const Vec3 &other) const
Calculate the dot product of two vectors.
Vec3 operator%(const T scalar) const
Modulo the Vec3 object by a scalar.
Real distance(const Vec3 &other) const
Get distance between two vectors.
Vec3 operator+(const Vec3 &other) const
Addition operator for the Vec3 class.
T y
The y component of the vector.
std::conditional_t< std::is_floating_point_v< T >, T, float > Real
Type used for lengths and angles. Integer vectors use float so results are not truncated.
Vec3 & operator*=(const T scalar)
Multiplication assignment operator for the Vec3 class.
Vec3 & operator/=(const T scalar)
Division assignment operator for the Vec3 class.
bool operator==(const Vec3 &other) const =default
Equality operator for the Vec3 class.
Vec3 operator-(const Vec3 &other) const
Subtraction operator for the Vec3 class.
Vec3 & operator+=(const Vec3 &other)
Addition assignment operator for the Vec3 class.
Vec3 & operator%=(const T scalar)
Modulo assignment operator for the Vec3 class.
Vec3 operator*(const T scalar) const
Multiplication operator for the Vec3 class.
Polygonf visibility(const Vec2f &from, float radius, const std::vector< Polygonf > &occluders, float direction=0.0F, float cone=0.0F)
Find the area that can be seen from a point.
std::optional< float > ray_hit(const Vec2f &origin, const Vec2f &direction, const Vec2f &a, const Vec2f &b)
Find where a ray hits a line segment.
Vec2< T >::Real signed_area(const Polygon< T > &polygon)
Get the signed area of a polygon.
bool point_in_triangle(const Vec2< T > &point, const Vec2< T > &a, const Vec2< T > &b, const Vec2< T > &c)
Check if a point is inside a triangle. Points on an edge are inside.
Quad< T > bounds(const Polygon< T > &polygon)
Get the smallest rectangle that holds every corner of a polygon.
Polygon< float > Polygonf
std::vector< Vec2< T > > Polygon
A polygon, as its corners in order. The last corner joins the first.