CARLA
 
载入中...
搜索中...
未找到
DoublyConnectedEdgeList.h
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#pragma once
8
9#include "GraphTypes.h"
10#include "Position.h"
11#include "Util/ListView.h"
12
13#include <array>
14#include <list>
15
16namespace MapGen {
17
18 /// Simple doubly-connected edge list structure. It only allows adding
19 /// elements, not removing them.
20 class CARLA_API DoublyConnectedEdgeList : private NonCopyable
21 {
22 // =========================================================================
23 // -- DCEL types -----------------------------------------------------------
24 // =========================================================================
25
26 public:
27
29
30 struct Node;
31 struct HalfEdge;
32 struct Face;
33
34 struct Node : public GraphNode
35 {
37
38 Node(const Position &Pos) : Position(Pos) {}
39
40 Node &operator=(const Node &) = delete;
41
43 {
44 return Position;
45 }
46
47 private:
49 HalfEdge *LeavingHalfEdge = nullptr;
50 };
51
52 struct HalfEdge : public GraphHalfEdge
53 {
55
56 HalfEdge &operator=(const HalfEdge &) = delete;
57
58 private:
59 Node *Source = nullptr;
60 Node *Target = nullptr;
61 HalfEdge *Next = nullptr;
62 HalfEdge *Pair = nullptr;
63 Face *Face = nullptr;
64 };
65
66 struct Face : public GraphFace
67 {
69
70 Face &operator=(const Face &) = delete;
71
72 private:
73 HalfEdge *HalfEdge = nullptr;
74 };
75
76 using NodeContainer = std::list<Node>;
77 using NodeIterator = typename NodeContainer::iterator;
78 using ConstNodeIterator = typename NodeContainer::const_iterator;
79
80 using HalfEdgeContainer = std::list<HalfEdge>;
81 using HalfEdgeIterator = typename HalfEdgeContainer::iterator;
82 using ConstHalfEdgeIterator = typename HalfEdgeContainer::const_iterator;
83
84 using FaceContainer = std::list<Face>;
85 using FaceIterator = typename FaceContainer::iterator;
86 using ConstFaceIterator = typename FaceContainer::const_iterator;
87
88 // =========================================================================
89 // -- Constructors and destructor ------------------------------------------
90 // =========================================================================
91
92 public:
93
94 /// Create a DoublyConnectedEdgeList with two nodes, two edges and one face.
95 explicit DoublyConnectedEdgeList(const Position &Position0, const Position &Position1);
96
97 /// Create a DoublyConnectedEdgeList consisting of a cycle of N nodes.
98 template <size_t N>
99 explicit DoublyConnectedEdgeList(const std::array<Position, N> &Cycle)
100 : DoublyConnectedEdgeList(Cycle[0u], Cycle[1u])
101 {
102 static_assert(N > 2u, "Not enough nodes to make a cycle!");
103 for (auto i = 2u; i < Cycle.size(); ++i) {
104 AddNode(Cycle[i], Nodes.back());
105 }
106 ConnectNodes(Nodes.front(), Nodes.back());
107 }
108
110
111 // =========================================================================
112 /// @name Adding elements to the graph -------------------------------------
113 // =========================================================================
114 /// {
115 public:
116
117 /// Add a node at @a NodePosition and attach it to @a OtherNode.
118 ///
119 /// The time complexity is O(n*log(n)) where n is the number of edges
120 /// leaving @a OtherNode.
121 ///
122 /// @return The newly generated node.
123 Node &AddNode(const Position &NodePosition, Node &OtherNode);
124
125 /// Split @a HalfEdge (and its pair) at @a Position.
126 ///
127 /// The time complexity is O(n*log(n)) where n is the number of edges
128 /// leaving @a HalfEdge's source.
129 ///
130 /// @return The newly generated node.
131 Node &SplitEdge(const Position &Position, HalfEdge &HalfEdge);
132
133 /// Connect two nodes by a pair of edges.
134 ///
135 /// It is assumed that both nodes are connected by the same face.
136 ///
137 /// The time complexity is O(n0*log(n0) + n1*log(n1) + nf) where n0 and n1
138 /// are the number of edges leaving @a Node0 and @a Node1 respectively, and
139 /// nf is the number of edges in the face containing both nodes.
140 ///
141 /// @return The newly generated face.
142 Face &ConnectNodes(Node &Node0, Node &Node1);
143
144 /// @}
145 // =========================================================================
146 /// @name Counting graph elements ------------------------------------------
147 // =========================================================================
148 /// @{
149 public:
150
151 size_t CountNodes() const
152 {
153 return Nodes.size();
154 }
155
156 size_t CountHalfEdges() const
157 {
158 return HalfEdges.size();
159 }
160
161 size_t CountFaces() const
162 {
163 return Faces.size();
164 }
165
166 /// @}
167 // =========================================================================
168 /// @name Accessing graph elements -----------------------------------------
169 // =========================================================================
170 /// @{
171 public:
172
177
182
187
192
197
202
203 /// @}
204 // =========================================================================
205 /// @name Accessing graph pointers -----------------------------------------
206 // =========================================================================
207 /// @{
208 public:
209
210 // -- Primary pointers -----------------------------------------------------
211
212 static Node &GetSource(HalfEdge &halfEdge)
213 {
214 check(halfEdge.Source != nullptr);
215 return *halfEdge.Source;
216 }
217
218 static const Node &GetSource(const HalfEdge &halfEdge)
219 {
220 check(halfEdge.Source != nullptr);
221 return *halfEdge.Source;
222 }
223
224 static Node &GetTarget(HalfEdge &halfEdge)
225 {
226 check(halfEdge.Target != nullptr);
227 return *halfEdge.Target;
228 }
229
230 static const Node &GetTarget(const HalfEdge &halfEdge)
231 {
232 check(halfEdge.Target != nullptr);
233 return *halfEdge.Target;
234 }
235
236 static HalfEdge &GetPair(HalfEdge &halfEdge)
237 {
238 check(halfEdge.Pair != nullptr);
239 return *halfEdge.Pair;
240 }
241
242 static const HalfEdge &GetPair(const HalfEdge &halfEdge)
243 {
244 check(halfEdge.Pair != nullptr);
245 return *halfEdge.Pair;
246 }
247
248 static Face &GetFace(HalfEdge &halfEdge)
249 {
250 check(halfEdge.Face != nullptr);
251 return *halfEdge.Face;
252 }
253
254 static const Face &GetFace(const HalfEdge &halfEdge)
255 {
256 check(halfEdge.Face != nullptr);
257 return *halfEdge.Face;
258 }
259
261 {
262 check(node.LeavingHalfEdge != nullptr);
263 return *node.LeavingHalfEdge;
264 }
265
266 static const HalfEdge &GetLeavingHalfEdge(const Node &node)
267 {
268 check(node.LeavingHalfEdge != nullptr);
269 return *node.LeavingHalfEdge;
270 }
271
272 static HalfEdge &GetHalfEdge(Face &face)
273 {
274 check(face.HalfEdge != nullptr);
275 return *face.HalfEdge;
276 }
277
278 static const HalfEdge &GetHalfEdge(const Face &face)
279 {
280 check(face.HalfEdge != nullptr);
281 return *face.HalfEdge;
282 }
283
284 // -- Secondary pointers ---------------------------------------------------
285
286 static HalfEdge &GetNextInFace(HalfEdge &halfEdge)
287 {
288 check(halfEdge.Next != nullptr);
289 return *halfEdge.Next;
290 }
291
292 static const HalfEdge &GetNextInFace(const HalfEdge &halfEdge)
293 {
294 check(halfEdge.Next != nullptr);
295 return *halfEdge.Next;
296 }
297
298 static HalfEdge &GetNextInNode(HalfEdge &halfEdge)
299 {
300 return GetNextInFace(GetPair(halfEdge));
301 }
302
303 static const HalfEdge &GetNextInNode(const HalfEdge &halfEdge)
304 {
305 return GetNextInFace(GetPair(halfEdge));
306 }
307
308 /// @}
309 // =========================================================================
310 /// @name Other member functions -------------------------------------------
311 // =========================================================================
312 /// @{
313 public:
314
315 /// Return the angle [-pi, pi] of the half-edge.
316 static float GetAngle(const HalfEdge &halfEdge);
317
318#ifdef CARLA_ROAD_GENERATOR_EXTRA_LOG
319 void PrintToLog() const;
320 #endif // CARLA_ROAD_GENERATOR_EXTRA_LOG
321
322 /// @}
323 // =========================================================================
324 // -- Private members ------------------------------------------------------
325 // =========================================================================
326
327 private:
328
330
332
334 };
335
336} // namespace MapGen
Simple doubly-connected edge list structure.
typename HalfEdgeContainer::const_iterator ConstHalfEdgeIterator
typename HalfEdgeContainer::iterator HalfEdgeIterator
ListView< HalfEdgeIterator > GetHalfEdges()
ListView< ConstFaceIterator > GetFaces() const
static const Face & GetFace(const HalfEdge &halfEdge)
ListView< ConstHalfEdgeIterator > GetHalfEdges() const
static const Node & GetSource(const HalfEdge &halfEdge)
static HalfEdge & GetHalfEdge(Face &face)
static Node & GetTarget(HalfEdge &halfEdge)
typename NodeContainer::const_iterator ConstNodeIterator
ListView< ConstNodeIterator > GetNodes() const
static HalfEdge & GetLeavingHalfEdge(Node &node)
static HalfEdge & GetPair(HalfEdge &halfEdge)
static const Node & GetTarget(const HalfEdge &halfEdge)
static Face & GetFace(HalfEdge &halfEdge)
static const HalfEdge & GetPair(const HalfEdge &halfEdge)
static Node & GetSource(HalfEdge &halfEdge)
typename FaceContainer::iterator FaceIterator
static HalfEdge & GetNextInNode(HalfEdge &halfEdge)
typename NodeContainer::iterator NodeIterator
static const HalfEdge & GetHalfEdge(const Face &face)
static HalfEdge & GetNextInFace(HalfEdge &halfEdge)
static const HalfEdge & GetNextInFace(const HalfEdge &halfEdge)
static const HalfEdge & GetNextInNode(const HalfEdge &halfEdge)
static const HalfEdge & GetLeavingHalfEdge(const Node &node)
typename FaceContainer::const_iterator ConstFaceIterator
DoublyConnectedEdgeList(const std::array< Position, N > &Cycle)
Create a DoublyConnectedEdgeList consisting of a cycle of N nodes.
Face & operator=(const Face &)=delete
HalfEdge & operator=(const HalfEdge &)=delete
DoublyConnectedEdgeList::Position Position
const DoublyConnectedEdgeList::Position & GetPosition() const
Node & operator=(const Node &)=delete