// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2013 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "line_segment_in_rectangle.h" IGL_INLINE bool igl::line_segment_in_rectangle( const Eigen::Vector2d & s, const Eigen::Vector2d & d, const Eigen::Vector2d & A, const Eigen::Vector2d & B) { using namespace std; using namespace Eigen; // http://stackoverflow.com/a/100165/148668 const auto SegmentIntersectRectangle = [](double a_rectangleMinX, double a_rectangleMinY, double a_rectangleMaxX, double a_rectangleMaxY, double a_p1x, double a_p1y, double a_p2x, double a_p2y)->bool { // Find min and max X for the segment double minX = a_p1x; double maxX = a_p2x; if(a_p1x > a_p2x) { minX = a_p2x; maxX = a_p1x; } // Find the intersection of the segment's and rectangle's x-projections if(maxX > a_rectangleMaxX) { maxX = a_rectangleMaxX; } if(minX < a_rectangleMinX) { minX = a_rectangleMinX; } if(minX > maxX) // If their projections do not intersect return false { return false; } // Find corresponding min and max Y for min and max X we found before double minY = a_p1y; double maxY = a_p2y; double dx = a_p2x - a_p1x; if(fabs(dx) > 0.0000001) { double a = (a_p2y - a_p1y) / dx; double b = a_p1y - a * a_p1x; minY = a * minX + b; maxY = a * maxX + b; } if(minY > maxY) { double tmp = maxY; maxY = minY; minY = tmp; } // Find the intersection of the segment's and rectangle's y-projections if(maxY > a_rectangleMaxY) { maxY = a_rectangleMaxY; } if(minY < a_rectangleMinY) { minY = a_rectangleMinY; } if(minY > maxY) // If Y-projections do not intersect return false { return false; } return true; }; const double minX = std::min(A(0),B(0)); const double minY = std::min(A(1),B(1)); const double maxX = std::max(A(0),B(0)); const double maxY = std::max(A(1),B(1)); bool ret = SegmentIntersectRectangle(minX,minY,maxX,maxY,s(0),s(1),d(0),d(1)); return ret; }