A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
hex-grid-position-allocator.h
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0-only
3 *
4 * Author: Davide Magrin <magrinda@dei.unipd.it>
5 */
6
7#ifndef HEX_GRID_POSITION_ALLOCATOR_H
8#define HEX_GRID_POSITION_ALLOCATOR_H
9
10#include "ns3/position-allocator.h"
11
12#include <cmath>
13
14namespace ns3
15{
16
17/**
18 * \ingroup lorawan
19 *
20 * Position allocator for hexagonal tiling.
21 *
22 * Starting with a first hexagon in the axes' center, following tiles are added in outward
23 * rings. The first position returned for a new ring is always the top one, followed by the others
24 * in anti-clockwise rotation.
25 *
26 * Visual example with 10 tiles, indexed 0-9:
27 *
28 * _____
29 * / \
30 * _____/ 8 \
31 * / \ ˙ /
32 * / 9 \_____/
33 * \ ˙ / \
34 * next \_____/ 1 \_____
35 * ˙ / \ ˙ / \
36 * / 2 \_____/ 7 \
37 * \ ˙ / \ ˙ /
38 * \_____/ 0 \_____/
39 * / \ ˙ / \
40 * / 3 \_____/ 5 \
41 * \ ˙ / \ ˙ /
42 * \_____/ 4 \_____/
43 * \ ˙ /
44 * \_____/
45 *
46 * The size of tiles can be configured by setting the radius \f$\rho_{i}\f$ of the circle
47 * \b inscribed within hexagons (i.e., the internal circle).
48 *
49 * Let's say that we are placing access points, and we want to cover a square/circular area with
50 * hexagonal tiles. This leaves us with two questions: (i) which value should we choose for the
51 * internal radius? (ii) how many access point nodes (i.e., tiles) do we need to instantiate?
52 *
53 * For instance, to guarantee that no point is further than 1km from the center of any tile (i.e.,
54 * to have no uncovered patches), we can choose the radius \f$\rho_{c}\f$ of the
55 * \b circumscribed (external) circle of each hexagonal tile to be exactly 1km. Then, question
56 * (i) can be solved by setting the internal radius to \f$\rho_{i}=\frac{\sqrt{3}}{2}\rho_{c}\f$
57 * using the properties of equilateral triangles.
58 *
59 * To understand how many tiles need to be instantiated (that is, in this example, the number of
60 * access point nodes), it is often useful to start from the complete area's diagonal or radius, and
61 * to derive the number of complete rings \f$r\f$ required for coverage. Let's say we want to be
62 * able to cover a distance of at least \f$d\f$ km from the center. One way to do this can be to
63 * take the floor of \f$d\f$ divided by the distance between access points (the tiles' centers),
64 * which happens to be \f$2\rho_{i}\f$, and adding one/two ring for good measure. More formally,
65 * starting from a single central tile, we would need at least
66 * \f$r=\left\lfloor\frac{d}{2\rho_{i}}\right\rfloor+1\f$ \b additional rings around it. Then,
67 * the total number of tiles \f$n\f$ in a tiling of \f$r\f$ complete rings around a central tile
68 * evaluates to \f$n=3r^{2}-3r+1\f$ providing a possible solution for question (ii).
69 *
70 * \todo Move this into the module .rst documentation
71 */
73{
74 public:
75 HexGridPositionAllocator(); //!< Default constructor
76 ~HexGridPositionAllocator() override; //!< Destructor
77
78 /**
79 * Construct a new HexGridPositionAllocator object with given radius.
80 *
81 * \param radius The radius length of the circle inscribed in the hexagonal tiles.
82 */
83 HexGridPositionAllocator(double radius);
84
85 Vector GetNext() const override;
86
87 int64_t AssignStreams(int64_t stream) override;
88
89 /**
90 * Register this type.
91 * \return The object TypeId.
92 */
93 static TypeId GetTypeId();
94
95 /**
96 * Get the radius of the circle inscribed in the hexagonal tiles.
97 *
98 * \return The radius length.
99 */
100 double GetRadius() const;
101
102 /**
103 * Set the radius of the circle inscribed in the hexagonal tiles.
104 *
105 * \param radius The radius length.
106 */
107 void SetRadius(double radius);
108
109 private:
110 /**
111 * This method adds to the given list of positions an outer ring of positions.
112 *
113 * \param positions The list of position around which to create the new positions.
114 * \return The input list of position with an added outer ring.
115 */
116 std::vector<Vector> AddRing(std::vector<Vector> positions);
117
118 std::vector<Vector> m_positions; //!< The current list of positions
119 mutable std::vector<Vector>::const_iterator
120 m_next; //!< The iterator pointing to the next position to return
121 double m_radius; //!< The radius of a cell (defined as the half the distance between two
122 //!< adjacent nodes, that is, the radius of the circle inscribed in each
123 //!< hexagonal tile)
124
125 const static double pi; //!< Pi
126};
127
128} // namespace ns3
129
130#endif /* PERIODIC_SENDER_HELPER_H */
Position allocator for hexagonal tiling.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
void SetRadius(double radius)
Set the radius of the circle inscribed in the hexagonal tiles.
static TypeId GetTypeId()
Register this type.
std::vector< Vector > AddRing(std::vector< Vector > positions)
This method adds to the given list of positions an outer ring of positions.
double GetRadius() const
Get the radius of the circle inscribed in the hexagonal tiles.
double m_radius
The radius of a cell (defined as the half the distance between two adjacent nodes,...
std::vector< Vector > m_positions
The current list of positions.
std::vector< Vector >::const_iterator m_next
The iterator pointing to the next position to return.
Allocate a set of positions.
a unique identifier for an interface.
Definition type-id.h:48
Every class exported by the ns3 library is enclosed in the ns3 namespace.