header_utils
Loading...
Searching...
No Matches
random_geom.h
1
4
5#pragma once
6
7#include "random.h"
8#include "rec2.h"
9#include "geometry/ellipse.h"
10#include "geometry/polygon.h"
11#include "geometry/shape_concepts.h"
12
13namespace ghassanpl::random
14{
15 template <std::floating_point T = float, typename RANDOM = std::default_random_engine>
17 {
18 static std::uniform_real_distribution<T> dist{ T{}, glm::two_pi<T>() };
19 return dist(rng);
20 }
21
22 template <std::floating_point T = float, typename RANDOM = std::default_random_engine>
24 {
25 static std::uniform_real_distribution<T> dist{ T{}, T{360} };
26 return dist(rng);
27 }
28
29 template <std::floating_point T = float, typename RANDOM = std::default_random_engine>
30 glm::tvec2<T> unit_vector(RANDOM& rng = ::ghassanpl::random::default_random_engine)
31 {
32 return glm::rotate(glm::tvec2<T>{ T{ 1 }, T{ 0 } }, radians<T>(rng));
33 }
34
35 template <typename T, typename RANDOM = std::default_random_engine>
36 glm::tvec2<T> point_in(trec2<T> const& rect, RANDOM& rng = ::ghassanpl::random::default_random_engine)
37 {
38 return { range(rect.p1.x, rect.p2.x, rng), range(rect.p1.y, rect.p2.y, rng) };
39 }
40
41 template <typename T, typename RANDOM = std::default_random_engine>
42 glm::tvec2<T> point_in(glm::tvec2<T> const& max, RANDOM& rng = ::ghassanpl::random::default_random_engine)
43 {
44 return { range(T{}, max.x, rng), range(T{}, max.y, rng) };
45 }
46
48 template <typename T, typename RANDOM = std::default_random_engine>
49 glm::tvec2<T> point_in(geometry::tellipse<T> const& el, RANDOM& rng = ::ghassanpl::random::default_random_engine)
50 {
51 const auto phi = range(T{}, glm::two_pi<T>(), rng);
52 const auto p = glm::tvec2<T>{ cos(phi), sin(phi) } * glm::sqrt(percentage<T>(rng)) * el.radii * T(0.5);
53 return p + el.center;
54 }
55
56 template <typename T, typename RANDOM = std::default_random_engine>
57 glm::tvec2<T> point_in(geometry::ttriangle<T> const& tr, RANDOM& rng = ::ghassanpl::random::default_random_engine)
58 {
59 const auto r1 = glm::sqrt(percentage<T>(rng));
60 const auto r2 = percentage<T>(rng);
61
62 return (tr.a * (T(1) - r1) + tr.b * (r1 * (T(1) - r2)) + tr.c * (r2 * r1));
63 }
64
65 template <typename T, typename RANDOM = std::default_random_engine>
66 glm::tvec2<T> point_in(geometry::immutable::tpolygon<T> const& poly, RANDOM& rng = ::ghassanpl::random::default_random_engine)
67 {
68 if (poly.triangles().empty()) return {};
69
70 auto r = range(T{}, poly.calculate_area());
71 size_t i = 0;
72 while (r > 0.0)
73 {
74 if (!poly.has_triangle(i))
75 return {};
76
77 r -= poly.triangle_area(i);
78 if (r <= 0.0)
79 break;
80 i++;
81 }
82
83 return point_in(poly.triangle(i), rng);
84 }
85
87 template <typename T, geometry::shape<T> S, typename RANDOM = std::default_random_engine>
89 {
90 return s.edge_point_alpha(percentage(rng));
91 }
92
94 /*
95 template <typename T>
96 auto RandomNotIn(ghassanpl::trec2<T> const& verboten, ghassanpl::trec2<T> const& bounds)
97 {
99 const std::array<ghassanpl::trec2<T>, 4> surrounding = {
100 ghassanpl::trec2<T>{ bounds.p1.x, bounds.p1.y, bounds.p2.x, verboten.p1.y },
101 ghassanpl::trec2<T>{ bounds.p1.x, verboten.p2.y, bounds.p2.x, bounds.p2.y },
102 ghassanpl::trec2<T>{ bounds.p1.x, bounds.p1.y, verboten.p1.x, bounds.p2.y },
103 ghassanpl::trec2<T>{ verboten.p2.x, bounds.p1.y, bounds.p2.x, bounds.p2.y },
104 };
105 const std::array<T, 4> areas = {
106 surrounding[0].calculate_area(),
107 surrounding[1].calculate_area(),
108 surrounding[2].calculate_area(),
109 surrounding[3].calculate_area()
110 };
111 const int total_area = areas[0] + areas[1] + areas[2] + areas[3];
112 const int rand_pos = RandomIn(total_area);
113 if (rand_pos < areas[0]) return Random(surrounding[0]);
114 if (rand_pos < areas[0] + areas[1]) return Random(surrounding[1]);
115 if (rand_pos < areas[0] + areas[1] + areas[2]) return Random(surrounding[2]);
116 return Random(surrounding[3]);
117 }
118 */
119
120 template <typename RANDOM = std::default_random_engine>
122 {
123 static std::uniform_int_distribution<typename RANDOM::result_type> dist{ 0, 3 };
124 switch (dist(rng))
125 {
126 case 0: return { 1.0f, 0.0f };
127 case 1: return { 0.0f, 1.0f };
128 case 2: return { -1.0f, 0.0f };
129 case 3: return { 0.0f, -1.0f };
130 }
131 return {};
132 }
133
134 template <typename RANDOM = std::default_random_engine>
135 glm::ivec2 diagonal_neighbor(RANDOM& rng = ::ghassanpl::random::default_random_engine)
136 {
137 static std::uniform_int_distribution<typename RANDOM::result_type> dist{ 0, 3 };
138 switch (dist(rng))
139 {
140 case 0: return { 1.0f, 1.0f };
141 case 1: return { -1.0f, 1.0f };
142 case 2: return { -1.0f, -1.0f };
143 case 3: return { 1.0f, -1.0f };
144 }
145 return {};
146 }
147
148 template <typename RANDOM = std::default_random_engine>
149 glm::ivec2 surrounding(RANDOM& rng = ::ghassanpl::random::default_random_engine)
150 {
151 static std::uniform_int_distribution<typename RANDOM::result_type> dist{ 0, 7 };
152 switch (dist(rng))
153 {
154 case 0: return { 1.0f, 0.0f };
155 case 1: return { 0.0f, 1.0f };
156 case 2: return { -1.0f, 0.0f };
157 case 3: return { 0.0f, -1.0f };
158 case 4: return { 1.0f, 1.0f };
159 case 5: return { -1.0f, 1.0f };
160 case 6: return { -1.0f, -1.0f };
161 case 7: return { 1.0f, -1.0f };
162 }
163 return {};
164 }
165
167
169 template <std::floating_point T = float>
170 constexpr glm::tvec2<T> halton_sequence_2d(size_t index, size_t base_x = 2, size_t base_y = 3)
171 {
172 return { halton_sequence<T>(index, base_x), halton_sequence<T>(index, base_y) };
173 }
174
175}
constexpr auto bit_count
Equal to the number of bits in the type.
Definition bits.h:33
glm::ivec2 neighbor(RANDOM &rng=::ghassanpl::random::default_random_engine)
TODO: in(circle), in(poly)?, on(rect), on(circle), on(arc)
constexpr glm::tvec2< T > halton_sequence_2d(size_t index, size_t base_x=2, size_t base_y=3)
TODO: Should we move the below to random_seq?
glm::tvec2< T > point_on(S const &shape, RANDOM &rng=::ghassanpl::random::default_random_engine)
Returns a random point on the edge of the shape.
Definition random_geom.h:88
thread_local std::default_random_engine default_random_engine
TODO: Tests check out https://github.com/effolkronium/random/.
Definition random.h:17