spacebox/src/Box.cpp

356 lines
6.1 KiB
C++

#include "Box.hpp"
Box::Box(const glm::vec2& nw, const glm::vec2& size)
{
x = nw.x;
y = nw.y;
w = size.x;
h = size.y;
}
float Box::get_x() const
{
return x;
}
float Box::get_y() const
{
return y;
}
float Box::get_w() const
{
return w;
}
float Box::get_h() const
{
return h;
}
void Box::set_x(float x)
{
this->x = x;
}
void Box::set_y(float y)
{
this->y = y;
}
void Box::set_w(float width)
{
w = width;
}
void Box::set_h(float height)
{
h = height;
}
glm::vec2 Box::get_size() const
{
return glm::vec2(get_w(), get_h());
}
float Box::get_area() const
{
return get_w() * get_h();
}
void Box::set_size(const glm::vec2& size, bool preserve_center)
{
glm::vec2 center = get_center();
set_w(size.x);
set_h(size.y);
if (preserve_center)
{
set_center(center);
}
}
float Box::get_top() const
{
return get_y();
}
float Box::get_right() const
{
return get_x() + get_w();
}
float Box::get_bottom() const
{
return get_y() + get_h();
}
float Box::get_left() const
{
return get_x();
}
float Box::get_center_x() const
{
return get_left() + get_w() / 2;
}
float Box::get_center_y() const
{
return get_top() + get_h() / 2;
}
void Box::set_top(float top)
{
set_y(top);
}
void Box::set_right(float right, bool drag)
{
float delta = right - get_right();
if (!drag)
{
move({delta, 0});
}
else
{
drag_right(delta);
}
}
void Box::drag_right(float delta)
{
float previous_right = get_right();
float new_right = get_right() + delta;
set_w(get_w() + new_right - previous_right);
set_right(new_right);
}
void Box::set_bottom(float bottom)
{
move({0, bottom - get_bottom()});
}
void Box::set_left(float left, bool drag)
{
if (!drag)
{
set_x(left);
}
else
{
drag_left(left - get_left());
}
}
void Box::drag_left(float delta)
{
float previous_left = get_left();
set_left(get_left() + delta);
set_w(get_w() + previous_left - get_left());
}
void Box::set_center_x(float x)
{
move({x - get_center_x(), 0});
}
void Box::set_center_y(float y)
{
move({0, y - get_center_y()});
}
glm::vec2 Box::get_nw() const
{
return {get_x(), get_y()};
}
glm::vec2 Box::get_north() const
{
return glm::vec2(get_x() + get_w() / 2, get_y());
}
glm::vec2 Box::get_ne() const
{
return glm::vec2(get_right(), get_y());
}
glm::vec2 Box::get_east() const
{
return glm::vec2(get_right(), get_top() + get_h() / 2);
}
glm::vec2 Box::get_se() const
{
return glm::vec2(get_right(), get_bottom());
}
glm::vec2 Box::get_south() const
{
return glm::vec2(get_left() + get_w() / 2, get_bottom());
}
glm::vec2 Box::get_sw() const
{
return glm::vec2(get_left(), get_bottom());
}
glm::vec2 Box::get_west() const
{
return glm::vec2(get_x(), get_y() + get_h() / 2);
}
glm::vec2 Box::get_center() const
{
return glm::vec2(get_x() + get_w() / 2, get_y() + get_h() / 2);
}
void Box::set_nw(const glm::vec2& nw)
{
move(nw - get_nw());
}
void Box::set_north(const glm::vec2& n)
{
move(n - get_north());
}
void Box::set_ne(const glm::vec2& ne)
{
move(ne - get_ne());
}
void Box::set_east(const glm::vec2& e)
{
move(e - get_east());
}
void Box::set_se(const glm::vec2& se)
{
move(se - get_se());
}
void Box::set_south(const glm::vec2& s)
{
move(s - get_south());
}
void Box::set_west(const glm::vec2& w)
{
move(w - get_west());
}
void Box::set_center(const glm::vec2& center)
{
move(center - get_center());
}
Box::operator SDL_Rect() const
{
return {
static_cast<int>(get_x()), static_cast<int>(get_y()),
static_cast<int>(get_w()), static_cast<int>(get_h())
};
}
void Box::clear()
{
set_nw(glm::vec2(0, 0));
set_size(glm::vec2(0, 0));
}
void Box::scale(glm::vec2 delta, bool preserve_center)
{
glm::vec2 center = get_center();
set_size(get_size() * delta);
if (preserve_center)
{
set_center(center);
}
}
void Box::scale(float delta, bool preserve_center)
{
Box::scale({delta, delta}, preserve_center);
}
void Box::grow(glm::vec2 delta, bool preserve_center)
{
glm::vec2 center = get_center();
set_size(get_size() + delta);
if (preserve_center)
{
set_center(center);
}
}
void Box::grow(float delta, bool preserve_center)
{
Box::grow({delta, delta}, preserve_center);
}
void Box::move(const glm::vec2& delta)
{
set_x(get_x() + delta.x);
set_y(get_y() + delta.y);
}
bool Box::collide(const glm::vec2& point) const
{
return point.x >= get_left() && point.x <= get_right() && point.y >= get_top() && point.y <= get_bottom();
}
bool Box::collide(const Segment& segment, glm::vec2* intersection) const
{
if (collide(segment.get_box()))
{
return segment.intersect({get_nw(), get_ne()}, intersection) ||
segment.intersect({get_ne(), get_se()}, intersection) ||
segment.intersect({get_sw(), get_se()}, intersection) ||
segment.intersect({get_nw(), get_sw()}, intersection);
}
else
{
return false;
}
}
bool Box::collide(const Segment& segment, glm::vec2& intersection) const
{
return collide(segment, &intersection);
}
bool Box::collide(const Box& box, Box* overlap) const
{
float top = std::max(get_top(), box.get_top());
float right = std::min(get_right(), box.get_right());
float bottom = std::min(get_bottom(), box.get_bottom());
float left = std::max(get_left(), box.get_left());
float w = right - left;
float h = bottom - top;
bool collide = w > 0 && h > 0;
if (collide && overlap != NULL)
{
overlap->set_x(left);
overlap->set_y(top);
overlap->set_w(w);
overlap->set_h(h);
}
return collide;
}
bool Box::collide(const Box& box, Box& overlap) const
{
return collide(box, &overlap);
}
std::ostream& Box::to_string (std::ostream& out) const
{
out << "{(" << get_x() << ", " << get_y() << "), (" << get_w() << ", " << get_h() << ")}";
return out;
}
std::ostream& operator<< (std::ostream& out, const Box& box)
{
return box.to_string(out);
}