152 lines
4.9 KiB
C
152 lines
4.9 KiB
C
|
// Copyright (c) 2015 Università della Svizzera italiana.
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// This file is part of CGAL (www.cgal.org).
|
||
|
//
|
||
|
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Segment_Delaunay_graph_Linf_2/include/CGAL/Orientation_Linf_2.h $
|
||
|
// $Id: Orientation_Linf_2.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
|
||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||
|
//
|
||
|
//
|
||
|
// Author(s) : Panagiotis Cheilaris, Sandeep Kumar Dey, Evanthia Papadopoulou
|
||
|
//philaris@gmail.com, sandeep.kr.dey@gmail.com, evanthia.papadopoulou@usi.ch
|
||
|
|
||
|
#ifndef CGAL_ORIENTATION_LINF_2_H
|
||
|
#define CGAL_ORIENTATION_LINF_2_H
|
||
|
|
||
|
#include <CGAL/license/Segment_Delaunay_graph_Linf_2.h>
|
||
|
|
||
|
|
||
|
#include <CGAL/basic.h>
|
||
|
#include <CGAL/enum.h>
|
||
|
|
||
|
namespace CGAL {
|
||
|
|
||
|
typedef Sign OrientationLinf;
|
||
|
|
||
|
|
||
|
template<class K>
|
||
|
class Orientation_Linf_2
|
||
|
{
|
||
|
private:
|
||
|
typedef typename K::Point_2 Point_2;
|
||
|
typedef typename K::Compare_x_2 Compare_x_2;
|
||
|
typedef typename K::Compare_y_2 Compare_y_2;
|
||
|
typedef typename K::Comparison_result Comparison_result;
|
||
|
|
||
|
Compare_x_2 compare_x_2;
|
||
|
Compare_y_2 compare_y_2;
|
||
|
|
||
|
|
||
|
OrientationLinf predicate(const Point_2& p, const Point_2& q,
|
||
|
const Point_2& r) const
|
||
|
{
|
||
|
Comparison_result cmpxpq = compare_x_2(p, q);
|
||
|
Comparison_result cmpypq = compare_y_2(p, q);
|
||
|
Comparison_result cmpxpr = compare_x_2(p, r);
|
||
|
Comparison_result cmpypr = compare_y_2(p, r);
|
||
|
Comparison_result cmpxqr = compare_x_2(q, r);
|
||
|
Comparison_result cmpyqr = compare_y_2(q, r);
|
||
|
|
||
|
//std::cout << "debug Orientation_Linf_2 (p,q,r)= "
|
||
|
// << p << ' ' << q << ' ' << r
|
||
|
// << std::endl;
|
||
|
|
||
|
if ( cmpxpq == EQUAL ) {
|
||
|
if (cmpypq == EQUAL) {//p and q are same points
|
||
|
return DEGENERATE;
|
||
|
}
|
||
|
else {//pq forms a vertical line
|
||
|
if (cmpxpr == EQUAL) {//r lies on the vertical line formed by pq
|
||
|
return DEGENERATE;
|
||
|
}
|
||
|
else {
|
||
|
return (cmpypq == cmpxpr) ? RIGHT_TURN : LEFT_TURN ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if ( cmpypq == EQUAL ) {//p and q forms a horizontal line
|
||
|
// here: cmpxpq != EQUAL
|
||
|
if (cmpypr == EQUAL) {//r lies on the horizontal line formed by pq
|
||
|
return DEGENERATE;
|
||
|
}
|
||
|
else {
|
||
|
return (cmpxpq == cmpypr) ? LEFT_TURN : RIGHT_TURN ;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// here both cmpxpq != EQUAL and cmpypq != EQUAL
|
||
|
bool is_monotone =
|
||
|
( ( ( cmpxpr == -cmpxqr ) &&
|
||
|
( cmpypr == -cmpyqr ) ) ||
|
||
|
( ( cmpxpq == cmpxpr) && ( cmpxpr == cmpxqr ) &&
|
||
|
( cmpypq == cmpypr) && ( cmpypr == cmpyqr ) ) ||
|
||
|
( (-cmpxpq == cmpxpr) && ( cmpxpr == cmpxqr) &&
|
||
|
(-cmpypq == cmpypr) && ( cmpypr == cmpyqr) ) ) ;
|
||
|
|
||
|
//std::cout << "debug is_monotone=" << is_monotone << std::endl;
|
||
|
|
||
|
if (is_monotone) {
|
||
|
//p, q, r are monotone here
|
||
|
//std::cout << "debug Orientation_Linf_2 are monotone"
|
||
|
// << std::endl;
|
||
|
return DEGENERATE;
|
||
|
}
|
||
|
else { // p, q, r do not form stair case
|
||
|
//std::cout << "debug Orientation_Linf_2 not monotone"
|
||
|
// << std::endl;
|
||
|
if ( cmpxpq == SMALLER ) {
|
||
|
if ( cmpypq == SMALLER ) {//CASE-I q lies in the North East of p
|
||
|
return (cmpyqr == SMALLER ||
|
||
|
cmpxpr == LARGER ||
|
||
|
(cmpxqr == LARGER && cmpypr == SMALLER)) ?
|
||
|
LEFT_TURN : RIGHT_TURN;
|
||
|
}//end of CASE-I
|
||
|
else {
|
||
|
// compare_y_2(p, q) == LARGER --
|
||
|
// CASE-II q lies in the South East of p
|
||
|
return (cmpxqr == SMALLER ||
|
||
|
cmpypr == SMALLER ||
|
||
|
(cmpxpr == SMALLER && cmpyqr == SMALLER)) ?
|
||
|
LEFT_TURN : RIGHT_TURN;
|
||
|
}//end of CASE-II
|
||
|
}
|
||
|
else {//cmpxpq == LARGER case III and case IV
|
||
|
//std::cout << "debug Orientation_Linf_2 cmpxpq LARGER"
|
||
|
// << std::endl;
|
||
|
if ( cmpypq == SMALLER ) {//CASE-III q lies in the North West of p
|
||
|
//std::cout << "debug Orientation_Linf_2 cmpypq SMALLER"
|
||
|
// << std::endl;
|
||
|
return (cmpxpr == SMALLER ||
|
||
|
cmpyqr == SMALLER ||
|
||
|
(cmpxqr == SMALLER && cmpypr == SMALLER)) ?
|
||
|
RIGHT_TURN : LEFT_TURN;
|
||
|
}//end of CASE-III
|
||
|
else {//compare_y_2(p, q) == LARGER -- CASE-IV q lies in the South West of p
|
||
|
//std::cout << "debug Orientation_Linf_2 cmpypq LARGER"
|
||
|
// << std::endl;
|
||
|
return (cmpypr == SMALLER ||
|
||
|
cmpxqr == LARGER ||
|
||
|
(cmpxpr == LARGER && cmpyqr == SMALLER)) ?
|
||
|
RIGHT_TURN : LEFT_TURN;
|
||
|
}//end of CASE-IV
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
typedef OrientationLinf result_type;
|
||
|
typedef Point_2 argument_type;
|
||
|
|
||
|
OrientationLinf operator()(const Point_2& p, const Point_2& q,
|
||
|
const Point_2& r) const
|
||
|
{
|
||
|
return predicate(p, q, r);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} //namespace CGAL
|
||
|
|
||
|
#endif // CGAL_ORIENTATION_LINF_2_H
|