Переглянути джерело

Line intersects quadrangle.
Generalize to polygons

Sam Jaffe 6 роки тому
батько
коміт
73fa8ee57c
1 змінених файлів з 25 додано та 6 видалено
  1. 25 6
      math/src/common.cpp

+ 25 - 6
math/src/common.cpp

@@ -7,6 +7,8 @@
 
 #include "game/math/common.hpp"
 
+#include <vector>
+
 #include "game/math/angle.hpp"
 #include "game/math/compare.hpp"
 #include "game/math/shape.hpp"
@@ -45,12 +47,9 @@ namespace math {
     return {pt, {{std::numeric_limits<float>::infinity(), pt[1]}}};
   }
   
-  bool contains(dim2::quad const & shape, dim2::point const & pt) {
+  static bool contains(std::vector<dim2::line> const & segments,
+                       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);
@@ -60,6 +59,14 @@ namespace math {
     return (hits & 1) == 1;
   }
   
+  bool contains(dim2::quad const & shape, dim2::point const & pt) {
+    std::vector<dim2::line> segments{
+      {shape.ll, shape.lr}, {shape.lr, shape.ur},
+      {shape.ur, shape.ul}, {shape.ul, shape.ll}
+    };
+    return contains(segments, pt);
+  }
+  
   bool intersects(dim2::line const & lhs, dim2::line const & rhs) {
     dim2::point const inter = lines::intersection(lhs, rhs);
     return contains(rhs, inter);
@@ -71,7 +78,19 @@ namespace math {
     return delta.dot(delta) <= std::pow(rhs.radius, 2);
   }
   
-  bool intersects(dim2::line const & lhs, dim2::quad const & rhs);
+  bool intersects(dim2::line const & lhs, dim2::quad const & rhs) {
+    std::vector<dim2::line> segments{
+      {rhs.ll, rhs.lr}, {rhs.lr, rhs.ur},
+      {rhs.ur, rhs.ul}, {rhs.ul, rhs.ll}
+    };
+    auto lhs_intersects = [&lhs](dim2::line const & ln) {
+      return intersects(lhs, ln);
+    };
+    return std::any_of(segments.begin(), segments.end(), lhs_intersects) ||
+        contains(segments, lhs.first) ||
+        contains(segments, lhs.second);
+  }
+  
   bool intersects(dim2::quad const & lhs, dim2::circle const & rhs);
   bool intersects(dim2::quad const & lhs, dim2::quad const & rhs);