DYT/Tool/OpenSceneGraph-3.6.5/include/geos/algorithm/Orientation.h
2024-12-25 07:49:36 +08:00

123 lines
4.4 KiB
C++

/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2018 Paul Ramsey <pramsey@cleverlephant.ca>
*
* 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/Orientation.java @ 2017-09-04
*
**********************************************************************/
#pragma once
#include <geos/export.h>
#include <geos/geom/Coordinate.h>
#include <geos/geom/CoordinateSequence.h>
namespace geos {
namespace algorithm { // geos::algorithm
/** \brief
* Functions to compute the orientation of basic geometric structures
* including point triplets (triangles) and rings.
*
* Orientation is a fundamental property of planar geometries
* (and more generally geometry on two-dimensional manifolds).
*
* Orientation is notoriously subject to numerical precision errors
* in the case of collinear or nearly collinear points.
* JTS uses extended-precision arithmetic to increase
* the robustness of the computation.
*
* @author Martin Davis
*/
class GEOS_DLL Orientation {
public:
/* A value that indicates an orientation or turn */
enum {
CLOCKWISE = -1,
COLLINEAR = 0,
COUNTERCLOCKWISE = 1,
RIGHT = -1,
LEFT = 1,
STRAIGHT = 0
};
/** \brief
* Returns the orientation index of the direction of the point q relative to
* a directed infinite line specified by p1-p2.
*
* The index indicates whether the point lies to the
* `Orientation::LEFT` or `Orientation::RIGHT`
* of the line, or lies on it `Orientation::COLLINEAR`.
* The index also indicates the orientation of the triangle formed
* by the three points
* ( `Orientation::COUNTERCLOCKWISE`,
* `Orientation::CLOCKWISE`, or `Orientation::STRAIGHT` )
*/
static int index(const geom::CoordinateXY& p1, const geom::CoordinateXY& p2,
const geom::CoordinateXY& q);
/**
* Computes whether a ring defined by a geom::CoordinateSequence is
* oriented counter-clockwise.
*
* * The list of points is assumed to have the first and last points equal.
* * This handles coordinate lists which contain repeated points.
* * This handles rings which contain collapsed segments
* (in particular, along the top of the ring).
*
* This algorithm is guaranteed to work with valid rings.
* It also works with "mildly invalid" rings
* which contain collapsed (coincident) flat segments along the top of the ring.
* If the ring is "more" invalid (e.g. self-crosses or touches),
* the computed result may not be correct.
*
* @param ring a CoordinateSequence forming a ring (with first and last point identical)
* @return true if the ring is oriented counter-clockwise.
* @throws IllegalArgumentException if there are too few points to determine orientation (< 4)
*/
static bool isCCW(const geom::CoordinateSequence* ring);
/**
* Tests if a ring defined by a CoordinateSequence is
* oriented counter-clockwise, using the signed area of the ring.
*
* * The list of points is assumed to have the first and last points equal.
* * This handles coordinate lists which contain repeated points.
* * This handles rings which contain collapsed segments
* (in particular, along the top of the ring).
* * This handles rings which are invalid due to self-intersection
*
* This algorithm is guaranteed to work with valid rings.
* For invalid rings (containing self-intersections),
* the algorithm determines the orientation of
* the largest enclosed area (including overlaps).
* This provides a more useful result in some situations, such as buffering.
*
* However, this approach may be less accurate in the case of
* rings with almost zero area.
* (Note that the orientation of rings with zero area is essentially
* undefined, and hence non-deterministic.)
*
* @param ring a CoordinateSequence forming a ring (with first and last point identical)
* @return true if the ring is oriented counter-clockwise.
*/
static bool isCCWArea(const geom::CoordinateSequence* ring);
};
} // namespace geos::algorithm
} // namespace geos