Wizard Engine
2D cross-platform game engine built around SDL2
 
Loading...
Searching...
No Matches
polygon.cpp
1/*
2 Wizard Engine
3 Copyright (C) 2023-2024 Zana Domán
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
23#define __WIZARD_ENGINE_INTERNAL__
24
26
27void wze::polygon::update_x() {
28 size_t i;
29
30 for (i = 0; i != shape().size(); ++i) {
31 _points.at(i).first =
32 x() + math::transform_x(shape().at(i).first, shape().at(i).second,
33 transformation_matrix());
34 }
35}
36
37void wze::polygon::update_y() {
38 size_t i;
39
40 for (i = 0; i != shape().size(); ++i) {
41 _points.at(i).second =
42 y() + math::transform_y(shape().at(i).first, shape().at(i).second,
43 transformation_matrix());
44 }
45}
46
47float wze::polygon::circumradius() const {
48 float circumradius;
49 float temporary;
50
51 circumradius = 0;
52 std::for_each(shape().begin(), shape().end(),
53 [&](std::pair<float, float> const& vertex) -> void {
54 temporary = apply(math::length, vertex);
55 if (circumradius < temporary) {
56 circumradius = temporary;
57 }
58 });
59
60 return circumradius;
61}
62
63std::pair<float, float>
64wze::polygon::project(std::pair<float, float> const& vector) const {
65 std::pair<float, float> projection;
66
67 projection.first = std::numeric_limits<float>::max();
68 projection.second = -std::numeric_limits<float>::max();
69 std::for_each(points().begin(), points().end(),
70 [&](std::pair<float, float> const& point) -> void {
71 float scalar;
72
73 scalar = point.first * vector.first +
74 point.second * vector.second;
75 projection.first = std::min(projection.first, scalar);
76 projection.second = std::max(projection.second, scalar);
77 });
78
79 return projection;
80}
81
82std::vector<std::pair<float, float>> const& wze::polygon::shape() const {
83 return _shape;
84}
85
86float wze::polygon::shape_radius() const {
87 return _shape_radius;
88}
89
90std::vector<std::pair<float, float>> const& wze::polygon::points() const {
91 return _points;
92}
93
94float wze::polygon::points_radius() const {
95 return _points_radius;
96}
97
98float wze::polygon::x() const {
99 return _x;
100}
101
102void wze::polygon::set_x(float x) {
103 _x = x;
104 update_x();
105}
106
107float wze::polygon::y() const {
108 return _y;
109}
110
111void wze::polygon::set_y(float y) {
112 _y = y;
113 update_y();
114}
115
116float wze::polygon::angle() const {
117 return _angle;
118}
119
120void wze::polygon::set_angle(float angle) {
121 _angle = angle;
122 _transformation_matrix =
123 math::transformation_matrix(this->angle(), scale());
124 update_x();
125 update_y();
126}
127
128float wze::polygon::scale() const {
129 return _scale;
130}
131
132void wze::polygon::set_scale(float scale) {
133 _scale = scale;
134 _points_radius = shape_radius() * this->scale();
135 _transformation_matrix =
136 math::transformation_matrix(angle(), this->scale());
137 update_x();
138 update_y();
139}
140
141std::array<float, 4> const& wze::polygon::transformation_matrix() const {
142 return _transformation_matrix;
143}
144
145float wze::polygon::x_offset() const {
146 return _x_offset;
147}
148
149void wze::polygon::set_x_offset(float x_offset) {
150 _x_offset = x_offset;
151}
152
153float wze::polygon::y_offset() const {
154 return _y_offset;
155}
156
157void wze::polygon::set_y_offset(float y_offset) {
158 _y_offset = y_offset;
159}
160
161float wze::polygon::angle_offset() const {
162 return _angle_offset;
163}
164
165void wze::polygon::set_angle_offset(float angle_offset) {
166 _angle_offset = angle_offset;
167}
168
169bool wze::polygon::attach_x() const {
170 return _attach_x;
171}
172
173void wze::polygon::set_attach_x(bool attach_x) {
174 _attach_x = attach_x;
175}
176
177bool wze::polygon::attach_y() const {
178 return _attach_y;
179}
180
181void wze::polygon::set_attach_y(bool attach_y) {
182 _attach_y = attach_y;
183}
184
185bool wze::polygon::attach_angle() const {
186 return _attach_angle;
187}
188
189void wze::polygon::set_attach_angle(bool attach_angle) {
190 _attach_angle = attach_angle;
191}
192
193bool wze::polygon::x_angle_lock() const {
194 return _x_angle_lock;
195}
196
197void wze::polygon::set_x_angle_lock(bool x_angle_lock) {
198 _x_angle_lock = x_angle_lock;
199}
200
201bool wze::polygon::y_angle_lock() const {
202 return _y_angle_lock;
203}
204
205void wze::polygon::set_y_angle_lock(bool y_angle_lock) {
206 _y_angle_lock = y_angle_lock;
207}
208
209wze::polygon::polygon(std::vector<std::pair<float, float>> const& shape,
210 float x, float y, float angle, float scale,
211 float x_offset, float y_offset, float angle_offset,
212 bool attach_x, bool attach_y, bool attach_angle,
213 bool x_angle_lock, bool y_angle_lock) {
214 _shape = shape;
215 _shape_radius = circumradius();
216 _points.resize(this->shape().size());
217 set_x(x);
218 set_y(y);
219 set_angle(angle);
220 set_scale(scale);
221 set_x_offset(x_offset);
222 set_y_offset(y_offset);
223 set_angle_offset(angle_offset);
224 set_attach_x(attach_x);
225 set_attach_y(attach_y);
226 set_attach_angle(attach_angle);
227 set_x_angle_lock(x_angle_lock);
228 set_y_angle_lock(y_angle_lock);
229}
230
231bool wze::polygon::inside(float x, float y) const {
232 std::vector<std::pair<float, float>>::const_iterator point1;
233 std::vector<std::pair<float, float>>::const_iterator point2;
234 float determinant;
235 float temporary;
236
237 if (points_radius() < math::length(x - this->x(), y - this->y())) {
238 return false;
239 }
240
241 determinant = 0;
242 for (point1 = points().begin(), point2 = points().begin() + 1;
243 point1 != points().end(); ++point1, ++point2) {
244 if (point2 == points().end()) {
245 point2 = points().begin();
246 }
247
248 temporary = (point2->first - point1->first) * (y - point1->second) -
249 (x - point1->first) * (point2->second - point1->second);
250
251 if ((0 < determinant && temporary < 0) ||
252 (determinant < 0 && 0 < temporary)) {
253 return false;
254 }
255
256 determinant = temporary;
257 }
258
259 return true;
260}
static constexpr float transform_y(float x, float y, std::array< float, 4 > const &transformation_matrix)
Transforms the y component of a vector.
Definition math.hpp:162
static std::array< float, 4 > transformation_matrix(float angle, float scale)
Creates a transformation matrix.
Definition math.cpp:57
static float length(float x, float y)
Returns the length of a vector.
Definition math.cpp:33
static constexpr float transform_x(float x, float y, std::array< float, 4 > const &transformation_matrix)
Transforms the x component of a vector.
Definition math.hpp:148
Convex polygon component.