10#include "vipra/geometry/f3d.hpp"
11#include "vipra/geometry/line.hpp"
13#include "vipra/geometry/rectangle.hpp"
14#include "vipra/geometry/triangle.hpp"
15#include "vipra/random/random.hpp"
16namespace VIPRA::Geometry {
22 [[nodiscard]]
auto is_point_inside(
f3d point)
const noexcept -> bool;
23 [[nodiscard]]
auto bounding_box()
const noexcept ->
Rectangle;
24 [[nodiscard]]
auto center()
const noexcept ->
f3d;
25 [[nodiscard]]
auto points()
const noexcept -> std::vector<f3d>
const&
29 [[nodiscard]]
auto sides()
const noexcept -> std::vector<Line>;
32 std::vector<f3d> _points;
35 explicit Polygon(std::vector<f3d>
const& points) : _points(points) {}
37 explicit Polygon(std::vector<f3d>&& points) : _points(std::move(points)) {}
39 template <
size_t po
int_s>
40 explicit Polygon(std::array<f3d, point_s>
const& points)
42 _points.resize(point_s);
43 std::copy(points.begin(), points.end(), _points.begin());
46 template <
size_t po
int_s>
47 explicit Polygon(std::array<f3d, point_s>&& points)
49 _points.resize(point_s);
50 std::copy(points.begin(), points.end(), _points.begin());
53 explicit Polygon(std::vector<Line>
const& lines)
55 _points.resize(lines.size());
56 for (
size_t i = 0; i < lines.size(); ++i ) {
57 _points[i] = lines[i].start;
61 explicit Polygon(std::vector<Line>&& lines)
63 _points.resize(lines.size());
64 for (
size_t i = 0; i < lines.size(); ++i ) {
65 _points[i] = lines[i].start;
69 template <
size_t po
int_s>
70 explicit Polygon(std::array<Line, point_s>
const& lines)
72 _points.resize(point_s);
73 for (
size_t i = 0; i < point_s; ++i ) {
74 _points[i] = lines[i].start;
78 template <
size_t po
int_s>
79 explicit Polygon(std::array<Line, point_s>&& lines)
81 _points.resize(point_s);
82 for (
size_t i = 0; i < point_s; ++i ) {
83 _points[i] = lines[i].start;
89 Polygon(Polygon
const&) =
default;
90 auto operator=(Polygon
const&) -> Polygon& =
default;
91 Polygon(Polygon&&)
noexcept =
default;
92 auto operator=(Polygon&&)
noexcept -> Polygon& =
default;
97inline auto Polygon::is_point_inside(
f3d point)
const noexcept ->
bool
99 if ( _points.size() < 3 )
return false;
102 for (
size_t i = 0, j = _points.size() - 1; i < _points.size(); j = i++ ) {
103 f_pnt xi = _points[i].x;
104 f_pnt yi = _points[i].y;
105 f_pnt xj = _points[j].x;
106 f_pnt yj = _points[j].y;
109 if ( (yi > point.y) != (yj > point.y) ) {
110 f_pnt intersectX = (xj - xi) * (point.y - yi) / (yj - yi) + xi;
111 if ( point.x < intersectX ) inside = ! inside;
117inline auto Polygon::center() const noexcept -> f3d
119 const auto sideList = sides();
122 std::for_each(sideList.begin(), sideList.end(),
123 [&](Line
const& edge) { center += edge.start; });
125 return center /= sideList.size();
128inline auto Polygon::random_point(VIPRA::Random::Engine& engine)
const noexcept -> f3d
132 auto box = bounding_box();
134 std::uniform_real_distribution<VIPRA::f_pnt> xDist{box.sides()[3].end.x,
135 box.sides()[3].start.x};
136 std::uniform_real_distribution<VIPRA::f_pnt> yDist{box.sides()[2].end.y,
137 box.sides()[2].start.y};
142 point.x = xDist(engine);
143 point.y = yDist(engine);
144 }
while ( ! box.is_point_inside(point) );
148inline auto Polygon::bounding_box() const noexcept ->
Rectangle
150 f3d botLeft{std::numeric_limits<VIPRA::f_pnt>::max(),
151 std::numeric_limits<VIPRA::f_pnt>::max()};
152 f3d topRight{std::numeric_limits<VIPRA::f_pnt>::min(),
153 std::numeric_limits<VIPRA::f_pnt>::min()};
154 for (
auto const& point : _points ) {
155 topRight.x = std::max(topRight.x, point.x);
156 topRight.y = std::max(topRight.y, point.y);
157 botLeft.x = std::min(botLeft.x, point.x);
158 botLeft.y = std::min(botLeft.y, point.y);
161 const f3d topLeft = f3d{botLeft.x, topRight.y};
162 const f3d botRight = f3d{topRight.x, botLeft.y};
164 return Rectangle{botLeft, topLeft, topRight, botRight};
167inline auto Polygon::sides() const noexcept -> std::vector<
Line>
169 std::vector<Line> lines;
170 lines.resize(_points.size());
172 for (
size_t i = 0; i < _points.size() - 1; ++i ) {
173 lines[i] = Line{_points[i], _points[i + 1]};
175 lines.back() = Line{_points.back(), _points.front()};
Definition rectangle.hpp:20
Psuedo Random number engine.
Definition random.hpp:22