Skip to content

Commit

Permalink
Math: Added some constants to handle floating point presicion compari…
Browse files Browse the repository at this point in the history
…sons (#2)

* Added some constants to handle floating point presicion comparisons and other calculations plus some refactoring

* Removed validation
  • Loading branch information
JassonCordones authored Jun 23, 2024
1 parent 725f63a commit ff343e0
Showing 1 changed file with 43 additions and 22 deletions.
65 changes: 43 additions & 22 deletions src/math/Box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

using namespace Hyprutils::Math;

constexpr double HALF = 0.5;
constexpr double DOUBLE = 2.0;
constexpr double EPSILON = 1e-9;

CBox& Hyprutils::Math::CBox::scale(double scale) {
x *= scale;
y *= scale;
Expand All @@ -33,29 +37,33 @@ CBox& Hyprutils::Math::CBox::translate(const Vector2D& vec) {
}

Vector2D Hyprutils::Math::CBox::middle() const {
return Vector2D{x + w / 2.0, y + h / 2.0};
return Vector2D{x + w * HALF, y + h * HALF};
}

bool Hyprutils::Math::CBox::containsPoint(const Vector2D& vec) const {
return VECINRECT(vec, x, y, x + w, y + h);
}

bool Hyprutils::Math::CBox::empty() const {
return w == 0 || h == 0;
return std::fabs(w) < EPSILON || std::fabs(h) < EPSILON;
}

CBox& Hyprutils::Math::CBox::round() {
float newW = x + w - std::round(x);
float newH = y + h - std::round(y);
x = std::round(x);
y = std::round(y);
double roundedX = std::round(x);
double roundedY = std::round(y);
double newW = x + w - roundedX;
double newH = y + h - roundedY;

x = roundedX;
y = roundedY;
w = std::round(newW);
h = std::round(newH);

return *this;
}

CBox& Hyprutils::Math::CBox::transform(const eTransform t, double w, double h) {

CBox temp = *this;

if (t % 2 == 0) {
Expand Down Expand Up @@ -119,19 +127,19 @@ CBox& Hyprutils::Math::CBox::scaleFromCenter(double scale) {
w *= scale;
h *= scale;

x -= (w - oldW) / 2.0;
y -= (h - oldH) / 2.0;
x -= (w - oldW) * HALF;
y -= (h - oldH) * HALF;

return *this;
}

CBox& Hyprutils::Math::CBox::expand(const double& value) {
x -= value;
y -= value;
w += value * 2.0;
h += value * 2.0;
w += value * DOUBLE;
h += value * DOUBLE;

if (w <= 0 || h <= 0) {
if (w <= EPSILON || h <= EPSILON) {
w = 0;
h = 0;
}
Expand All @@ -147,14 +155,14 @@ CBox& Hyprutils::Math::CBox::noNegativeSize() {
}

CBox Hyprutils::Math::CBox::intersection(const CBox& other) const {
const float newX = std::max(x, other.x);
const float newY = std::max(y, other.y);
const float newBottom = std::min(y + h, other.y + other.h);
const float newRight = std::min(x + w, other.x + other.w);
float newW = newRight - newX;
float newH = newBottom - newY;

if (newW <= 0 || newH <= 0) {
const double newX = std::max(x, other.x);
const double newY = std::max(y, other.y);
const double newBottom = std::min(y + h, other.y + other.h);
const double newRight = std::min(x + w, other.x + other.w);
double newW = newRight - newX;
double newH = newBottom - newY;

if (newW <= EPSILON || newH <= EPSILON) {
newW = 0;
newH = 0;
}
Expand All @@ -171,10 +179,12 @@ bool Hyprutils::Math::CBox::inside(const CBox& bound) const {
}

CBox Hyprutils::Math::CBox::roundInternal() {
float newW = x + w - std::floor(x);
float newH = y + h - std::floor(y);
double flooredX = std::floor(x);
double flooredY = std::floor(y);
double newW = x + w - flooredX;
double newH = y + h - flooredY;

return CBox{std::floor(x), std::floor(y), std::floor(newW), std::floor(newH)};
return CBox{flooredX, flooredY, std::floor(newW), std::floor(newH)};
}

CBox Hyprutils::Math::CBox::copy() const {
Expand All @@ -196,6 +206,17 @@ Vector2D Hyprutils::Math::CBox::closestPoint(const Vector2D& vec) const {
Vector2D nv = vec;
nv.x = std::clamp(nv.x, x, x + w);
nv.y = std::clamp(nv.y, y, y + h);

if (std::fabs(nv.x - x) < EPSILON)
nv.x = x;
else if (std::fabs(nv.x - (x + w)) < EPSILON)
nv.x = x + w;

if (std::fabs(nv.y - y) < EPSILON)
nv.y = y;
else if (std::fabs(nv.y - (y + h)) < EPSILON)
nv.y = y + h;

return nv;
}

Expand Down

0 comments on commit ff343e0

Please sign in to comment.