Commit 013dd017 authored by Davis King's avatar Davis King

Added is_convex_quadrilateral(), find_convex_quadrilateral(), and

no_convex_quadrilateral.
parent d3bd9d61
......@@ -7,6 +7,7 @@
#include "vector.h"
#include <utility>
#include "../numeric_constants.h"
#include <array>
namespace dlib
{
......@@ -184,6 +185,48 @@ namespace dlib
return std::acos(tmp)*180/pi;
}
// ----------------------------------------------------------------------------------------
struct no_convex_quadrilateral : dlib::error
{
no_convex_quadrilateral() : dlib::error("Lines given to find_convex_quadrilateral() don't form any convex quadrilateral.") {}
};
inline std::array<dpoint,4> find_convex_quadrilateral (
const std::array<line,4>& lines
)
{
const dpoint v01 = intersect(lines[0],lines[1]);
const dpoint v02 = intersect(lines[0],lines[2]);
const dpoint v03 = intersect(lines[0],lines[3]);
const dpoint v12 = intersect(lines[1],lines[2]);
const dpoint v13 = intersect(lines[1],lines[3]);
const dpoint v23 = intersect(lines[2],lines[3]);
const auto& v10 = v01;
const auto& v20 = v02;
const auto& v30 = v03;
const auto& v21 = v12;
const auto& v31 = v13;
const auto& v32 = v23;
if (is_convex_quadrilateral({v01, v12, v23, v30}))
return {v01, v12, v23, v30};
if (is_convex_quadrilateral({v01, v13, v32, v20}))
return {v01, v13, v32, v20};
if (is_convex_quadrilateral({v02, v23, v31, v10}))
return {v02, v23, v31, v10};
if (is_convex_quadrilateral({v02, v21, v13, v30}))
return {v02, v21, v13, v30};
if (is_convex_quadrilateral({v03, v32, v21, v10}))
return {v03, v32, v21, v10};
if (is_convex_quadrilateral({v03, v31, v12, v20}))
return {v03, v31, v12, v20};
throw no_convex_quadrilateral();
}
// ----------------------------------------------------------------------------------------
}
......
......@@ -202,6 +202,32 @@ namespace dlib
that appear in the same region as reference_point.
!*/
// ----------------------------------------------------------------------------------------
struct no_convex_quadrilateral : dlib::error
{
/*!
WHAT THIS OBJECT REPRESENTS
This is the exception thrown by find_convex_quadrilateral() if the inputs
can't form a convex quadrilateral.
!*/
no_convex_quadrilateral(
) : dlib::error("Lines given to find_convex_quadrilateral() don't form any convex quadrilateral.")
{}
};
std::array<dpoint,4> find_convex_quadrilateral (
const std::array<line,4>& lines
);
/*!
ensures
- Is there a set of 4 points, made up of the intersections of the given lines,
that forms a convex quadrilateral? If yes then this routine returns those 4
points and if not throws no_convex_quadrilateral.
throws
- no_convex_quadrilateral
!*/
// ----------------------------------------------------------------------------------------
}
......
......@@ -11,6 +11,7 @@
#include <iostream>
#include "../matrix/matrix.h"
#include <limits>
#include <array>
#if defined(_MSC_VER) && _MSC_VER < 1400
// Despite my efforts to disabuse visual studio of its usual nonsense I can't find a
......@@ -1274,6 +1275,38 @@ namespace dlib
typedef vector<long,2> point;
typedef vector<double,2> dpoint;
// ----------------------------------------------------------------------------------------
inline bool is_convex_quadrilateral (
const std::array<dpoint,4>& pts
)
{
auto orientation = [&](size_t i)
{
size_t a = (i+1)%4;
size_t b = (i+3)%4;
return (pts[a]-pts[i]).cross(pts[b]-pts[i]).z();
};
// If pts has any infinite points then this isn't a valid quadrilateral.
for (auto& p : pts)
{
if (p.x() == std::numeric_limits<double>::infinity())
return false;
if (p.y() == std::numeric_limits<double>::infinity())
return false;
}
double s0 = orientation(0);
double s1 = orientation(1);
double s2 = orientation(2);
double s3 = orientation(3);
// if all these things have the same sign then it's convex.
return (s0>0&&s1>0&&s2>0&&s3>0) || (s0<0&&s1<0&&s2<0&&s3<0);
}
// ----------------------------------------------------------------------------------------
}
......
......@@ -444,6 +444,18 @@ namespace dlib
typedef vector<double,2> dpoint;
// ----------------------------------------------------------------------------------------
bool is_convex_quadrilateral (
const std::array<dpoint,4>& pts
);
/*!
ensures
- If you walk the points in pts in order pts[0], pts[1], pts[2], pts[3], pts[0]
does it draw a convex quadrilateral? This routine returns true if yes and
false if not.
!*/
// ----------------------------------------------------------------------------------------
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment