math_util.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // SPDX-FileCopyrightText: 2013 Dolphin Emulator Project
  2. // SPDX-FileCopyrightText: 2014 Citra Emulator Project
  3. // SPDX-License-Identifier: GPL-2.0-or-later
  4. #pragma once
  5. #include <algorithm>
  6. #include <cstdlib>
  7. #include <type_traits>
  8. namespace Common {
  9. constexpr float PI = 3.1415926535f;
  10. template <class T>
  11. struct Rectangle {
  12. T left{};
  13. T top{};
  14. T right{};
  15. T bottom{};
  16. constexpr Rectangle() = default;
  17. constexpr Rectangle(T width, T height) : right(width), bottom(height) {}
  18. constexpr Rectangle(T left_, T top_, T right_, T bottom_)
  19. : left(left_), top(top_), right(right_), bottom(bottom_) {}
  20. [[nodiscard]] constexpr T Left() const {
  21. return left;
  22. }
  23. [[nodiscard]] constexpr T Top() const {
  24. return top;
  25. }
  26. [[nodiscard]] constexpr T Right() const {
  27. return right;
  28. }
  29. [[nodiscard]] constexpr T Bottom() const {
  30. return bottom;
  31. }
  32. [[nodiscard]] constexpr bool IsEmpty() const {
  33. return (GetWidth() <= 0) || (GetHeight() <= 0);
  34. }
  35. [[nodiscard]] constexpr T GetWidth() const {
  36. if constexpr (std::is_floating_point_v<T>) {
  37. return std::abs(right - left);
  38. } else {
  39. return static_cast<T>(std::abs(static_cast<std::make_signed_t<T>>(right - left)));
  40. }
  41. }
  42. [[nodiscard]] constexpr T GetHeight() const {
  43. if constexpr (std::is_floating_point_v<T>) {
  44. return std::abs(bottom - top);
  45. } else {
  46. return static_cast<T>(std::abs(static_cast<std::make_signed_t<T>>(bottom - top)));
  47. }
  48. }
  49. [[nodiscard]] constexpr Rectangle<T> TranslateX(const T x) const {
  50. return Rectangle{left + x, top, right + x, bottom};
  51. }
  52. [[nodiscard]] constexpr Rectangle<T> TranslateY(const T y) const {
  53. return Rectangle{left, top + y, right, bottom + y};
  54. }
  55. [[nodiscard]] constexpr Rectangle<T> Scale(const float s) const {
  56. return Rectangle{left, top, static_cast<T>(static_cast<float>(left + GetWidth()) * s),
  57. static_cast<T>(static_cast<float>(top + GetHeight()) * s)};
  58. }
  59. [[nodiscard]] constexpr bool operator==(const Rectangle<T>& rhs) const {
  60. return (left == rhs.left) && (top == rhs.top) && (right == rhs.right) &&
  61. (bottom == rhs.bottom);
  62. }
  63. [[nodiscard]] constexpr bool operator!=(const Rectangle<T>& rhs) const {
  64. return !operator==(rhs);
  65. }
  66. [[nodiscard]] constexpr bool Intersect(const Rectangle<T>& with, Rectangle<T>* result) const {
  67. result->left = std::max(left, with.left);
  68. result->top = std::max(top, with.top);
  69. result->right = std::min(right, with.right);
  70. result->bottom = std::min(bottom, with.bottom);
  71. return !result->IsEmpty();
  72. }
  73. };
  74. template <typename T>
  75. Rectangle(T, T, T, T) -> Rectangle<T>;
  76. } // namespace Common