LCOV - code coverage report
Current view: top level - cell - MathUtils.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 38 54 70.4 %
Date: 2025-12-06 00:15:40 Functions: 9 14 64.3 %

          Line data    Source code
       1             : #include "MathUtils.hpp"
       2             : 
       3             : #include <algorithm>
       4             : #include <cmath>
       5             : #include <numbers>
       6             : #include <numeric>
       7             : #include <ostream>
       8             : #include <random>
       9             : 
      10           0 : sf::Time operator*(const sf::Time& time, double factor)
      11             : {
      12           0 :     return time * static_cast<float>(factor);
      13             : }
      14             : 
      15           2 : std::ostream& operator<<(std::ostream& os, const sf::Vector2d& v)
      16             : {
      17           2 :     return os << "(" << v.x << ", " << v.y << ")";
      18             : }
      19             : 
      20           7 : double operator*(const sf::Vector2d& a, const sf::Vector2d& b)
      21             : {
      22           7 :     return a.x * b.x + a.y * b.y;
      23             : }
      24             : 
      25             : namespace cell::mathutils
      26             : {
      27             : 
      28          10 : double abs(const sf::Vector2d& vec)
      29             : {
      30          10 :     return std::hypot(vec.x, vec.y);
      31             : }
      32             : 
      33           0 : sf::Vector2d calculateNormal(const sf::Vector2d& v1, const sf::Vector2d& v2)
      34             : {
      35           0 :     const auto diff = v2 - v1;
      36             : 
      37           0 :     return diff / abs(diff);
      38             : }
      39             : 
      40           3 : std::vector<sf::Vector2d> calculateGrid(double width, double height, double edgeLength)
      41             : {
      42           3 :     static std::random_device rd;
      43           3 :     static std::mt19937 gen(rd());
      44             : 
      45           3 :     std::vector<sf::Vector2d> gridPoints;
      46           3 :     gridPoints.reserve(static_cast<std::size_t>((static_cast<double>(width) / edgeLength) *
      47           3 :                                                 (static_cast<double>(height) / edgeLength)));
      48           3 :     double spacing = edgeLength + 1;
      49             : 
      50         835 :     for (int i = 0; i < static_cast<int>(width / spacing); ++i)
      51             :     {
      52      463166 :         for (int j = 0; j < static_cast<int>(height / spacing); ++j)
      53      462334 :             gridPoints.emplace_back(spacing * static_cast<double>(i + 1), spacing * static_cast<double>(j + 1));
      54             :     }
      55             : 
      56           3 :     std::shuffle(gridPoints.begin(), gridPoints.end(), gen);
      57             : 
      58           3 :     return gridPoints;
      59           0 : }
      60             : 
      61           0 : bool pointIsInCircle(const sf::Vector2d& point, const sf::Vector2d& M, double R)
      62             : {
      63           0 :     const auto diff = point - M;
      64             : 
      65           0 :     return diff.x * diff.x + diff.y * diff.y < R * R;
      66             : }
      67             : 
      68      462896 : bool circleIsFullyContainedByCircle(const sf::Vector2d& M1, double R1, const sf::Vector2d& M2, double R2)
      69             : {
      70      462896 :     const auto diff = M1 - M2;
      71             : 
      72      462896 :     return diff.x * diff.x + diff.y * diff.y < (R2 - R1) * (R2 - R1);
      73             : }
      74             : 
      75      362181 : bool circlesOverlap(const sf::Vector2d& M1, double R1, const sf::Vector2d& M2, double R2)
      76             : {
      77      362181 :     return circlesOverlap(M1, R1, M2, R2, MinOverlap{0.0});
      78             : }
      79             : 
      80      362195 : bool circlesOverlap(const sf::Vector2d& M1, double R1, const sf::Vector2d& M2, double R2, MinOverlap minOverlap)
      81             : {
      82      362195 :     const auto diff = M1 - M2;
      83      362195 :     const double R = R1 + R2 - minOverlap.value;
      84             : 
      85      362195 :     return diff.x * diff.x + diff.y * diff.y <= R * R;
      86             : }
      87             : 
      88          16 : bool circlesIntersect(const sf::Vector2d& M1, double R1, const sf::Vector2d& M2, double R2)
      89             : {
      90             :     // equivalent to: return circlesOverlap(...) && !circleIsFullyContainedByCircle(...)
      91          16 :     const auto diff = M1 - M2;
      92          16 :     const auto distanceSquared = diff.x * diff.x + diff.y * diff.y;
      93             : 
      94          16 :     return (distanceSquared <= (R1 + R2) * (R1 + R2)) && distanceSquared >= (R2 - R1) * (R2 - R1);
      95             : }
      96             : 
      97           0 : bool isMovingTowards(const sf::Vector2d& pos1, const sf::Vector2d& velocity, const sf::Vector2d& point)
      98             : {
      99           0 :     const auto diff = point - pos1;
     100             : 
     101           0 :     return velocity * diff > 0;
     102             : }
     103             : 
     104           0 : double calculateOverlap(const sf::Vector2d& r, double R1, double R2)
     105             : {
     106           0 :     double distance = mathutils::abs(r);
     107             : 
     108           0 :     return R1 + R2 - distance;
     109             : }
     110             : 
     111           2 : double getAngleBetween(const sf::Vector2d& a, const sf::Vector2d& b)
     112             : {
     113           2 :     const double lenA = abs(a);
     114           2 :     const double lenB = abs(b);
     115             : 
     116           2 :     if (lenA == 0.0 || lenB == 0.0)
     117           0 :         return 0.0; // arbitrary, no direction
     118             : 
     119           2 :     double dot = a * b / (lenA * lenB);
     120             : 
     121             :     // Clamp to valid range for acos
     122           2 :     dot = std::clamp(dot, -1.0, 1.0);
     123             : 
     124           2 :     return std::acos(dot) * 180.0 / std::numbers::pi;
     125             : }
     126             : 
     127             : } // namespace cell::mathutils

Generated by: LCOV version 1.14