8#include "vipra/geometry/definitions.hpp"
9#include "vipra/geometry/f3d.hpp"
10#include "vipra/geometry/line.hpp"
11#include "vipra/random/random.hpp"
12#include "vipra/types/float.hpp"
14namespace VIPRA::Geometry {
22 VIPRA_POLY_FUNC
auto is_point_inside(
f3d point)
const noexcept -> bool;
24 VIPRA_POLY_FUNC
auto sides()
const noexcept -> std::array<Line, 4>;
25 VIPRA_POLY_FUNC
auto rotation()
const noexcept -> f_pnt;
27 VIPRA_POLY_FUNC
auto center()
const noexcept ->
f3d const& {
return _center; }
28 VIPRA_POLY_FUNC
auto area()
const noexcept -> f_pnt {
return _area; }
29 VIPRA_POLY_FUNC
auto width()
const noexcept -> f_pnt {
return _width; }
30 VIPRA_POLY_FUNC
auto height()
const noexcept -> f_pnt {
return _height; }
31 VIPRA_POLY_FUNC
auto points()
const noexcept -> std::array<f3d, 4>
const&
37 std::array<f3d, 4> _points;
43 constexpr void calc_dims()
45 _width = _points[0].distance_to(_points[3]);
46 _height = _points[0].distance_to(_points[1]);
50 constexpr explicit Rectangle(
f3d point1,
f3d point2,
f3d point3,
f3d point4)
51 : _points({point1, point2, point3, point4})
54 _area = _height * _width;
56 constexpr explicit Rectangle(std::array<f3d, 4>
const& points) : _points(points)
59 _area = _height * _width;
61 constexpr explicit Rectangle(std::array<f3d, 4>&& points) : _points(points)
64 _area = _height * _width;
66 constexpr explicit Rectangle(std::vector<Line>
const& lines)
68 std::transform(lines.begin(), lines.end(), _points.begin(),
69 [](
Line const& line) { return line.start; });
71 _area = _height * _width;
74 constexpr explicit Rectangle(std::vector<Line>&& lines)
76 std::transform(lines.begin(), lines.end(), _points.begin(),
77 [](
Line const& line) { return line.start; });
79 _area = _height * _width;
82 constexpr explicit Rectangle(std::array<Line, 4>
const& lines)
84 std::transform(lines.begin(), lines.end(), _points.begin(),
85 [](
Line const& line) { return line.start; });
87 _area = _height * _width;
90 constexpr explicit Rectangle(std::array<Line, 4>&& lines)
92 std::transform(lines.begin(), lines.end(), _points.begin(),
93 [](
Line const& line) { return line.start; });
95 _area = _height * _width;
98 VIPRA::f_pnt rotation);
100 ~Rectangle() =
default;
101 constexpr Rectangle() =
default;
102 constexpr Rectangle(Rectangle
const&) =
default;
103 constexpr auto operator=(Rectangle
const&) -> Rectangle& =
default;
104 constexpr Rectangle(Rectangle&&)
noexcept =
default;
105 constexpr auto operator=(Rectangle&&)
noexcept -> Rectangle& =
default;
108VIPRA_POLY_FUNC
auto Rectangle::is_point_inside(
f3d point)
const noexcept ->
bool
111 const f3d ab = _points[0] - _points[1];
112 const f3d am = _points[0] - point;
113 const f3d bc = _points[1] - _points[2];
114 const f3d bm = _points[1] - point;
115 const f_pnt dotABAM = ab.
dot(am);
116 const f_pnt dotABAB = ab.
dot(ab);
117 const f_pnt dotBCBM = bc.
dot(bm);
118 const f_pnt dotBCBC = bc.
dot(bc);
119 return 0 <= dotABAM && dotABAM <= dotABAB && 0 <= dotBCBM && dotBCBM <= dotBCBC;
126 f3d min{std::numeric_limits<VIPRA::f_pnt>::max(),
127 std::numeric_limits<VIPRA::f_pnt>::max()};
128 f3d max{std::numeric_limits<VIPRA::f_pnt>::min(),
129 std::numeric_limits<VIPRA::f_pnt>::min()};
130 for (
auto const& point : _points ) {
131 max.x = std::max(max.x, point.x);
132 max.y = std::max(max.y, point.y);
133 min.x = std::min(min.x, point.x);
134 min.y = std::min(min.y, point.y);
137 std::uniform_real_distribution<VIPRA::f_pnt> xDist{min.x, max.x};
138 std::uniform_real_distribution<VIPRA::f_pnt> yDist{min.y, max.y};
143 point.x = xDist(engine);
144 point.y = yDist(engine);
145 }
while ( ! is_point_inside(point) );
149VIPRA_POLY_FUNC
auto Rectangle::sides() const noexcept -> std::array<
Line, 4>
151 std::array<Line, 4> lines;
152 for (
size_t i = 0; i < 4; ++i ) {
153 lines[i] = Line{_points[i], _points[i + 1]};
155 lines.back() = Line{_points.back(), _points.front()};
159VIPRA_POLY_FUNC
auto Rectangle::rotation() const noexcept -> f_pnt
161 constexpr f_pnt HALF = 180.0;
162 constexpr f_pnt FULL = 360.0;
164 const f_pnt xDif = _points[0].x - _points[2].x;
165 const f_pnt yDif = _points[0].y - _points[2].y;
167 f_pnt rotation = std::atan(xDif / yDif) * HALF / std::numbers::pi;
171 else if ( xDif < 0 ) {
178constexpr Rectangle::Rectangle(VIPRA::f3d
const& center, VIPRA::f3d
const& dimensions,
179 VIPRA::f_pnt rotation)
182 const VIPRA::f3d point1 = VIPRA::f3d{center.x + ((dimensions.x / 2) * cos(rotation)) -
183 ((dimensions.y / 2) * sin(rotation)),
184 center.y + ((dimensions.x / 2) * sin(rotation)) +
185 ((dimensions.y / 2) * cos(rotation))};
186 const VIPRA::f3d point2 = VIPRA::f3d{center.x - ((dimensions.x / 2) * cos(rotation)) -
187 ((dimensions.y / 2) * sin(rotation)),
188 center.y - ((dimensions.x / 2) * sin(rotation)) +
189 ((dimensions.y / 2) * cos(rotation))};
190 const VIPRA::f3d point3 = VIPRA::f3d{center.x - ((dimensions.x / 2) * cos(rotation)) +
191 ((dimensions.y / 2) * sin(rotation)),
192 center.y - ((dimensions.x / 2) * sin(rotation)) -
193 ((dimensions.y / 2) * cos(rotation))};
194 const VIPRA::f3d point4 = VIPRA::f3d{center.x + ((dimensions.x / 2) * cos(rotation)) +
195 ((dimensions.y / 2) * sin(rotation)),
196 center.y + ((dimensions.x / 2) * sin(rotation)) -
197 ((dimensions.y / 2) * cos(rotation))};
199 _points = {point1, point2, point3, point4};
201 _area = _height * _width;
Definition polygon.hpp:18
Definition triangle.hpp:17
Psuedo Random number engine.
Definition random.hpp:22
F3D_FUNC auto dot(f3d const &other) const noexcept -> VIPRA::f_pnt
Returns the dot product between two f3ds.
Definition f3d.hpp:261