Quellcode durchsuchen

Quadrangle contains point

Sam Jaffe vor 6 Jahren
Ursprung
Commit
f730ba984e
2 geänderte Dateien mit 31 neuen und 3 gelöschten Zeilen
  1. 2 0
      math/include/game/math/common.hpp
  2. 29 3
      math/src/common.cpp

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

@@ -13,8 +13,10 @@ 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::line const & shape, dim2::point const & pt);
   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);

+ 29 - 3
math/src/common.cpp

@@ -31,24 +31,50 @@ namespace math {
     };
   }
   
+  bool contains(dim2::line const & ln, dim2::point const & pt) {
+    return approx_equal((ln.first[0] - pt[0]) * ln.slope() + pt[1],
+                        ln.first[1], static_cast<float>(1E-6));
+  }
+  
   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);
+  
+  static dim2::line ray_x(dim2::point const & pt) {
+    return {pt, {{std::numeric_limits<float>::infinity(), pt[1]}}};
+  }
+  
+  bool contains(dim2::quad const & shape, dim2::point const & pt) {
+    dim2::line const ray = ray_x(pt);
+    dim2::line segments[] = {
+      {shape.ll, shape.lr}, {shape.lr, shape.ur},
+      {shape.ur, shape.ul}, {shape.ul, shape.ll}
+    };
+    int hits = 0;
+    for (auto l : segments) {
+      dim2::point const inter = lines::intersection(l, ray);
+      if (inter == pt) return true;
+      else if (contains(l, inter)) ++hits;
+    }
+    return (hits & 1) == 1;
+  }
+  
   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));
+    return contains(rhs, inter);
   }
+  
   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);