line_segment_in_rectangle.cpp 2.6 KB

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