DYT/Tool/OpenSceneGraph-3.6.5/include/geos/algorithm/CGAlgorithmsDD.h

194 lines
6.0 KiB
C
Raw Permalink Normal View History

2024-12-24 23:49:36 +00:00
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2014 Mateusz Loskot <mateusz@loskot.net>
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Public Licence as published
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************
*
* Last port: algorithm/CGAlgorithmsDD.java r789 (JTS-1.14)
*
**********************************************************************/
#pragma once
#include <geos/export.h>
#include <geos/math/DD.h>
// Forward declarations
namespace geos {
namespace geom {
class CoordinateXY;
class CoordinateSequence;
}
}
using namespace geos::math;
namespace geos {
namespace algorithm { // geos::algorithm
/// Implements basic computational geometry algorithms using extended precision float-point arithmetic.
class GEOS_DLL CGAlgorithmsDD {
public:
enum {
CLOCKWISE = -1,
COLLINEAR = 0,
COUNTERCLOCKWISE = 1
};
enum {
RIGHT = -1,
LEFT = 1,
STRAIGHT = 0,
FAILURE = 2
};
/** \brief
* Returns the index of the direction of the point `q` relative to
* a vector specified by `p1-p2`.
*
* @param p1 the origin point of the vector
* @param p2 the final point of the vector
* @param q the point to compute the direction to
*
* @return 1 if q is counter-clockwise (left) from p1-p2
* @return -1 if q is clockwise (right) from p1-p2
* @return 0 if q is collinear with p1-p2
*/
static int orientationIndex(const geom::CoordinateXY& p1,
const geom::CoordinateXY& p2,
const geom::CoordinateXY& q);
static int orientationIndex(double p1x, double p1y,
double p2x, double p2y,
double qx, double qy);
/**
* A filter for computing the orientation index of three coordinates.
*
* If the orientation can be computed safely using standard DP arithmetic,
* this routine returns the orientation index. Otherwise, a value `i > 1` is
* returned. In this case the orientation index must be computed using some
* other more robust method.
*
* The filter is fast to compute, so can be used to avoid the use of slower
* robust methods except when they are really needed, thus providing better
* average performance.
*
* Uses an approach due to Jonathan Shewchuk, which is in the public domain.
*/
static inline int orientationIndexFilter(
double pax, double pay,
double pbx, double pby,
double pcx, double pcy)
{
/**
* A value which is safely greater than the relative round-off
* error in double-precision numbers
*/
double constexpr DP_SAFE_EPSILON = 1e-15;
double detsum;
double const detleft = (pax - pcx) * (pby - pcy);
double const detright = (pay - pcy) * (pbx - pcx);
double const det = detleft - detright;
if(detleft > 0.0) {
if(detright <= 0.0) {
return orientation(det);
}
else {
detsum = detleft + detright;
}
}
else if(detleft < 0.0) {
if(detright >= 0.0) {
return orientation(det);
}
else {
detsum = -detleft - detright;
}
}
else {
return orientation(det);
}
double const errbound = DP_SAFE_EPSILON * detsum;
if((det >= errbound) || (-det >= errbound)) {
return orientation(det);
}
return CGAlgorithmsDD::FAILURE;
};
static int
orientation(double x)
{
if(x < 0) {
return CGAlgorithmsDD::RIGHT;
}
if(x > 0) {
return CGAlgorithmsDD::LEFT;
}
return CGAlgorithmsDD::STRAIGHT;
};
/**
* If the lines are parallel (either identical
* or separate) a null value is returned.
* @param p1 an endpoint of line segment 1
* @param p2 an endpoint of line segment 1
* @param q1 an endpoint of line segment 2
* @param q2 an endpoint of line segment 2
* @return an intersection point if one exists, or null if the lines are parallel
*/
static geom::CoordinateXY intersection(const geom::CoordinateXY& p1, const geom::CoordinateXY& p2,
const geom::CoordinateXY& q1, const geom::CoordinateXY& q2);
static int signOfDet2x2(double dx1, double dy1, double dx2, double dy2);
static DD detDD(double x1, double y1, double x2, double y2);
static DD detDD(const DD& x1, const DD& y1, const DD& x2, const DD& y2);
/** \brief
* Computes the circumcentre of a triangle.
*
* The circumcentre is the centre of the circumcircle, the smallest circle
* which encloses the triangle. It is also the common intersection point of
* the perpendicular bisectors of the sides of the triangle, and is the only
* point which has equal distance to all three vertices of the triangle.
*
* The circumcentre does not necessarily lie within the triangle. For example,
* the circumcentre of an obtuse isosceles triangle lies outside the triangle.
*
* This method uses @ref geos::math::DD extended-precision arithmetic to provide more accurate
* results than geos::geom::Triangle::circumcentre.
*
* @param a a vertex of the triangle
* @param b a vertex of the triangle
* @param c a vertex of the triangle
* @return the circumcentre of the triangle
*/
static geom::CoordinateXY circumcentreDD(const geom::CoordinateXY& a, const geom::CoordinateXY& b, const geom::CoordinateXY& c);
protected:
static int signOfDet2x2(const DD& x1, const DD& y1, const DD& x2, const DD& y2);
};
} // namespace geos::algorithm
} // namespace geos