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

148 lines
4.2 KiB
C++

/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2020 Paul Ramsey <pramsey@cleverelephant.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.
*
**********************************************************************/
#pragma once
#include <geos/triangulate/tri/TriEdge.h>
#include <geos/triangulate/tri/Tri.h>
#include <geos/triangulate/tri/TriList.h>
// Forward declarations
namespace geos {
namespace geom {
class Coordinate;
}
}
using geos::geom::Coordinate;
using geos::triangulate::tri::TriList;
using geos::triangulate::tri::Tri;
namespace geos {
namespace triangulate {
namespace polygon {
/**
* Improves the quality of a triangulation of Tri via
* iterated Delaunay flipping.
* This produces the Constrained Delaunay Triangulation
* with the constraints being the boundary of the input triangulation.
*
* @author mdavis
*
*/
class GEOS_DLL TriDelaunayImprover {
private:
// Members
static constexpr std::size_t MAX_ITERATION = 200;
TriList<Tri>& triList;
/**
* Improves a triangulation by examining pairs of adjacent triangles
* (forming a quadrilateral) and testing if flipping the diagonal of
* the quadrilateral would produce two new triangles with larger minimum
* interior angles.
*
* @return the number of flips that were made
*/
std::size_t improveScan(TriList<Tri>& triList);
/**
* Does a flip of the common edge of two Tris if the Delaunay condition is not met.
*
* @param tri0 a Tri
* @param tri1 a Tri
* @return true if the triangles were flipped
*/
bool improveNonDelaunay(Tri* tri, TriIndex index);
/**
* Tests if the quadrilateral formed by two adjacent triangles is convex.
* opp0-adj0-adj1 and opp1-adj1-adj0 are the triangle corners
* and hence are known to be convex.
* The quadrilateral is convex if the other corners opp0-adj0-opp1
* and opp1-adj1-opp0 have the same orientation (since at least one must be convex).
*
* @param adj0 adjacent edge vertex 0
* @param adj1 adjacent edge vertex 1
* @param opp0 corner vertex of triangle 0
* @param opp1 corner vertex of triangle 1
* @return true if the quadrilateral is convex
*/
static bool isConvex(const Coordinate& adj0, const Coordinate& adj1,
const Coordinate& opp0, const Coordinate& opp1);
/**
* Tests if either of a pair of adjacent triangles satisfy the Delaunay condition.
* The triangles are opp0-adj0-adj1 and opp1-adj1-adj0.
* The Delaunay condition is not met if one opposite vertex
* lies is in the circumcircle of the other triangle.
*
* @param adj0 adjacent edge vertex 0
* @param adj1 adjacent edge vertex 1
* @param opp0 corner vertex of triangle 0
* @param opp1 corner vertex of triangle 1
* @return true if the triangles are Delaunay
*/
static bool isDelaunay(const Coordinate& adj0, const Coordinate& adj1,
const Coordinate& opp0, const Coordinate& opp1);
/**
* Tests whether a point p is in the circumcircle of a triangle abc
* (oriented clockwise).
* @param a a vertex of the triangle
* @param b a vertex of the triangle
* @param c a vertex of the triangle
* @param p the point
*
* @return true if the point is in the circumcircle
*/
static bool
isInCircle(const Coordinate& a, const Coordinate& b,
const Coordinate& c, const Coordinate& p);
void improve();
public:
TriDelaunayImprover(TriList<Tri>& p_triList)
: triList(p_triList)
{};
/**
* Improves the quality of a triangulation of Tri via
* iterated Delaunay flipping.
* The Tris are assumed to be linked into a Triangulation
* (e.g. via TriangulationBuilder).
*
* @param triList the list of Tris to flip.
*/
static void improve(TriList<Tri>& triList);
};
} // namespace geos.triangulate.polygon
} // namespace geos.triangulate
} // namespace geos