20 #ifndef ANTKEEPER_MATH_NOISE_VORONOI_HPP
21 #define ANTKEEPER_MATH_NOISE_VORONOI_HPP
46 template <std::
size_t N>
47 constexpr std::size_t kernel_size = 4 << std::max<std::size_t>(0, (2 * (N - 1)));
62 template <
class T, std::size_t N, std::size_t... I>
63 [[nodiscard]] constexpr
vector<T, N> kernel_offset(std::size_t i, std::index_sequence<I...>)
65 return {
static_cast<T
>((I ? (i / (2 << std::max<std::size_t>(0, 2 * I - 1))) : i) % 4)...};
79 template <
class T, std::size_t N, std::size_t... I>
80 [[nodiscard]] constexpr std::array<vector<T, N>, kernel_size<N>> generate_kernel(std::index_sequence<I...>)
82 return {kernel_offset<T, N>(I, std::make_index_sequence<N>{})...};
93 template <
class T, std::
size_t N>
94 constexpr
auto kernel = generate_kernel<T, N>(std::make_index_sequence<kernel_size<N>>{});
109 template <
class T, std::
size_t N>
110 [[nodiscard]] std::tuple
130 T hash_scale = (T{1} /
static_cast<T
>(std::numeric_limits<hash::make_uint_t<T>>::max())) * randomness;
134 vector<T, N> position_f =
position - position_i;
137 T f1_sqr_distance = std::numeric_limits<T>::infinity();
138 vector<T, N> f1_displacement;
139 hash::make_uint_t<T> f1_hash;
140 for (std::size_t i = 0; i < kernel_size<N>; ++i)
143 const vector<T, N>& offset_i = kernel<T, N>[i];
146 vector<T, N> hash_position = position_i + offset_i;
147 for (std::size_t j = 0; j < N; ++j)
151 hash_position[j] = std::fmod(hash_position[j], tiling[j]);
152 if (hash_position[j] < T{0})
153 hash_position[j] += tiling[j];
158 vector<hash::make_uint_t<T>, N> hash_i =
hash(hash_position);
161 vector<T, N> offset_f = vector<T, N>(hash_i) * hash_scale;
164 vector<T, N> displacement = (offset_i + offset_f) - position_f;
173 f1_displacement = displacement;
199 template <
class T, std::
size_t N>
200 [[nodiscard]] std::tuple
209 hash::make_uint_t<T>,
223 T hash_scale = (T{1} /
static_cast<T
>(std::numeric_limits<hash::make_uint_t<T>>::max())) * randomness;
227 vector<T, N> position_f =
position - position_i;
230 T f1_sqr_distance_center = std::numeric_limits<T>::infinity();
231 vector<T, N> displacement_cache[kernel_size<N>];
232 std::size_t f1_i = 0;
233 hash::make_uint_t<T> f1_hash;
234 for (std::size_t i = 0; i < kernel_size<N>; ++i)
237 const vector<T, N>& offset_i = kernel<T, N>[i];
240 vector<T, N> hash_position = position_i + offset_i;
241 for (std::size_t j = 0; j < N; ++j)
245 hash_position[j] = std::fmod(hash_position[j], tiling[j]);
246 if (hash_position[j] < T{0})
247 hash_position[j] += tiling[j];
252 vector<hash::make_uint_t<T>, N> hash_i =
hash(hash_position);
255 vector<T, N> offset_f = vector<T, N>(hash_i) * hash_scale;
258 displacement_cache[
i] = (offset_i + offset_f) - position_f;
273 const vector<T, N>& f1_displacement = displacement_cache[f1_i];
276 T edge_sqr_distance_edge = std::numeric_limits<T>::infinity();
277 for (std::size_t i = 0; i < kernel_size<N>; ++
i)
284 const vector<T, N>& displacement = displacement_cache[
i];
287 const vector<T, N> midpoint = (f1_displacement + displacement) * T{0.5};
290 const vector<T, N> direction =
normalize(displacement - f1_displacement);
302 f1_sqr_distance_center,
305 edge_sqr_distance_edge
322 template <
class T, std::
size_t N>
323 [[nodiscard]] std::tuple
332 hash::make_uint_t<T>,
352 T hash_scale = (T{1} /
static_cast<T
>(std::numeric_limits<hash::make_uint_t<T>>::max())) * randomness;
356 vector<T, N> position_f =
position - position_i;
359 T f1_sqr_distance_center = std::numeric_limits<T>::infinity();
360 vector<T, N> f1_displacement = {0, 0};
361 hash::make_uint_t<T> f1_hash = 0;
362 T f2_sqr_distance_center = std::numeric_limits<T>::infinity();
363 vector<T, N> f2_displacement = {0, 0};
364 hash::make_uint_t<T> f2_hash = 0;
365 for (std::size_t i = 0; i < kernel_size<N>; ++
i)
368 const vector<T, N>& offset_i = kernel<T, N>[
i];
371 vector<T, N> hash_position = position_i + offset_i;
372 for (std::size_t j = 0;
j < N; ++
j)
376 hash_position[
j] = std::fmod(hash_position[j], tiling[j]);
377 if (hash_position[j] < T{0})
378 hash_position[j] += tiling[j];
383 vector<hash::make_uint_t<T>, N> hash_i =
hash(hash_position);
386 vector<T, N> offset_f = vector<T, N>(hash_i) * hash_scale;
389 vector<T, N> displacement = (offset_i + offset_f) - position_f;
397 f2_sqr_distance_center = f1_sqr_distance_center;
398 f2_displacement = f1_displacement;
402 f1_displacement = displacement;
408 f2_displacement = displacement;
415 f1_sqr_distance_center,
418 f2_sqr_distance_center,
typename make_uint< T >::type make_uint_t
Helper type for make_uint.
std::tuple< T, vector< T, N >, hash::make_uint_t< T >> f1(const vector< T, N > &position, T randomness=T{1}, const vector< T, N > &tiling=vector< T, N >::zero(), vector< hash::make_uint_t< T >, N >(*hash)(const vector< T, N > &)=&hash::pcg< T, N >)
Finds the Voronoi cell (F1) containing the input position.
std::tuple< T, vector< T, N >, hash::make_uint_t< T >, T > f1_edge(const vector< T, N > &position, T randomness=T{1}, const vector< T, N > &tiling=vector< T, N >::zero(), vector< hash::make_uint_t< T >, N >(*hash)(const vector< T, N > &)=&hash::pcg< T, N >)
Finds the Voronoi cell (F1) containing the input position, along with the distance to the nearest edg...
std::tuple< T, vector< T, N >, hash::make_uint_t< T >, T, vector< T, N >, hash::make_uint_t< T >> f1_f2(const vector< T, N > &position, T randomness=T{1}, const vector< T, N > &tiling=vector< T, N >::zero(), vector< hash::make_uint_t< T >, N >(*hash)(const vector< T, N > &)=&hash::pcg< T, N >)
Finds the Voronoi cell (F1) containing the input position, as well as the nearest neighboring cell (F...
Mathematical functions and data types.
constexpr T sqr_distance(const vector< T, N > &p0, const vector< T, N > &p1) noexcept
Calculates the square distance between two points.
constexpr vector< T, N > floor(const vector< T, N > &x)
Performs a element-wise floor operation.
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
constexpr T sqr_length(const quaternion< T > &q) noexcept
Calculates the square length of a quaternion.
constexpr T dot(const quaternion< T > &a, const quaternion< T > &b) noexcept
Calculates the dot product of two quaternions.
@ position
Vertex position (vec3)
static constexpr vector zero() noexcept
Returns a zero vector, where every element is equal to zero.