line_segment_in_rectangle.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "line_segment_in_rectangle.h"
  9. IGL_INLINE bool igl::line_segment_in_rectangle(
  10. const Eigen::Vector2d & s,
  11. const Eigen::Vector2d & d,
  12. const Eigen::Vector2d & A,
  13. const Eigen::Vector2d & B)
  14. {
  15. using namespace std;
  16. using namespace Eigen;
  17. // http://stackoverflow.com/a/100165/148668
  18. const auto SegmentIntersectRectangle = [](double a_rectangleMinX,
  19. double a_rectangleMinY,
  20. double a_rectangleMaxX,
  21. double a_rectangleMaxY,
  22. double a_p1x,
  23. double a_p1y,
  24. double a_p2x,
  25. double a_p2y)->bool
  26. {
  27. // Find min and max X for the segment
  28. double minX = a_p1x;
  29. double maxX = a_p2x;
  30. if(a_p1x > a_p2x)
  31. {
  32. minX = a_p2x;
  33. maxX = a_p1x;
  34. }
  35. // Find the intersection of the segment's and rectangle's x-projections
  36. if(maxX > a_rectangleMaxX)
  37. {
  38. maxX = a_rectangleMaxX;
  39. }
  40. if(minX < a_rectangleMinX)
  41. {
  42. minX = a_rectangleMinX;
  43. }
  44. if(minX > maxX) // If their projections do not intersect return false
  45. {
  46. return false;
  47. }
  48. // Find corresponding min and max Y for min and max X we found before
  49. double minY = a_p1y;
  50. double maxY = a_p2y;
  51. double dx = a_p2x - a_p1x;
  52. if(fabs(dx) > 0.0000001)
  53. {
  54. double a = (a_p2y - a_p1y) / dx;
  55. double b = a_p1y - a * a_p1x;
  56. minY = a * minX + b;
  57. maxY = a * maxX + b;
  58. }
  59. if(minY > maxY)
  60. {
  61. double tmp = maxY;
  62. maxY = minY;
  63. minY = tmp;
  64. }
  65. // Find the intersection of the segment's and rectangle's y-projections
  66. if(maxY > a_rectangleMaxY)
  67. {
  68. maxY = a_rectangleMaxY;
  69. }
  70. if(minY < a_rectangleMinY)
  71. {
  72. minY = a_rectangleMinY;
  73. }
  74. if(minY > maxY) // If Y-projections do not intersect return false
  75. {
  76. return false;
  77. }
  78. return true;
  79. };
  80. const double minX = min(A(0),B(0));
  81. const double minY = min(A(1),B(1));
  82. const double maxX = max(A(0),B(0));
  83. const double maxY = max(A(1),B(1));
  84. bool ret = SegmentIntersectRectangle(minX,minY,maxX,maxY,s(0),s(1),d(0),d(1));
  85. return ret;
  86. }