Line data Source code
1 : #ifndef F49356D0_94E7_4146_8837_E2FA0C87BEBB_HPP 2 : #define F49356D0_94E7_4146_8837_E2FA0C87BEBB_HPP 3 : 4 : /** 5 : * @brief The math utilities here are partly explained in the physics part of the documentation 6 : */ 7 : 8 : #include "Types.hpp" 9 : #include "Vector2d.hpp" 10 : 11 : #include <ostream> 12 : #include <random> 13 : #include <unordered_map> 14 : #include <utility> 15 : 16 : namespace cell 17 : { 18 : class Disc; 19 : } 20 : 21 : namespace cell::mathutils 22 : { 23 : 24 : /** 25 : * @param M1 Center point of contained circle 26 : * @param R1 Radius of contained circle 27 : * @param M2 Center point of containing circle 28 : * @param R2 Radius of containing circle 29 : */ 30 462915 : inline bool circleIsFullyContainedByCircle(const Vector2d& M1, double R1, const Vector2d& M2, double R2) noexcept 31 : { 32 462915 : const auto diff = M1 - M2; 33 : 34 462915 : return diff.x * diff.x + diff.y * diff.y < (R2 - R1) * (R2 - R1); 35 : } 36 : 37 362199 : inline bool circlesOverlap(const Vector2d& M1, double R1, const Vector2d& M2, double R2, MinOverlap minOverlap) noexcept 38 : { 39 362199 : const auto diff = M1 - M2; 40 362199 : const double R = R1 + R2 - minOverlap.value; 41 : 42 362199 : return diff.x * diff.x + diff.y * diff.y <= R * R; 43 : } 44 : 45 362189 : inline bool circlesOverlap(const Vector2d& M1, double R1, const Vector2d& M2, double R2) noexcept 46 : { 47 362189 : return circlesOverlap(M1, R1, M2, R2, MinOverlap{0.0}); 48 : } 49 : 50 17 : inline bool circlesIntersect(const Vector2d& M1, double R1, const Vector2d& M2, double R2) noexcept 51 : { 52 : // equivalent to: return circlesOverlap(...) && !circleIsFullyContainedByCircle(...) 53 17 : const auto diff = M1 - M2; 54 17 : const auto distanceSquared = diff.x * diff.x + diff.y * diff.y; 55 : 56 17 : return (distanceSquared <= (R1 + R2) * (R1 + R2)) && distanceSquared >= (R2 - R1) * (R2 - R1); 57 : } 58 : 59 : /** 60 : * @returns |vec| 61 : */ 62 11 : inline double abs(const Vector2d& vec) noexcept 63 : { 64 11 : return std::hypot(vec.x, vec.y); 65 : } 66 : 67 : inline double calculateOverlap(const Vector2d& r, double R1, double R2) noexcept 68 : { 69 : double distance = mathutils::abs(r); 70 : 71 : return R1 + R2 - distance; 72 : } 73 : 74 : /** 75 : * @brief Returns a number in the given range 76 : */ 77 16 : template <typename T> T getRandomNumber(std::type_identity_t<T> low, std::type_identity_t<T> high) noexcept 78 : { 79 16 : static thread_local std::mt19937 gen{std::random_device{}()}; 80 : if constexpr (std::is_integral_v<T>) 81 : { 82 8 : std::uniform_int_distribution<T> dist(low, high); 83 8 : return dist(gen); 84 : } 85 : else 86 : { 87 8 : std::uniform_real_distribution<T> dist(low, high); 88 8 : return dist(gen); 89 : } 90 : } 91 : 92 10 : inline unsigned int getRandomInt() noexcept 93 : { 94 10 : static thread_local std::minstd_rand rng{std::random_device{}()}; 95 : 96 10 : return rng(); 97 : } 98 : 99 : /** 100 : * @brief Calculates a grid of starting positions for discs based on the largest radius of all disc types in the 101 : * settings. 102 : */ 103 : std::vector<Vector2d> calculateGrid(double width, double height, double edgeLength); 104 : 105 : } // namespace cell::mathutils 106 : 107 : #endif /* F49356D0_94E7_4146_8837_E2FA0C87BEBB_HPP */