line_segment_in_rectangle.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[email protected]>
  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. // http://stackoverflow.com/a/100165/148668
  16. const auto SegmentIntersectRectangle = [](double a_rectangleMinX,
  17. double a_rectangleMinY,
  18. double a_rectangleMaxX,
  19. double a_rectangleMaxY,
  20. double a_p1x,
  21. double a_p1y,
  22. double a_p2x,
  23. double a_p2y)->bool
  24. {
  25. // Find min and max X for the segment
  26. double minX = a_p1x;
  27. double maxX = a_p2x;
  28. if(a_p1x > a_p2x)
  29. {
  30. minX = a_p2x;
  31. maxX = a_p1x;
  32. }
  33. // Find the intersection of the segment's and rectangle's x-projections
  34. if(maxX > a_rectangleMaxX)
  35. {
  36. maxX = a_rectangleMaxX;
  37. }
  38. if(minX < a_rectangleMinX)
  39. {
  40. minX = a_rectangleMinX;
  41. }
  42. if(minX > maxX) // If their projections do not intersect return false
  43. {
  44. return false;
  45. }
  46. // Find corresponding min and max Y for min and max X we found before
  47. double minY = a_p1y;
  48. double maxY = a_p2y;
  49. double dx = a_p2x - a_p1x;
  50. if(fabs(dx) > 0.0000001)
  51. {
  52. double a = (a_p2y - a_p1y) / dx;
  53. double b = a_p1y - a * a_p1x;
  54. minY = a * minX + b;
  55. maxY = a * maxX + b;
  56. }
  57. if(minY > maxY)
  58. {
  59. double tmp = maxY;
  60. maxY = minY;
  61. minY = tmp;
  62. }
  63. // Find the intersection of the segment's and rectangle's y-projections
  64. if(maxY > a_rectangleMaxY)
  65. {
  66. maxY = a_rectangleMaxY;
  67. }
  68. if(minY < a_rectangleMinY)
  69. {
  70. minY = a_rectangleMinY;
  71. }
  72. if(minY > maxY) // If Y-projections do not intersect return false
  73. {
  74. return false;
  75. }
  76. return true;
  77. };
  78. const double minX = std::min(A(0),B(0));
  79. const double minY = std::min(A(1),B(1));
  80. const double maxX = std::max(A(0),B(0));
  81. const double maxY = std::max(A(1),B(1));
  82. bool ret = SegmentIntersectRectangle(minX,minY,maxX,maxY,s(0),s(1),d(0),d(1));
  83. return ret;
  84. }