Parcourir la source

Start writing code for shape intersection/containing.

Sam Jaffe il y a 6 ans
Parent
commit
3e1350059e

+ 24 - 0
math/include/game/math/common.hpp

@@ -12,4 +12,28 @@
 namespace math {
   vec2 rotate(vec2 const & center, vec2 const & point, radian r);
   dim2::quad rotate(vec2 const & center, dim2::quad const & q, radian r);
+  
+  bool contains(dim2::circle const & shape, dim2::point const & pt);
+  bool contains(dim2::quad const & shape, dim2::point const & pt);
+  bool intersects(dim2::line const & lhs, dim2::line const & rhs);
+  bool intersects(dim2::line const & lhs, dim2::circle const & rhs);
+  bool intersects(dim2::line const & lhs, dim2::quad const & rhs);
+  bool intersects(dim2::quad const & lhs, dim2::line const & rhs);
+  bool intersects(dim2::quad const & lhs, dim2::circle const & rhs);
+  bool intersects(dim2::quad const & lhs, dim2::quad const & rhs);
+  bool intersects(dim2::circle const & lhs, dim2::line const & rhs);
+  bool intersects(dim2::circle const & lhs, dim2::quad const & rhs);
+  bool intersects(dim2::circle const & lhs, dim2::circle const & rhs);
+}
+
+namespace math {  
+  inline bool intersects(dim2::quad const & lhs, dim2::line const & rhs) {
+    return intersects(rhs, lhs);
+  }
+  inline bool intersects(dim2::circle const & lhs, dim2::line const & rhs) {
+    return intersects(rhs, lhs);
+  }
+  inline bool intersects(dim2::circle const & lhs, dim2::quad const & rhs) {
+    return intersects(rhs, lhs);
+  }
 }

+ 39 - 0
math/include/game/math/compare.hpp

@@ -0,0 +1,39 @@
+#pragma once
+
+#include <algorithm>
+#include <cmath>
+
+namespace math {
+  template <typename T>
+  bool between(T val, T min, T max) {
+    return val >= min && val < max;
+  }
+
+  template <typename T>
+  bool approx_equal(T lhs, T rhs, T eps) {
+    T const a = std::abs(lhs);
+    T const b = std::abs(rhs);
+    return std::abs(lhs - rhs) <= (std::max(a, b) * eps);
+  }
+  
+  template <typename T>
+  bool essentially_equal(T lhs, T rhs, T eps) {
+    T const a = std::abs(lhs);
+    T const b = std::abs(rhs);
+    return std::abs(lhs - rhs) <= (std::min(a, b) * eps);
+  }
+  
+  template <typename T>
+  bool definitely_greater(T lhs, T rhs, T eps) {
+    T const a = std::abs(lhs);
+    T const b = std::abs(rhs);
+    return (lhs - rhs) > (std::max(a, b) * eps);
+  }
+  
+  template <typename T>
+  bool definitely_less(T lhs, T rhs, T eps) {
+    T const a = std::abs(lhs);
+    T const b = std::abs(rhs);
+    return (rhs - lhs) > (std::max(a, b) * eps);
+  }
+}

+ 10 - 9
math/include/game/math/math_fwd.hpp

@@ -20,8 +20,18 @@ namespace math {
     template <typename T, size_t N>
     using square_matrix = matrix<T, N, N>;
   }
+}
+
+namespace math {
+  using vec2i = vector::vector<int, 2>;
+  using vec2  = vector::vector<float, 2>;
+  using vec3  = vector::vector<float, 3>;
+  using rgba  = vector::vector<uint8_t, 4>;
   
+  using matr4 = matrix::matrix<float, 4, 4>;
+
   namespace dim2 {
+    using point = vec2;
     struct line;
     struct circle;
     struct quad;
@@ -32,12 +42,3 @@ namespace math {
   struct degree;
   struct radian;
 }
-
-namespace math {
-  using vec2i = vector::vector<int, 2>;
-  using vec2  = vector::vector<float, 2>;
-  using vec3  = vector::vector<float, 3>;
-  using rgba  = vector::vector<uint8_t, 4>;
-  
-  using matr4 = matrix::matrix<float, 4, 4>;
-}

+ 24 - 0
math/src/common.cpp

@@ -8,6 +8,7 @@
 #include "game/math/common.hpp"
 
 #include "game/math/angle.hpp"
+#include "game/math/compare.hpp"
 #include "game/math/shape.hpp"
 
 namespace math {
@@ -29,4 +30,27 @@ namespace math {
       rotate(c, q.ul, r)
     };
   }
+  
+  bool contains(dim2::circle const & shape, dim2::point const & pt) {
+    vec2 const delta = pt - shape.center;
+    return delta.dot(delta) <= std::pow(shape.radius, 2);
+  }
+  bool contains(dim2::quad const & shape, dim2::point const & pt);
+  bool intersects(dim2::line const & lhs, dim2::line const & rhs) {
+    dim2::point const inter = lines::intersection(lhs, rhs);
+    return approx_equal((rhs.first[0] - inter[0]) * rhs.slope() + inter[1],
+                        rhs.first[1], static_cast<float>(1E-6));
+  }
+  bool intersects(dim2::line const & lhs, dim2::circle const & rhs) {
+    dim2::line const orth = lines::orthogonal(lhs, rhs.center);
+    vec2 const delta = orth.second - orth.first;
+    return delta.dot(delta) <= std::pow(rhs.radius, 2);
+  }
+  bool intersects(dim2::line const & lhs, dim2::quad const & rhs);
+  bool intersects(dim2::quad const & lhs, dim2::circle const & rhs);
+  bool intersects(dim2::quad const & lhs, dim2::quad const & rhs);
+  bool intersects(dim2::circle const & lhs, dim2::circle const & rhs) {
+    vec2 const delta = rhs.center - lhs.center;
+    return delta.dot(delta) <= std::pow(lhs.radius + rhs.radius, 2);
+  }
 }