104 lines
2.6 KiB
C++
104 lines
2.6 KiB
C++
|
// This file is part of libigl, a simple c++ geometry processing library.
|
||
|
//
|
||
|
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||
|
//
|
||
|
// 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;
|
||
|
}
|