Corentin Chauvin-Hameau – 2019-2020
Coverage Path Planning for an underwater robot surveying a marine farm
perlin_noise.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  *
4  * \brief Declaration of 2D perlin noise generator
5  * \author Corentin Chauvin-Hameau
6  * \date 2019
7  */
8 
9 #ifndef PERLIN_NOISE_HPP
10 #define PERLIN_NOISE_HPP
11 
12 #include <random>
13 #include <vector>
14 #include <algorithm>
15 #include <iostream>
16 
17 namespace mfcpp {
18  /**
19  * \brief Perlin noise generator
20  */
22  public:
23  /**
24  * \brief Default constructor
25  */
27 
28  /**
29  * \brief Constructor initialising the generator with the given parameters
30  *
31  * \param height Height of the 2D space in which to generate the noise
32  * \param width Width of the 2D space in which to generate the noise
33  * \param n_height Size of the discretised grid in the first dimension
34  * \param n_width Size of the discretised grid in the second dimensio
35  * \param seed Seed for randomisation (0 for random seeding)
36  */
37  PerlinNoiseGenerator(float height, float width, unsigned int n_height,
38  unsigned int n_width, unsigned long int seed=0);
39 
41 
42  /**
43  * \brief Configures the generator
44  *
45  * \param height Height of the 2D space in which to generate the noise
46  * \param width Width of the 2D space in which to generate the noise
47  * \param n_height Size of the discretised grid in the first dimension
48  * \param n_width Size of the discretised grid in the second dimension
49  * \param seed Seed for randomisation (0 for random seeding)
50  */
51  void configure(float height, float width, unsigned int n_height,
52  unsigned int n_width, unsigned long int seed=0);
53 
54  /**
55  * \brief Fills the hash list with random gradients
56  */
57  void randomise_gradients();
58 
59  /**
60  * \brief Populates the grid with random gradients from the hash list
61  *
62  * \param seed Seed for randomisation (0 for random seeding)
63  */
64  void generate(unsigned long int seed=0);
65 
66  /**
67  * \brief Evaluates the perlin noise at a given position
68  *
69  * \param x First coordinate where to evaluate
70  * \param y Second coordinate where to evaluate
71  * \return Perlin noise value at (x, y)
72  */
73  double evaluate(float x, float y) const;
74 
75  /**
76  * \brief Applies a polynomial to accentuate the given value
77  *
78  * Values under 0.5 are pushed towards 0, while values above 0.5 are
79  * pushed towards 1.
80  *
81  * \param x Given value
82  * \return Accentuated value
83  */
84  inline float accentuate(float x) const;
85 
86  private:
87  /**
88  * \brief Two dimensional vector
89  */
90  struct Vec2d {
91  float x; ///< First coordinate
92  float y; ///< Second coordinate
93 
94  Vec2d();
95  Vec2d(float _x, float _y);
96  void operator=(const Vec2d &a);
97 
98  /**
99  * \brief Computes the square of the euclidean norm of the vector
100  * \return Square of the euclidean norm of the vector
101  */
102  float norm2();
103 
104  /**
105  * \brief Computes the euclidean norm of the vector
106  * \return Euclidean norm of the vector
107  */
108  float norm();
109  };
110 
111  /// Height of the 2D space in which to generate the noise
112  float height_;
113 
114  /// Width of the 2D space in which to generate the noise
115  float width_;
116 
117  /// Size of the discretised grid in the first dimension
118  unsigned int n_height_;
119 
120  /// Size of the discretised grid in the second dimension
121  unsigned int n_width_;
122 
123  /// Gradients evaluated at nodes of the grid
124  std::vector<std::vector<Vec2d>> gradients_;
125 
126  /// Hash list of random gradients
127  std::vector<Vec2d> hash_gradients_;
128 
129  /// Whether to randomise seeding for random numbers
131 
132  /// Seed for random numbers when no random seeding
133  unsigned long int seed_;
134 
135  /// Seed initialiser for generation of random numbers
136  std::random_device random_device_;
137 
138  /**
139  * \brief Initialises random generation
140  *
141  * \param seed Seed to use for initialisation. If 0, random seeding
142  */
143  void init_random(unsigned long int seed);
144 
145  /**
146  * \brief Computes the dot product between two vectors
147  *
148  * \param u First vector
149  * \param v Second vector
150  * \return Dot product between u and v
151  */
152  float dot_product(Vec2d u, Vec2d v) const;
153 
154  /**
155  * \brief Compute the dot product of the distance vector to the node an
156  * the gradient at this node
157  *
158  * \param i Index of the node for the first dimension
159  * \param j Index of the node for the second dimension
160  * \param x First coordinate of the evaluated point
161  * \param y Second coordinate of the evaluated point
162  */
163  float dot_dist_grad(unsigned int i, unsigned int j, float x, float y) const;
164 
165  /**
166  * \brief Linear interpolation between two values
167  *
168  * \param a First value to interpolate
169  * \param b Second value to interpolate
170  * \param t Interpolation ratio
171  * \return Interpolation between a and b
172  */
173  float interpolate(float a, float b, float t) const;
174 
175 
176  /**
177  * \brief Sixth order polynomial to smooth the noise
178  *
179  * \param t Number between 0 and 1
180  * \return 6t^5 - 15t^4 + 10t^3
181  */
182  inline float fade(float t) const;
183  };
184 
185 
186  /*
187  * Defintion of inline functions
188  */
189  inline float PerlinNoiseGenerator::fade(float t) const
190  {
191  return t * t * t * (t * (t * 6 - 15) + 10); // 6t^5 - 15t^4 + 10t^3
192  }
193 
194 
195  inline float PerlinNoiseGenerator::accentuate(float x) const
196  {
197  return fade(fade(fade(fade(x))));
198  }
199 
200 }
201 
202 #endif
float norm2()
Computes the square of the euclidean norm of the vector.
float fade(float t) const
Sixth order polynomial to smooth the noise.
Definition: common.hpp:23
std::vector< std::vector< Vec2d > > gradients_
Gradients evaluated at nodes of the grid.
float dot_product(Vec2d u, Vec2d v) const
Computes the dot product between two vectors.
void init_random(unsigned long int seed)
Initialises random generation.
float height_
Height of the 2D space in which to generate the noise.
float width_
Width of the 2D space in which to generate the noise.
Perlin noise generator.
float interpolate(float a, float b, float t) const
Linear interpolation between two values.
void configure(float height, float width, unsigned int n_height, unsigned int n_width, unsigned long int seed=0)
Configures the generator.
unsigned int n_height_
Size of the discretised grid in the first dimension.
bool randomise_seed_
Whether to randomise seeding for random numbers.
float y
Second coordinate.
std::random_device random_device_
Seed initialiser for generation of random numbers.
float accentuate(float x) const
Applies a polynomial to accentuate the given value.
void generate(unsigned long int seed=0)
Populates the grid with random gradients from the hash list.
unsigned int n_width_
Size of the discretised grid in the second dimension.
Two dimensional vector.
unsigned long int seed_
Seed for random numbers when no random seeding.
void randomise_gradients()
Fills the hash list with random gradients.
std::vector< Vec2d > hash_gradients_
Hash list of random gradients.
float dot_dist_grad(unsigned int i, unsigned int j, float x, float y) const
Compute the dot product of the distance vector to the node an the gradient at this node...
PerlinNoiseGenerator()
Default constructor.
float norm()
Computes the euclidean norm of the vector.
double evaluate(float x, float y) const
Evaluates the perlin noise at a given position.