#pragma once #include #include #include #include #include template struct BoundingBox { static_assert(std::is_arithmetic::value, "This class only works with floats or integers."); T MinX, MaxX, MinY, MaxY; BoundingBox(T MinX = std::numeric_limits::max(), T MaxX = std::numeric_limits::lowest(), T MinY = std::numeric_limits::max(), T MaxY = std::numeric_limits::lowest()) : MinX(MinX), MaxX(MaxX), MinY(MinY), MaxY(MaxY) { } T width () const { return MaxX - MinX; } T heigth() const { return MaxY - MinY; } T area () const { return width()*heigth(); } bool isInside(T x, T y) const { return (x >= MinX && x <= MaxX) && (y >= MinY && y <= MaxY); } // Expands the size of the BB if the given values are extreme void expand(T x, T y) { if (x < MinX) MinX = x; if (x > MaxX) MaxX = x; if (y < MinY) MinY = y; if (y > MaxY) MaxY = y; } // Enlarges the BB in both direction along an axis. void inflate(T szX, T szY) { MinX -= szX; MinY -= szY; MaxX += szX; MaxY += szY; } }; template struct Point2D { static_assert(std::is_arithmetic::value, "This class only works with floats and integers."); T X, Y; Point2D(T x = 0, T y = 0) : X(x), Y(y) { } }; template struct Size2D { static_assert(std::is_arithmetic::value, "This class only works with floats and integers."); T sX, sY; Size2D(T all) : sX(all), sY(all) { } Size2D(T x = 0, T y = 0) : sX(x), sY(y) { } }; #ifdef NDEBUG #define assertCond(_EXPR_) (false) #define assertThrow(_arg_) ((void)0) #define assert_throw(...) ((void)0) #define assertMsg(...) ((void)0) #else // Evaluates the expression. Ifdef NDEBUG returns always false #define assertCond(_EXPR_) (!(_EXPR_)) // Throws a excpetion with the argument as message by prepending the current file name and line number #define assertThrow(_std_string_) assert_throw( (_std_string_), __FILE__, __LINE__) inline void assert_throw(const std::string& message, const char* file, int line) { std::stringstream ss; ss << file << ":" << line << ": " << message; throw std::invalid_argument(ss.str()); } #define assertMsg(_EXPR_, _MSG_) if (!(_EXPR_)) assertThrow(_MSG_) #endif // ostream overloads template std::ostream& operator<<(std::ostream& os, const Point2D& pt) { return os << "(" << pt.X << "; " << pt.Y << ")"; } template std::ostream& operator<<(std::ostream& os, const BoundingBox& bb) { return os << "(X: " << bb.MinX << " - " << bb.MaxX << ";" << " Y: " << bb.MinY << " - " << bb.MaxY << ")"; }