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 /// 简单的双连通边链表结构。它只允许添加元素,不允许删除元素。
19 class CARLA_API DoublyConnectedEdgeList : private NonCopyable
20 {
21 // =========================================================================
22 // -- DCEL 类型 -----------------------------------------------------------
23 // =========================================================================
24
25 public:
26
28
29 struct Node;
30 struct HalfEdge;
31 struct Face;
32
33 struct Node : public GraphNode
34 {
36
37 Node(const Position &Pos) : Position(Pos) {}
38
39 Node &operator=(const Node &) = delete;
40
42 {
43 return Position;
44 }
45
46 private:
48 HalfEdge *LeavingHalfEdge = nullptr;
49 };
50
51 struct HalfEdge : public GraphHalfEdge
52 {
54
55 HalfEdge &operator=(const HalfEdge &) = delete;
56
57 private:
58 Node *Source = nullptr;
59 Node *Target = nullptr;
60 HalfEdge *Next = nullptr;
61 HalfEdge *Pair = nullptr;
62 Face *Face = nullptr;
63 };
64
65 struct Face : public GraphFace
66 {
68
69 Face &operator=(const Face &) = delete;
70
71 private:
72 HalfEdge *HalfEdge = nullptr;
73 };
74
75 using NodeContainer = std::list<Node>;
76 using NodeIterator = typename NodeContainer::iterator;
77 using ConstNodeIterator = typename NodeContainer::const_iterator;
78
79 using HalfEdgeContainer = std::list<HalfEdge>;
80 using HalfEdgeIterator = typename HalfEdgeContainer::iterator;
81 using ConstHalfEdgeIterator = typename HalfEdgeContainer::const_iterator;
82
83 using FaceContainer = std::list<Face>;
84 using FaceIterator = typename FaceContainer::iterator;
85 using ConstFaceIterator = typename FaceContainer::const_iterator;
86
87 // =========================================================================
88 // -- 构造函数和析构函数 ----------------------------------------------------
89 // =========================================================================
90
91 public:
92
93 /// 创建一个有2个节点、2个边和1个面的双连通边链表DoublyConnectedEdgeList。
94 explicit DoublyConnectedEdgeList(const Position &Position0, const Position &Position1);
95
96 /// 创建一个由N个节点组成双连通链表DoublyConnectedEdgeList环。
97 template <size_t N>
98 explicit DoublyConnectedEdgeList(const std::array<Position, N> &Cycle)
99 : DoublyConnectedEdgeList(Cycle[0u], Cycle[1u])
100 {
101 static_assert(N > 2u, "Not enough nodes to make a cycle!");
102 for (auto i = 2u; i < Cycle.size(); ++i) {
103 AddNode(Cycle[i], Nodes.back());
104 }
105 ConnectNodes(Nodes.front(), Nodes.back());
106 }
107
109
110 // =========================================================================
111 /// @name 向图中添加元素-----------------------------------------------------
112 // =========================================================================
113 /// {
114 public:
115
116 /// Add a node at @a NodePosition and attach it to @a OtherNode.
117 ///
118 /// 时间复杂度为 O(n*log(n)),其中 n 是离开节点 @a OtherNode 的边数。
119 ///
120 /// @return 新生成的节点。
121 Node &AddNode(const Position &NodePosition, Node &OtherNode);
122
123 /// 在 @a 位置分割 @a HalfEdge (和它的配对)
124 ///
125 /// 时间复杂度为 O(n*log(n)),其中 n 是离开 @a HalfEdge 源的边数
126 ///
127 /// @return 新生成的节点。
128 Node &SplitEdge(const Position &Position, HalfEdge &HalfEdge);
129
130 /// 用一对边连接两个节点。
131 ///
132 /// 假设两个节点由同一面连接。
133 ///
134 /// 时间复杂度为 O(n0*log(n0) + n1*log(n1) + nf),
135 /// 其中 n0 和 n1 分别是离开节点 @a Node0 和节点 @a Node1 的边数。
136 /// 并且 nf 是包含两个节点的面的边数。
137 ///
138 /// @return 新生成的面。
139 Face &ConnectNodes(Node &Node0, Node &Node1);
140
141 /// @}
142 // =========================================================================
143 /// @name 统计图元素的数目 --------------------------------------------------
144 // =========================================================================
145 /// @{
146 public:
147
148 size_t CountNodes() const
149 {
150 return Nodes.size();
151 }
152
153 size_t CountHalfEdges() const
154 {
155 return HalfEdges.size();
156 }
157
158 size_t CountFaces() const
159 {
160 return Faces.size();
161 }
162
163 /// @}
164 // =========================================================================
165 /// @name 访问图的元素 ------------------------------------------------------
166 // =========================================================================
167 /// @{
168 public:
169
174
179
184
189
194
199
200 /// @}
201 // =========================================================================
202 /// @name 访问图指针 --------------------------------------------------------
203 // =========================================================================
204 /// @{
205 public:
206
207 // -- 主要指针 --------------------------------------------------------------
208
209 static Node &GetSource(HalfEdge &halfEdge)
210 {
211 check(halfEdge.Source != nullptr);
212 return *halfEdge.Source;
213 }
214
215 static const Node &GetSource(const HalfEdge &halfEdge)
216 {
217 check(halfEdge.Source != nullptr);
218 return *halfEdge.Source;
219 }
220
221 static Node &GetTarget(HalfEdge &halfEdge)
222 {
223 check(halfEdge.Target != nullptr);
224 return *halfEdge.Target;
225 }
226
227 static const Node &GetTarget(const HalfEdge &halfEdge)
228 {
229 check(halfEdge.Target != nullptr);
230 return *halfEdge.Target;
231 }
232
233 static HalfEdge &GetPair(HalfEdge &halfEdge)
234 {
235 check(halfEdge.Pair != nullptr);
236 return *halfEdge.Pair;
237 }
238
239 static const HalfEdge &GetPair(const HalfEdge &halfEdge)
240 {
241 check(halfEdge.Pair != nullptr);
242 return *halfEdge.Pair;
243 }
244
245 static Face &GetFace(HalfEdge &halfEdge)
246 {
247 check(halfEdge.Face != nullptr);
248 return *halfEdge.Face;
249 }
250
251 static const Face &GetFace(const HalfEdge &halfEdge)
252 {
253 check(halfEdge.Face != nullptr);
254 return *halfEdge.Face;
255 }
256
258 {
259 check(node.LeavingHalfEdge != nullptr);
260 return *node.LeavingHalfEdge;
261 }
262
263 static const HalfEdge &GetLeavingHalfEdge(const Node &node)
264 {
265 check(node.LeavingHalfEdge != nullptr);
266 return *node.LeavingHalfEdge;
267 }
268
269 static HalfEdge &GetHalfEdge(Face &face)
270 {
271 check(face.HalfEdge != nullptr);
272 return *face.HalfEdge;
273 }
274
275 static const HalfEdge &GetHalfEdge(const Face &face)
276 {
277 check(face.HalfEdge != nullptr);
278 return *face.HalfEdge;
279 }
280
281 // -- 二级指针 ------------------------------------------------------------
282
283 static HalfEdge &GetNextInFace(HalfEdge &halfEdge)
284 {
285 check(halfEdge.Next != nullptr);
286 return *halfEdge.Next;
287 }
288
289 static const HalfEdge &GetNextInFace(const HalfEdge &halfEdge)
290 {
291 check(halfEdge.Next != nullptr);
292 return *halfEdge.Next;
293 }
294
295 static HalfEdge &GetNextInNode(HalfEdge &halfEdge)
296 {
297 return GetNextInFace(GetPair(halfEdge));
298 }
299
300 static const HalfEdge &GetNextInNode(const HalfEdge &halfEdge)
301 {
302 return GetNextInFace(GetPair(halfEdge));
303 }
304
305 /// @}
306 // =========================================================================
307 /// @name 其他成员函数 ------------------------------------------------------
308 // =========================================================================
309 /// @{
310 public:
311
312 /// 返回 half-edge 的角度,范围为 [-pi, pi]
313 static float GetAngle(const HalfEdge &halfEdge);
314
315#ifdef CARLA_ROAD_GENERATOR_EXTRA_LOG
316 void PrintToLog() const;
317 #endif // CARLA_ROAD_GENERATOR_EXTRA_LOG
318
319 /// @}
320 // =========================================================================
321 // -- 私有成员 --------------------------------------------------------------
322 // =========================================================================
323
324 private:
325
327
329
331 };
332
333} // namespace MapGen
简单的双连通边链表结构。它只允许添加元素,不允许删除元素。
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)
创建一个由N个节点组成双连通链表DoublyConnectedEdgeList环。
Face & operator=(const Face &)=delete
HalfEdge & operator=(const HalfEdge &)=delete
DoublyConnectedEdgeList::Position Position
const DoublyConnectedEdgeList::Position & GetPosition() const
Node & operator=(const Node &)=delete