From f8741e27e2ecda09ccd7a568cdc292088b3fb768 Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Sun, 21 Feb 2021 16:30:21 -0800 Subject: [PATCH] vec2 & rect code cleanup --- include/blah.h | 1 + include/blah/core/log.h | 2 +- include/blah/math/rectI.h | 29 +++---- include/blah/math/vec2.h | 79 +++++++++++++++-- src/drawing/batch.cpp | 8 +- src/math/rectI.cpp | 110 +++++++++++++++++++++-- src/math/vec2.cpp | 177 +++++++++++++++++++++++++++++++------- 7 files changed, 337 insertions(+), 69 deletions(-) diff --git a/include/blah.h b/include/blah.h index 920c3ef..8cd72da 100644 --- a/include/blah.h +++ b/include/blah.h @@ -45,6 +45,7 @@ #include "blah/math/rectI.h" #include "blah/math/stopwatch.h" #include "blah/math/vec2.h" +#include "blah/math/vec3.h" #include "blah/math/vec4.h" #include "blah/streams/bufferstream.h" diff --git a/include/blah/core/log.h b/include/blah/core/log.h index 7f2fbad..626fdae 100644 --- a/include/blah/core/log.h +++ b/include/blah/core/log.h @@ -1,7 +1,7 @@ #pragma once // error / abort -#ifdef DEBUG +#if defined(DEBUG) || defined(_DEBUG) #include #define BLAH_ERROR(message) \ diff --git a/include/blah/math/rectI.h b/include/blah/math/rectI.h index 2a8bfd5..fb4e10e 100644 --- a/include/blah/math/rectI.h +++ b/include/blah/math/rectI.h @@ -17,12 +17,12 @@ namespace Blah RectI(int rx, int ry, int rw, int rh); RectI(Point pos, Point size); - int left() const { return x; } - int right() const { return x + w; } - int top() const { return y; } - int bottom() const { return y + h; } - int centerX() const { return x + w / 2; } - int centerY() const { return y + h / 2; } + int left() const; + int right() const; + int top() const; + int bottom() const; + int center_x() const; + int center_y() const; Point center() const; Point top_left() const; @@ -30,14 +30,7 @@ namespace Blah Point bottom_left() const; Point bottom_right() const; - bool overlaps(const RectI& other) const - { - return x < other.x + other.w - && other.x < x + w - && y < other.y + other.h - && other.y < y + h; - } - + bool overlaps(const RectI& other) const; bool contains(const Point& pt) const; bool contains(const Vec2& pt) const; @@ -51,14 +44,14 @@ namespace Blah char get_sector(const Point& pt) const; char get_sector(const Vec2& pt) const; - bool operator==(const RectI& rhs) const { return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h; } - bool operator!=(const RectI& rhs) const { return !(*this == rhs); } + bool operator==(const RectI& rhs) const; + bool operator!=(const RectI& rhs) const; RectI operator+(const Point& rhs) const; RectI operator-(const Point& rhs) const; + RectI operator*(const int& rhs) const; + RectI operator/(const int& rhs) const; RectI& operator+=(const Point& rhs); RectI& operator-=(const Point& rhs); - - RectI operator*(const int& rhs) const { return RectI(x * rhs, y * rhs, w * rhs, h * rhs); } }; } \ No newline at end of file diff --git a/include/blah/math/vec2.h b/include/blah/math/vec2.h index 4e872b5..1449a2c 100644 --- a/include/blah/math/vec2.h +++ b/include/blah/math/vec2.h @@ -33,39 +33,108 @@ namespace Blah bool operator ==(const Vec2& rhs) const; bool operator !=(const Vec2& rhs) const; - + + // Returns the absolute value of the Vector + Vec2 abs() const; + + // Returns the Normalized Vector + // If the length is 0, the resulting Vector is 0,0 Vec2 normal() const; + + // Rotates the Vector 90 degrees right (y, -x) Vec2 turn_right() const; + + // Rotates the Vector 90 degrees left (-y, x) Vec2 turn_left() const; + + // Returns the length of the Vector float length() const; + + // Returns the squared length of the Vector float length_squared() const; + + // Gets the perpendicular Vector (-y, x) Vec2 perpendicular() const; + + // Gets the angle, in radians, of the Vector float angle() const; + // Calculates the Dot Product between two vectors static float dot(Vec2 a, Vec2 b); + + // Calculates the Dot Product between two vectors static float dot(float x, float y, Vec2 b); + + // Calculates the Dot Product between two vectors static float dot(float x1, float y1, float x2, float y2); + // Transforms a Vector by the given Matrix static Vec2 transform(const Vec2& vec, const Mat3x2& matrix); + + // Transforms a Vector by the given Matrix static Vec2 transform(float x, float y, const Mat3x2& matrix); - static Vec2 from_angle(float radians, float length); - static Vec2 from_angle(float radians); + + // Transforms a Vector Normal by the given Matrix + static Vec2 transform_normal(const Vec2& vec, const Mat3x2& matrix); + + // Transforms a Vector Normal by the given Matrix + static Vec2 transform_normal(float x, float y, const Mat3x2& matrix); + + // Calculates a Vector value from the given radians + static Vec2 from_angle(float radians, float length = 1.0f); + + // Lerps between two Vectors static Vec2 lerp(Vec2 start, Vec2 end, float t); - static Vec2 bezier_lerp(Vec2 start, Vec2 b, Vec2 end, float t); - static Vec2 bezier_lerp(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t); + + // Lerps between two Vectors along a Bezier curve + static Vec2 lerp_bezier(Vec2 start, Vec2 b, Vec2 end, float t); + + // Lerps between two Vectors along a Bezier curve + static Vec2 lerp_bezier(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t); + + // Reflects a vector along the given Normal static Vec2 reflect(const Vec2& vector, const Vec2& normal); + // Gets the minimum between two vectors + static Vec2 min(const Vec2& a, const Vec2& b); + + // Gets the maximum between two vectors + static Vec2 max(const Vec2& a, const Vec2& b); + + // (1, 0) static const Vec2 unit_x; + + // (0, 1) static const Vec2 unit_y; + + // (1, 0) static const Vec2 right; + + // (0, -1) static const Vec2 up; + + // (0, 1) static const Vec2 down; + + // (-1, 0) static const Vec2 left; + + // (0, 0) static const Vec2 zero; + + // (1, 1) static const Vec2 one; + + // (0.707, -0.707) static const Vec2 up_right; + + // (-0.707, -0.707) static const Vec2 up_left; + + // (0.707, 0.707) static const Vec2 down_right; + + // (-0.707, 0.707) static const Vec2 down_left; }; diff --git a/src/drawing/batch.cpp b/src/drawing/batch.cpp index 6fd527f..cddac61 100644 --- a/src/drawing/batch.cpp +++ b/src/drawing/batch.cpp @@ -507,7 +507,7 @@ void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& to, int ste for (int i = 1; i < steps; i++) { - Vec2 at = Vec2::bezier_lerp(from, b, to, add * i); + Vec2 at = Vec2::lerp_bezier(from, b, to, add * i); line(prev, at, t, color); prev = at; } @@ -522,7 +522,7 @@ void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& c, const Ve for (int i = 1; i < steps; i++) { - Vec2 at = Vec2::bezier_lerp(from, b, c, to, add * i); + Vec2 at = Vec2::lerp_bezier(from, b, c, to, add * i); line(prev, at, t, color); prev = at; } @@ -668,8 +668,8 @@ void Batch::rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr, { // get corners Rect tl = Rect(rect.top_left(), Vec2(rtl, rtl)); - Rect tr = Rect(rect.top_right() + Vec2(-rtr, 0), Vec2(rtr, rtr)); - Rect bl = Rect(rect.bottom_left() + Vec2(0, -rbl), Vec2(rbl, rbl)); + Rect tr = Rect(rect.top_right() + Vec2(-rtr, 0.0f), Vec2(rtr, rtr)); + Rect bl = Rect(rect.bottom_left() + Vec2(0.0f, -rbl), Vec2(rbl, rbl)); Rect br = Rect(rect.bottom_right() + Vec2(-rbr, -rbr), Vec2(rbr, rbr)); // rounded corners diff --git a/src/math/rectI.cpp b/src/math/rectI.cpp index 18c2456..fd4b28a 100644 --- a/src/math/rectI.cpp +++ b/src/math/rectI.cpp @@ -26,11 +26,68 @@ RectI::RectI(Point pos, Point size) h = size.y; } -Point RectI::center() const { return Point(centerX(), centerY()); } -Point RectI::top_left() const { return Point(left(), top()); } -Point RectI::top_right() const { return Point(right(), top()); } -Point RectI::bottom_left() const { return Point(left(), bottom()); } -Point RectI::bottom_right() const { return Point(right(), bottom()); } +int RectI::left() const +{ + return x; +} + +int RectI::right() const +{ + return x + w; +} + +int RectI::top() const +{ + return y; +} + +int RectI::bottom() const +{ + return y + h; +} + +int RectI::center_x() const +{ + return x + w / 2; +} + +int RectI::center_y() const +{ + return y + h / 2; +} + +Point RectI::center() const +{ + return Point(x + w / 2, y + h / 2); +} + +Point RectI::top_left() const +{ + return Point(x, y); +} + +Point RectI::top_right() const +{ + return Point(x + w, y); +} + +Point RectI::bottom_left() const +{ + return Point(x, y + h); +} + +Point RectI::bottom_right() const +{ + return Point(x + w, y + h); +} + +bool RectI::overlaps(const RectI& other) const +{ + return x < other.x + other.w + && other.x < x + w + && y < other.y + other.h + && other.y < y + h; +} bool RectI::contains(const Point& point) const { @@ -84,7 +141,42 @@ char RectI::get_sector(const Vec2& pt) const return h | v; } -RectI RectI::operator+(const Point& rhs) const { return RectI(x + rhs.x, y + rhs.y, w, h); } -RectI RectI::operator-(const Point& rhs) const { return RectI(x - rhs.x, y - rhs.y, w, h); } -RectI& RectI::operator+=(const Point& rhs) { x += rhs.x; y += rhs.y; return *this; } -RectI& RectI::operator-=(const Point& rhs) { x -= rhs.x; y -= rhs.y; return *this; } \ No newline at end of file +bool RectI::operator==(const RectI& rhs) const +{ + return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h; +} + +bool RectI::operator!=(const RectI& rhs) const +{ + return !(*this == rhs); +} + +RectI RectI::operator+(const Point& rhs) const +{ + return RectI(x + rhs.x, y + rhs.y, w, h); +} + +RectI RectI::operator-(const Point& rhs) const +{ + return RectI(x - rhs.x, y - rhs.y, w, h); +} + +RectI RectI::operator*(const int& rhs) const +{ + return RectI(x * rhs, y * rhs, w * rhs, h * rhs); +} + +RectI RectI::operator/(const int& rhs) const +{ + return RectI(x / rhs, y / rhs, w / rhs, h / rhs); +} + +RectI& RectI::operator+=(const Point& rhs) +{ + x += rhs.x; y += rhs.y; return *this; +} + +RectI& RectI::operator-=(const Point& rhs) +{ + x -= rhs.x; y -= rhs.y; return *this; +} diff --git a/src/math/vec2.cpp b/src/math/vec2.cpp index 6ad6c82..dff0d29 100644 --- a/src/math/vec2.cpp +++ b/src/math/vec2.cpp @@ -5,28 +5,100 @@ using namespace Blah; -Vec2::Vec2() { x = y = 0; } -Vec2::Vec2(float vx, float vy) { x = vx; y = vy; } -Vec2::Vec2(int vx, float vy) { x = (float)vx; y = vy; } -Vec2::Vec2(float vx, int vy) { x = vx; y = (float)vy; } -Vec2::Vec2(int vx, int vy) { x = (float)vx; y = (float)vy; } -Vec2::Vec2(Point p) { x = (float)p.x; y = (float)p.y; } +Vec2::Vec2() + : x(0) + , y(0) +{} -Vec2 Vec2::operator +(const Vec2 rhs) const { return Vec2(x + rhs.x, y + rhs.y); } -Vec2 Vec2::operator -(const Vec2 rhs) const { return Vec2(x - rhs.x, y - rhs.y); } -Vec2 Vec2::operator /(const float rhs) const { return Vec2(x / rhs, y / rhs); } -Vec2 Vec2::operator *(const float rhs) const { return Vec2(x * rhs, y * rhs); } -Vec2 Vec2::operator-() const { return Vec2(-x, -y); } +Vec2::Vec2(float vx, float vy) + : x(vx) + , y(vy) +{} -Vec2& Vec2::operator +=(const Vec2& rhs) { x += rhs.x; y += rhs.y; return *this; } -Vec2& Vec2::operator -=(const Vec2& rhs) { x -= rhs.x; y -= rhs.y; return *this; } -Vec2& Vec2::operator /=(const Vec2& rhs) { x /= rhs.x; y /= rhs.y; return *this; } -Vec2& Vec2::operator *=(const Vec2& rhs) { x *= rhs.x; y *= rhs.y; return *this; } -Vec2& Vec2::operator/=(float rhs) { x /= rhs; y /= rhs; return *this; } -Vec2& Vec2::operator*=(float rhs) { x *= rhs; y *= rhs; return *this; } +Vec2::Vec2(int vx, float vy) + : x(static_cast(vx)) + , y(vy) +{} -bool Vec2::operator ==(const Vec2& rhs) const { return x == rhs.x && y == rhs.y; } -bool Vec2::operator !=(const Vec2& rhs) const { return x != rhs.x || y != rhs.y; } +Vec2::Vec2(float vx, int vy) + : x(vx) + , y(static_cast(vy)) +{} + +Vec2::Vec2(int vx, int vy) + : x(static_cast(vx)) + , y(static_cast(vy)) +{} + +Vec2::Vec2(Point p) + : x(static_cast(p.x)) + , y(static_cast(p.y)) +{} + +Vec2 Vec2::operator +(const Vec2 rhs) const +{ + return Vec2(x + rhs.x, y + rhs.y); +} + +Vec2 Vec2::operator -(const Vec2 rhs) const +{ + return Vec2(x - rhs.x, y - rhs.y); +} + +Vec2 Vec2::operator /(const float rhs) const +{ + return Vec2(x / rhs, y / rhs); +} + +Vec2 Vec2::operator *(const float rhs) const +{ + return Vec2(x * rhs, y * rhs); +} + +Vec2 Vec2::operator-() const +{ + return Vec2(-x, -y); +} + +Vec2& Vec2::operator +=(const Vec2& rhs) +{ + x += rhs.x; y += rhs.y; return *this; +} + +Vec2& Vec2::operator -=(const Vec2& rhs) +{ + x -= rhs.x; y -= rhs.y; return *this; +} + +Vec2& Vec2::operator /=(const Vec2& rhs) +{ + x /= rhs.x; y /= rhs.y; return *this; +} + +Vec2& Vec2::operator *=(const Vec2& rhs) +{ + x *= rhs.x; y *= rhs.y; return *this; +} + +Vec2& Vec2::operator/=(float rhs) +{ + x /= rhs; y /= rhs; return *this; +} + +Vec2& Vec2::operator*=(float rhs) +{ + x *= rhs; y *= rhs; return *this; +} + +bool Vec2::operator ==(const Vec2& rhs) const +{ + return x == rhs.x && y == rhs.y; +} + +bool Vec2::operator !=(const Vec2& rhs) const +{ + return x != rhs.x || y != rhs.y; +} Vec2 Vec2::normal() const { @@ -46,8 +118,15 @@ Vec2 Vec2::turn_left() const return Vec2(-y, x); } -float Vec2::length() const { return sqrtf(x * x + y * y); } -float Vec2::length_squared() const { return x * x + y * y; } +float Vec2::length() const +{ + return sqrtf(x * x + y * y); +} + +float Vec2::length_squared() const +{ + return x * x + y * y; +} Vec2 Vec2::perpendicular() const { @@ -59,9 +138,20 @@ float Vec2::angle() const return Calc::atan2(y, x); } -float Vec2::dot(Vec2 a, Vec2 b) { return (a.x * b.x + a.y * b.y); } -float Vec2::dot(float x, float y, Vec2 b) { return (x * b.x + y * b.y); } -float Vec2::dot(float x1, float y1, float x2, float y2) { return (x1 * x2 + y1 * y2); } +float Vec2::dot(Vec2 a, Vec2 b) +{ + return (a.x * b.x + a.y * b.y); +} + +float Vec2::dot(float x, float y, Vec2 b) +{ + return (x * b.x + y * b.y); +} + +float Vec2::dot(float x1, float y1, float x2, float y2) +{ + return (x1 * x2 + y1 * y2); +} Vec2 Vec2::transform(const Vec2& vec, const Mat3x2& matrix) { @@ -77,16 +167,25 @@ Vec2 Vec2::transform(float x, float y, const Mat3x2& matrix) (x * matrix.m12) + (y * matrix.m22) + matrix.m32); } +Vec2 transform_normal(const Vec2& vec, const Mat3x2& matrix) +{ + return Vec2( + vec.x * matrix.m11 + vec.y * matrix.m21, + vec.x * matrix.m12 + vec.y * matrix.m22); +} + +Vec2 transform_normal(float x, float y, const Mat3x2& matrix) +{ + return Vec2( + x * matrix.m11 + y * matrix.m21, + x * matrix.m12 + y * matrix.m22); +} + Vec2 Vec2::from_angle(float radians, float length) { return Vec2((float)cos(radians) * length, (float)sin(radians) * length); } -Vec2 Vec2::from_angle(float radians) -{ - return from_angle(radians, 1); -} - Vec2 Vec2::lerp(Vec2 a, Vec2 b, float t) { if (t == 0) @@ -97,14 +196,14 @@ Vec2 Vec2::lerp(Vec2 a, Vec2 b, float t) return a + (b - a) * t; } -Vec2 Vec2::bezier_lerp(Vec2 start, Vec2 b, Vec2 end, float t) +Vec2 Vec2::lerp_bezier(Vec2 start, Vec2 b, Vec2 end, float t) { return lerp(lerp(start, b, t), lerp(b, end, t), t); } -Vec2 Vec2::bezier_lerp(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t) +Vec2 Vec2::lerp_bezier(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t) { - return bezier_lerp(lerp(start, b, t), lerp(b, c, t), lerp(c, end, t), t); + return lerp_bezier(lerp(start, b, t), lerp(b, c, t), lerp(c, end, t), t); } Vec2 Vec2::reflect(const Vec2& vector, const Vec2& normal) @@ -116,6 +215,20 @@ Vec2 Vec2::reflect(const Vec2& vector, const Vec2& normal) vector.y - 2.0f * dot * normal.y); } +Vec2 Vec2::min(const Vec2& a, const Vec2& b) +{ + return Vec2( + a.x < b.x ? a.x : b.x, + a.y < b.y ? a.y : b.y); +} + +Vec2 Vec2::max(const Vec2& a, const Vec2& b) +{ + return Vec2( + a.x > b.x ? a.x : b.x, + a.y > b.y ? a.y : b.y); +} + const Vec2 Vec2::unit_x = Vec2(1, 0); const Vec2 Vec2::unit_y = Vec2(0, 1); const Vec2 Vec2::right = Vec2(1, 0);