1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2012 Excensus LLC.
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
13 **********************************************************************
15 * Last port: triangulate/quadedge/QuadEdgeSubdivision.java r524
17 **********************************************************************/
19 #ifndef GEOS_TRIANGULATE_QUADEDGE_QUADEDGESUBDIVISION_H
20 #define GEOS_TRIANGULATE_QUADEDGE_QUADEDGESUBDIVISION_H
28 #include <geos/geom/MultiLineString.h>
29 #include <geos/triangulate/quadedge/QuadEdgeLocator.h>
30 #include <geos/triangulate/quadedge/Vertex.h>
36 class CoordinateSequence
;
37 class GeometryCollection
;
38 class GeometryFactory
;
44 namespace triangulate
{ //geos.triangulate
45 namespace quadedge
{ //geos.triangulate.quadedge
48 class TriangleVisitor
;
50 const double EDGE_COINCIDENCE_TOL_FACTOR
= 1000;
53 * A class that contains the {@link QuadEdge}s representing a planar
54 * subdivision that models a triangulation.
55 * The subdivision is constructed using the
56 * quadedge algebra defined in the classs {@link QuadEdge}.
57 * All metric calculations
58 * are done in the {@link Vertex} class.
59 * In addition to a triangulation, subdivisions
60 * support extraction of Voronoi diagrams.
61 * This is easily accomplished, since the Voronoi diagram is the dual
62 * of the Delaunay triangulation.
64 * Subdivisions can be provided with a tolerance value. Inserted vertices which
65 * are closer than this value to vertices already in the subdivision will be
66 * ignored. Using a suitable tolerance value can prevent robustness failures
67 * from happening during Delaunay triangulation.
69 * Subdivisions maintain a <b>frame</b> triangle around the client-created
70 * edges. The frame is used to provide a bounded "container" for all edges
71 * within a TIN. Normally the frame edges, frame connecting edges, and frame
72 * triangles are not included in client processing.
74 * @author JTS: David Skea
75 * @author JTS: Martin Davis
76 * @author Benjamin Campbell
78 class GEOS_DLL QuadEdgeSubdivision
{
80 typedef std::list
<QuadEdge
*> QuadEdgeList
;
83 * Gets the edges for the triangle to the left of the given {@link QuadEdge}.
88 * @throws IllegalArgumentException
89 * if the edges do not form a triangle
91 static void getTriangleEdges(const QuadEdge
&startQE
,
92 const QuadEdge
* triEdge
[3]);
95 QuadEdgeList quadEdges
;
96 QuadEdgeList createdEdges
;
97 QuadEdge
* startingEdges
[3];
99 double edgeCoincidenceTolerance
;
100 Vertex frameVertex
[3];
101 geom::Envelope frameEnv
;
102 std::auto_ptr
<QuadEdgeLocator
> locator
;
106 * Creates a new instance of a quad-edge subdivision based on a frame triangle
107 * that encloses a supplied bounding box. A new super-bounding box that
108 * contains the triangle is computed and stored.
111 * the bouding box to surround
113 * the tolerance value for determining if two sites are equal
115 QuadEdgeSubdivision(const geom::Envelope
&env
, double tolerance
);
117 virtual ~QuadEdgeSubdivision();
120 virtual void createFrame(const geom::Envelope
&env
);
122 virtual void initSubdiv(QuadEdge
* initEdges
[3]);
126 * Gets the vertex-equality tolerance value
127 * used in this subdivision
129 * @return the tolerance value
131 inline double getTolerance() const {
136 * Gets the envelope of the Subdivision (including the frame).
138 * @return the envelope
140 inline const geom::Envelope
& getEnvelope() const {
145 * Gets the collection of base {@link QuadEdge}s (one for every pair of
146 * vertices which is connected).
148 * @return a QuadEdgeList
150 inline const QuadEdgeList
& getEdges() const {
155 * Sets the {@link QuadEdgeLocator} to use for locating containing triangles
156 * in this subdivision.
161 inline void setLocator(std::auto_ptr
<QuadEdgeLocator
> locator
) {
162 this->locator
= locator
;
166 * Creates a new quadedge, recording it in the edges list.
172 virtual QuadEdge
& makeEdge(const Vertex
&o
, const Vertex
&d
);
175 * Creates a new QuadEdge connecting the destination of a to the origin of b,
176 * in such a way that all three have the same left face after the connection
177 * is complete. The quadedge is recorded in the edges list.
183 virtual QuadEdge
& connect(QuadEdge
&a
, QuadEdge
&b
);
186 * Deletes a quadedge from the subdivision. Linked quadedges are updated to
187 * reflect the deletion.
190 * the quadedge to delete
192 void remove(QuadEdge
&e
);
195 * Locates an edge of a triangle which contains a location
196 * specified by a Vertex v.
197 * The edge returned has the
198 * property that either v is on e, or e is an edge of a triangle containing v.
199 * The search starts from startEdge amd proceeds on the general direction of v.
201 * This locate algorithm relies on the subdivision being Delaunay. For
202 * non-Delaunay subdivisions, this may loop for ever.
204 * @param v the location to search for
205 * @param startEdge an edge of the subdivision to start searching at
206 * @returns a QuadEdge which contains v, or is on the edge of a triangle containing v
207 * @throws LocateFailureException
208 * if the location algorithm fails to converge in a reasonable
209 * number of iterations. The returned pointer should not be
210 * freed be the caller.
212 QuadEdge
* locateFromEdge(const Vertex
&v
,
213 const QuadEdge
&startEdge
) const;
216 * Finds a quadedge of a triangle containing a location
217 * specified by a {@link Vertex}, if one exists.
219 * @param x the vertex to locate
220 * @return a quadedge on the edge of a triangle which touches or contains the location
221 * @return null if no such triangle exists. The returned pointer should not be
222 * freed be the caller.
224 inline QuadEdge
* locate(const Vertex
&v
) const {
225 return locator
->locate(v
);
229 * Finds a quadedge of a triangle containing a location
230 * specified by a {@link Coordinate}, if one exists.
232 * @param p the Coordinate to locate
233 * @return a quadedge on the edge of a triangle which touches or contains the location
234 * @return null if no such triangle exists. The returned pointer should not be
235 * freed be the caller.
237 inline QuadEdge
* locate(const geom::Coordinate
&p
) {
238 return locator
->locate(Vertex(p
));
242 * Locates the edge between the given vertices, if it exists in the
245 * @param p0 a coordinate
246 * @param p1 another coordinate
247 * @return the edge joining the coordinates, if present
248 * @return null if no such edge exists
249 * @return the caller _should not_ free the returned pointer
251 QuadEdge
* locate(const geom::Coordinate
&p0
, const geom::Coordinate
&p1
);
254 * Inserts a new site into the Subdivision, connecting it to the vertices of
255 * the containing triangle (or quadrilateral, if the split point falls on an
258 * This method does NOT maintain the Delaunay condition. If desired, this must
259 * be checked and enforced by the caller.
261 * This method does NOT check if the inserted vertex falls on an edge. This
262 * must be checked by the caller, since this situation may cause erroneous
266 * the vertex to insert
267 * @return a new quad edge terminating in v
269 QuadEdge
& insertSite(const Vertex
&v
);
272 * Tests whether a QuadEdge is an edge incident on a frame triangle vertex.
276 * @return true if the edge is connected to the frame triangle
278 bool isFrameEdge(const QuadEdge
&e
) const;
281 * Tests whether a QuadEdge is an edge on the border of the frame facets and
282 * the internal facets. E.g. an edge which does not itself touch a frame
283 * vertex, but which touches an edge which does.
287 * @return true if the edge is on the border of the frame
289 bool isFrameBorderEdge(const QuadEdge
&e
) const;
292 * Tests whether a vertex is a vertex of the outer triangle.
296 * @return true if the vertex is an outer triangle vertex
298 bool isFrameVertex(const Vertex
&v
) const;
302 * Tests whether a {@link Coordinate} lies on a {@link QuadEdge}, up to a
303 * tolerance determined by the subdivision tolerance.
309 * @return true if the vertex lies on the edge
311 bool isOnEdge(const QuadEdge
&e
, const geom::Coordinate
&p
) const;
314 * Tests whether a {@link Vertex} is the start or end vertex of a
315 * {@link QuadEdge}, up to the subdivision tolerance distance.
319 * @return true if the vertex is a endpoint of the edge
321 bool isVertexOfEdge(const QuadEdge
&e
, const Vertex
&v
) const;
324 * Gets all primary quadedges in the subdivision.
325 * A primary edge is a {@link QuadEdge}
326 * which occupies the 0'th position in its array of associated quadedges.
327 * These provide the unique geometric edges of the triangulation.
329 * @param includeFrame true if the frame edges are to be included
330 * @return a List of QuadEdges. The caller takes ownership of the returned QuadEdgeList but not the
333 std::auto_ptr
<QuadEdgeList
> getPrimaryEdges(bool includeFrame
);
335 /*****************************************************************************
337 ****************************************************************************/
339 void visitTriangles(TriangleVisitor
*triVisitor
, bool includeFrame
);
342 typedef std::stack
<QuadEdge
*> QuadEdgeStack
;
343 typedef std::set
<QuadEdge
*> QuadEdgeSet
;
344 typedef std::list
< geom::CoordinateSequence
*> TriList
;
347 * The quadedges forming a single triangle.
348 * Only one visitor is allowed to be active at a
349 * time, so this is safe.
351 QuadEdge
* triEdges
[3];
354 * Stores the edges for a visited triangle. Also pushes sym (neighbour) edges
355 * on stack to visit later.
359 * @param includeFrame
360 * @return the visited triangle edges
361 * @return null if the triangle should not be visited (for instance, if it is
364 QuadEdge
** fetchTriangleToVisit(QuadEdge
*edge
, QuadEdgeStack
&edgeStack
, bool includeFrame
,
365 QuadEdgeSet
&visitedEdges
);
368 * Gets the coordinates for each triangle in the subdivision as an array.
370 * @param includeFrame
371 * true if the frame triangles should be included
372 * @param triList a list of Coordinate[4] representing each triangle
374 void getTriangleCoordinates(TriList
* triList
, bool includeFrame
);
377 class TriangleCoordinatesVisitor
;
378 class TriangleCircumcentreVisitor
;
382 * Gets the geometry for the edges in the subdivision as a {@link MultiLineString}
383 * containing 2-point lines.
385 * @param geomFact the GeometryFactory to use
386 * @return a MultiLineString. The caller takes ownership of the returned object.
388 std::auto_ptr
<geom::MultiLineString
> getEdges(const geom::GeometryFactory
& geomFact
);
391 * Gets the geometry for the triangles in a triangulated subdivision as a {@link GeometryCollection}
392 * of triangular {@link Polygon}s.
394 * @param geomFact the GeometryFactory to use
395 * @return a GeometryCollection of triangular Polygons. The caller takes ownership of the returned object.
397 std::auto_ptr
<geom::GeometryCollection
> getTriangles(const geom::GeometryFactory
&geomFact
);
400 * Gets the cells in the Voronoi diagram for this triangulation.
401 * The cells are returned as a {@link GeometryCollection} of {@link Polygon}s
402 * The userData of each polygon is set to be the {@link Coordinate}
403 * of the cell site. This allows easily associating external
404 * data associated with the sites to the cells.
406 * @param geomFact a geometry factory
407 * @return a GeometryCollection of Polygons
409 std::auto_ptr
<geom::GeometryCollection
> getVoronoiDiagram(const geom::GeometryFactory
& geomFact
);
412 * Gets a List of {@link Polygon}s for the Voronoi cells
413 * of this triangulation.
414 * The userData of each polygon is set to be the {@link Coordinate}
415 * of the cell site. This allows easily associating external
416 * data associated with the sites to the cells.
418 * @param geomFact a geometry factory
419 * @return a List of Polygons
421 std::auto_ptr
< std::vector
<geom::Geometry
*> > getVoronoiCellPolygons(const geom::GeometryFactory
& geomFact
);
424 * Gets a collection of {@link QuadEdge}s whose origin
425 * vertices are a unique set which includes
426 * all vertices in the subdivision.
427 * The frame vertices can be included if required.
428 * This is useful for algorithms which require traversing the
429 * subdivision starting at all vertices.
430 * Returning a quadedge for each vertex
431 * is more efficient than
432 * the alternative of finding the actual vertices
433 * using {@link #getVertices} and then locating
434 * quadedges attached to them.
436 * @param includeFrame true if the frame vertices should be included
437 * @return a collection of QuadEdge with the vertices of the subdivision as their origins
439 std::auto_ptr
<QuadEdgeSubdivision::QuadEdgeList
> getVertexUniqueEdges(bool includeFrame
);
442 * Gets the Voronoi cell around a site specified
443 * by the origin of a QuadEdge.
444 * The userData of the polygon is set to be the {@link Coordinate}
445 * of the site. This allows attaching external
446 * data associated with the site to this cell polygon.
448 * @param qe a quadedge originating at the cell site
449 * @param geomFact a factory for building the polygon
450 * @return a polygon indicating the cell extent
452 std::auto_ptr
<geom::Geometry
> getVoronoiCellPolygon(QuadEdge
* qe
,const geom::GeometryFactory
& geomFact
);
455 } //namespace geos.triangulate.quadedge
456 } //namespace geos.triangulate
459 #endif //GEOS_TRIANGULATE_QUADEDGE_QUADEDGESUBDIVISION_H