Wizard Engine
2D cross-platform game engine built around SDL2
 
Loading...
Searching...
No Matches
polygon.hpp
Go to the documentation of this file.
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#ifndef WIZARD_ENGINE_POLYGON_HPP
23#define WIZARD_ENGINE_POLYGON_HPP
24
28
29namespace wze {
35class polygon final : public component {
36 private:
37 std::vector<std::pair<float, float>> _shape;
38 float _shape_radius;
39 std::vector<std::pair<float, float>> _points;
40 float _points_radius;
41 float _x;
42 float _y;
43 float _angle;
44 float _scale;
45 std::array<float, 4> _transformation_matrix;
46 float _x_offset;
47 float _y_offset;
48 float _angle_offset;
49 bool _attach_x;
50 bool _attach_y;
51 bool _attach_angle;
52 bool _x_angle_lock;
53 bool _y_angle_lock;
54
60 void update_x();
61
67 void update_y();
68
75 [[nodiscard]] float circumradius() const;
76
84 [[nodiscard]] std::pair<float, float>
85 project(std::pair<float, float> const& vector) const;
86
87 public:
95 [[nodiscard]] std::vector<std::pair<float, float>> const& shape() const;
96
103 [[nodiscard]] float shape_radius() const;
104
111 [[nodiscard]] std::vector<std::pair<float, float>> const& points() const;
112
119 [[nodiscard]] float points_radius() const;
120
127 [[nodiscard]] float x() const;
128
135 void set_x(float x) final;
136
143 [[nodiscard]] float y() const;
144
151 void set_y(float y) final;
152
159 [[nodiscard]] float angle() const;
160
167 void set_angle(float angle) final;
168
175 [[nodiscard]] float scale() const;
176
183 void set_scale(float scale);
184
191 [[nodiscard]] std::array<float, 4> const& transformation_matrix() const;
192
199 [[nodiscard]] float x_offset() const final;
200
207 void set_x_offset(float x_offset);
208
215 [[nodiscard]] float y_offset() const final;
216
223 void set_y_offset(float y_offset);
224
231 [[nodiscard]] float angle_offset() const final;
232
239 void set_angle_offset(float angle_offset);
240
247 [[nodiscard]] bool attach_x() const final;
248
255 void set_attach_x(bool attach_x);
256
263 [[nodiscard]] bool attach_y() const final;
264
271 void set_attach_y(bool attach_y);
272
279 [[nodiscard]] bool attach_angle() const final;
280
287 void set_attach_angle(bool attach_angle);
288
295 [[nodiscard]] bool x_angle_lock() const final;
296
303 void set_x_angle_lock(bool x_angle_lock);
304
311 [[nodiscard]] bool y_angle_lock() const final;
312
319 void set_y_angle_lock(bool y_angle_lock);
320
340 explicit polygon(std::vector<std::pair<float, float>> const& shape =
341 {{0, 0}, {0, 0}, {0, 0}},
342 float x = 0, float y = 0, float angle = 0, float scale = 1,
343 float x_offset = 0, float y_offset = 0,
344 float angle_offset = 0, bool attach_x = true,
345 bool attach_y = true, bool attach_angle = true,
346 bool x_angle_lock = true, bool y_angle_lock = true);
347
356 [[nodiscard]] bool inside(float x, float y) const;
357
366 template <typename T>
367 [[nodiscard]] std::enable_if_t<
368 std::is_same_v<T, bool> || std::is_same_v<T, float>, T>
369 overlap(polygon const& other) const {
370 polygon const* polygon1;
371 polygon const* polygon2;
372 T state;
373 size_t i;
374 std::vector<std::pair<float, float>>::const_iterator point1;
375 std::vector<std::pair<float, float>>::const_iterator point2;
376 std::pair<float, float> normal;
377 std::pair<float, float> projection1;
378 std::pair<float, float> projection2;
379
380 if (points_radius() + other.points_radius() <
381 math::length(other.x() - x(), other.y() - y())) {
382 return std::is_same_v<T, bool> ? false : 0;
383 }
384
385 polygon1 = this;
386 polygon2 = &other;
387 state =
388 std::is_same_v<T, bool> ? true : std::numeric_limits<float>::max();
389
390 for (i = 0; i != 2; ++i) {
391 for (point1 = polygon1->points().begin(),
392 point2 = polygon1->points().begin() + 1;
393 point1 != polygon1->points().end(); ++point1, ++point2) {
394 if (point2 == polygon1->points().end()) {
395 point2 = polygon1->points().begin();
396 }
397
398 normal = math::normal(point2->first - point1->first,
399 point2->second - point1->second);
400 if constexpr (std::is_same_v<T, float>) {
401 normal = std::apply(math::normalize, normal);
402 }
403 projection1 = polygon1->project(normal);
404 projection2 = polygon2->project(normal);
405
406 if (projection2.second < projection1.first ||
407 projection1.second < projection2.first) {
408 return std::is_same_v<T, bool> ? false : 0;
409 }
410
411 if constexpr (std::is_same_v<T, float>) {
412 state = std::min(
413 std::min(projection1.second, projection2.second) -
414 std::max(projection1.first, projection2.first),
415 state);
416 }
417 }
418
419 polygon1 = &other;
420 polygon2 = this;
421 }
422
423 return state;
424 }
425};
426} /* namespace wze */
427
428#endif /* WIZARD_ENGINE_POLYGON_HPP */
static constexpr std::pair< float, float > normal(float x, float y)
Returns the normal vector of a vector.
Definition math.hpp:86
static std::pair< float, float > normalize(float x, float y)
Normalizes a vector.
Definition math.cpp:41
static float length(float x, float y)
Returns the length of a vector.
Definition math.cpp:33
Interface to make an object composable.
Export header of the Wizard Engine.
Math modul.
Wizard Engine.