1.11
geometry.h
1/*
2 * Copyright (C) 2018 Microchip Technology Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6#ifndef EGT_GEOMETRY_H
7#define EGT_GEOMETRY_H
8
14#include <algorithm>
15#include <cassert>
16#include <cmath>
17#include <egt/detail/math.h>
18#include <egt/detail/meta.h>
19#include <ostream>
20#include <string>
21
22namespace egt
23{
24inline namespace v1
25{
34using DefaultDim = int;
35
36namespace detail
37{
38
44enum class Compatible
45{
46 normal,
47 display,
48 grid
49};
50
51}
52
53
61template <class Dim, detail::Compatible DimCompat = detail::Compatible::normal>
63{
64public:
65
69 using DimType = Dim;
70
71 constexpr PointType() noexcept = default;
72
77 constexpr PointType(Dim x, Dim y) noexcept
78 : m_x(x),
79 m_y(y)
80 {}
81
82 template<class Dim2>
83 constexpr PointType(const PointType<Dim2>& p)
84 : m_x(p.x()),
85 m_y(p.y())
86 {}
87
89 constexpr PointType& operator+=(const PointType& rhs) noexcept
90 {
91 m_x += rhs.m_x;
92 m_y += rhs.m_y;
93 return *this;
94 }
95
97 constexpr PointType& operator-=(const PointType& rhs) noexcept
98 {
99 m_x -= rhs.m_x;
100 m_y -= rhs.m_y;
101 return *this;
102 }
103
105 constexpr PointType& operator*=(const PointType& rhs) noexcept
106 {
107 m_x *= rhs.m_x;
108 m_y *= rhs.m_y;
109 return *this;
110 }
111
113 constexpr PointType& operator/=(const PointType& rhs) noexcept
114 {
115 m_x /= rhs.m_x;
116 m_y /= rhs.m_y;
117 return *this;
118 }
119
121 template <class T>
122 constexpr PointType& operator+=(const T& rhs) noexcept
123 {
124 m_x += rhs;
125 m_y += rhs;
126 return *this;
127 }
128
130 template <class T>
131 constexpr PointType& operator-=(const T& rhs) noexcept
132 {
133 m_x -= rhs;
134 m_y -= rhs;
135 return *this;
136 }
137
139 template <class T>
140 constexpr PointType& operator*=(const T& rhs) noexcept
141 {
142 m_x *= rhs;
143 m_y *= rhs;
144 return *this;
145 }
146
148 template <class T>
149 constexpr PointType& operator/=(const T& rhs) noexcept
150 {
151 m_x /= rhs;
152 m_y /= rhs;
153 return *this;
154 }
155
163 template <class T>
164 PointType point_on_circumference(T radius, T angle) const noexcept
165 {
166 return PointType(m_x + radius * std::cos(angle),
167 m_y + radius * std::sin(angle));
168 }
169
175 template <class T>
176 EGT_NODISCARD T angle_to(const PointType& point) const noexcept
177 {
178 return std::atan2(point.m_x - m_x, m_y - point.m_y);
179 }
180
186 EGT_NODISCARD Dim distance_to(const PointType& point) const noexcept
187 {
188 return std::hypot(point.m_x - m_x, point.m_y - m_y);
189 }
190
192 EGT_NODISCARD constexpr Dim x() const noexcept { return m_x; }
194 EGT_NODISCARD constexpr Dim y() const noexcept { return m_y; }
195
197 constexpr void x(Dim x) noexcept { m_x = x; }
199 constexpr void y(Dim y) noexcept { m_y = y; }
200
201protected:
203 Dim m_x{0};
205 Dim m_y{0};
206};
207
209template<class Dim, detail::Compatible DimCompat>
211{
212 return PointType<Dim, DimCompat>(-a.x(), -a.y());
213}
214
216template<class Dim, detail::Compatible DimCompat>
217constexpr bool operator==(const PointType<Dim, DimCompat>& lhs, const PointType<Dim, DimCompat>& rhs) noexcept
218{
219 return lhs.x() == rhs.x() && lhs.y() == rhs.y();
220}
221
223template<detail::Compatible DimCompat>
225{
226 return detail::float_equal(lhs.x(), rhs.x()) &&
227 detail::float_equal(lhs.y(), rhs.y());
228}
229
231template<class Dim, detail::Compatible DimCompat>
232constexpr bool operator!=(const PointType<Dim, DimCompat>& lhs, const PointType<Dim, DimCompat>& rhs) noexcept
233{
234 return !(lhs == rhs);
235}
236
238template<class Dim, detail::Compatible DimCompat>
240{
241 lhs -= rhs;
242 return lhs;
243}
244
246template<class Dim, detail::Compatible DimCompat>
248{
249 lhs += rhs;
250 return lhs;
251}
252
254template<class Dim, detail::Compatible DimCompat>
256{
257 lhs /= rhs;
258 return lhs;
259}
260
262template<class Dim, detail::Compatible DimCompat>
264{
265 lhs *= rhs;
266 return lhs;
267}
268
270template<class Dim, detail::Compatible DimCompat, class T>
272{
273 lhs -= rhs;
274 return lhs;
275}
276
278template<class Dim, detail::Compatible DimCompat, class T>
280{
281 lhs += rhs;
282 return lhs;
283}
284
286template<class Dim, detail::Compatible DimCompat, class T>
288{
289 lhs /= rhs;
290 return lhs;
291}
292
294template<class Dim, detail::Compatible DimCompat, class T>
296{
297 lhs *= rhs;
298 return lhs;
299}
300
302template<class Dim, detail::Compatible DimCompat>
303std::ostream& operator<<(std::ostream& os, const PointType<Dim, DimCompat>& point)
304{
305 os << "[" << point.x() << "," << point.y() << "]";
306 return os;
307}
308
315
316static_assert(detail::rule_of_5<Point>(), "must fulfill rule of 5");
317
324
331
339template<class Dim, detail::Compatible DimCompat = detail::Compatible::normal>
341{
342public:
343
347 using DimType = Dim;
348
349 constexpr SizeType() noexcept = default;
350
355 constexpr SizeType(Dim width, Dim height) noexcept
356 : m_height(height),
358 {}
359
360 template<class Dim2>
361 constexpr SizeType(const SizeType<Dim2>& s)
362 : m_height(s.height()),
363 m_width(s.width())
364 {}
365
372 EGT_NODISCARD constexpr bool empty() const noexcept
373 {
374 // cppcheck-suppress unsignedLessThanZero
375 return m_width <= 0 || m_height <= 0;
376 }
377
383 constexpr void clear() noexcept
384 {
385 m_height = m_width = 0;
386 }
387
389 constexpr SizeType& operator+=(const SizeType& rhs) noexcept
390 {
391 m_width += rhs.m_width;
392 m_height += rhs.m_height;
393 return *this;
394 }
395
397 constexpr SizeType& operator-=(const SizeType& rhs) noexcept
398 {
399 m_width -= rhs.m_width;
400 m_height -= rhs.m_height;
401 return *this;
402 }
403
405 constexpr SizeType& operator*=(const SizeType& rhs) noexcept
406 {
407 m_width *= rhs.m_width;
408 m_height *= rhs.m_height;
409 return *this;
410 }
411
413 constexpr SizeType& operator/=(const SizeType& rhs) noexcept
414 {
415 m_width /= rhs.m_width;
416 m_height /= rhs.m_height;
417 return *this;
418 }
419
421 template<class T>
422 constexpr SizeType& operator+=(const T& rhs) noexcept
423 {
424 m_width += rhs;
425 m_height += rhs;
426 return *this;
427 }
428
430 template<class T>
431 constexpr SizeType& operator-=(const T& rhs) noexcept
432 {
433 m_width -= rhs;
434 m_height -= rhs;
435 return *this;
436 }
437
439 template<class T>
440 constexpr SizeType& operator*=(const T& rhs) noexcept
441 {
442 m_width *= rhs;
443 m_height *= rhs;
444 return *this;
445 }
446
448 template<class T>
449 constexpr SizeType& operator/=(const T& rhs) noexcept
450 {
451 m_width /= rhs;
452 m_height /= rhs;
453 return *this;
454 }
455
457 EGT_NODISCARD constexpr Dim width() const noexcept { return m_width; }
459 EGT_NODISCARD constexpr Dim height() const noexcept { return m_height; }
460
462 constexpr void width(Dim width) noexcept { m_width = width; }
464 constexpr void height(Dim height) noexcept { m_height = height; }
465
466protected:
468 Dim m_height{0};
469
471 Dim m_width{0};
472};
473
475template<class Dim, detail::Compatible DimCompat>
476constexpr bool operator==(const SizeType<Dim, DimCompat>& lhs, const SizeType<Dim, DimCompat>& rhs) noexcept
477{
478 return lhs.width() == rhs.width() && lhs.height() == rhs.height();
479}
480
482template<detail::Compatible DimCompat>
484{
485 return detail::float_equal(lhs.width(), rhs.width()) &&
486 detail::float_equal(lhs.height(), rhs.height());
487}
488
490template<class Dim, detail::Compatible DimCompat>
491constexpr bool operator!=(const SizeType<Dim, DimCompat>& lhs, const SizeType<Dim, DimCompat>& rhs) noexcept
492{
493 return !(lhs == rhs);
494}
495
497template<class Dim, detail::Compatible DimCompat>
499{
500 lhs -= rhs;
501 return lhs;
502}
503
505template<class Dim, detail::Compatible DimCompat>
507{
508 lhs += rhs;
509 return lhs;
510}
511
513template<class Dim, detail::Compatible DimCompat>
515{
516 lhs *= rhs;
517 return lhs;
518}
519
521template<class Dim, detail::Compatible DimCompat>
523{
524 lhs /= rhs;
525 return lhs;
526}
527
529template<class Dim, detail::Compatible DimCompat, class T>
531{
532 lhs -= rhs;
533 return lhs;
534}
535
537template<class Dim, detail::Compatible DimCompat, class T>
539{
540 lhs += rhs;
541 return lhs;
542}
543
545template<class Dim, detail::Compatible DimCompat, class T>
547{
548 lhs *= rhs;
549 return lhs;
550}
551
553template<class Dim, detail::Compatible DimCompat, class T>
555{
556 lhs /= rhs;
557 return lhs;
558}
559
561template<class Dim, detail::Compatible DimCompat>
562std::ostream& operator<<(std::ostream& os, const SizeType<Dim, DimCompat>& size)
563{
564 os << size.width() << "x" << size.height();
565 return os;
566}
567
574
575static_assert(detail::rule_of_5<Size>(), "must fulfill rule of 5");
576
583
593template<class Dim, detail::Compatible DimCompat = detail::Compatible::normal>
595{
596public:
597
601 using DimType = Dim;
602
603 constexpr RectType() noexcept = default;
604
608 constexpr explicit RectType(const PointType<Dim>& point, const SizeType<Dim, DimCompat>& size) noexcept
609 : m_origin(point),
610 m_size(size)
611 {
612 assert(width() >= 0);
613 assert(height() >= 0);
614 }
615
620 // cppcheck-suppress noExplicitConstructor
621 // NOLINTNEXTLINE(hicpp-explicit-conversions)
622 constexpr RectType(const SizeType<Dim, DimCompat>& size) noexcept
623 : RectType( {}, size)
624 {}
625
632 constexpr RectType(Dim x, Dim y, Dim width, Dim height) noexcept
633 : RectType( {x, y}, {width, height})
634 {}
635
636 template<typename Dim2>
637 constexpr RectType(const RectType<Dim2>& r)
638 : m_origin(r.point()),
639 m_size(r.size())
640 {}
641
643 constexpr RectType& operator+=(const SizeType<Dim, DimCompat>& rhs) noexcept
644 {
645 m_size += rhs;
646 return *this;
647 }
648
650 constexpr RectType& operator-=(const SizeType<Dim, DimCompat>& rhs) noexcept
651 {
652 m_size -= rhs;
653 return *this;
654 }
655
657 constexpr RectType& operator+=(const PointType<Dim, DimCompat>& rhs) noexcept
658 {
659 m_origin += rhs;
660 return *this;
661 }
662
664 constexpr RectType& operator-=(const PointType<Dim, DimCompat>& rhs) noexcept
665 {
666 m_origin -= rhs;
667 return *this;
668 }
669
673 EGT_NODISCARD constexpr Dim area() const noexcept
674 {
675 return width() * height();
676 }
677
681 EGT_NODISCARD constexpr PointType<Dim, DimCompat> center() const noexcept
682 {
683 return PointType<Dim, DimCompat>(x() + (width() / 2.f), y() + (height() / 2.f));
684 }
685
689 constexpr void move_to_center(const PointType<Dim, DimCompat>& center) noexcept
690 {
691 const PointType<Dim, DimCompat> pos(center.x() - width() / 2.,
692 center.y() - height() / 2.);
693
694 m_origin = pos;
695 }
696
702 constexpr void grow_around_center(Dim radius) noexcept
703 {
704 m_origin -= (radius / 2);
705 m_size += radius;
706 }
707
713 constexpr void shrink_around_center(Dim radius) noexcept
714 {
715 m_origin += (radius / 2);
716 m_size -= radius;
717 }
718
722 EGT_NODISCARD constexpr const PointType<Dim, DimCompat>& point() const noexcept
723 {
724 return m_origin;
725 }
726
730 constexpr void point(const PointType<Dim, DimCompat>& p) noexcept
731 {
732 m_origin = p;
733 }
734
738 EGT_NODISCARD constexpr const SizeType<Dim, DimCompat>& size() const noexcept
739 {
740 return m_size;
741 }
742
746 constexpr void size(const SizeType<Dim, DimCompat>& size) noexcept
747 {
748 m_size = size;
749 }
750
754 EGT_NODISCARD constexpr Dim top() const noexcept
755 {
756 return m_origin.y();
757 }
758
762 EGT_NODISCARD constexpr Dim left() const noexcept
763 {
764 return m_origin.x();
765 }
766
770 EGT_NODISCARD constexpr Dim bottom() const noexcept
771 {
772 return top() + height();
773 }
774
778 EGT_NODISCARD constexpr Dim right() const noexcept
779 {
780 return left() + width();
781 }
782
788 EGT_NODISCARD constexpr PointType<Dim, DimCompat> top_left() const noexcept
789 {
791 }
792
796 EGT_NODISCARD constexpr PointType<Dim, DimCompat> top_right() const noexcept
797 {
799 }
800
804 EGT_NODISCARD constexpr PointType<Dim, DimCompat> bottom_left() const noexcept
805 {
807 }
808
812 EGT_NODISCARD constexpr PointType<Dim, DimCompat> bottom_right() const noexcept
813 {
815 }
816
820 constexpr void clear() noexcept
821 {
822 m_origin = {};
823 m_size = {};
824 }
825
829 EGT_NODISCARD constexpr bool empty() const noexcept
830 {
831 return width() <= 0 || height() <= 0;
832 }
833
851 EGT_NODISCARD constexpr bool intersect(const PointType<Dim, DimCompat>& point) const noexcept
852 {
853 return (point.x() < right() && point.x() >= left() &&
854 point.y() < bottom() && point.y() >= top());
855 }
856
861 EGT_NODISCARD constexpr bool intersect(const RectType& rect) const noexcept
862 {
863 return (x() < rect.x() + rect.width() && x() + width() > rect.x() &&
864 y() < rect.y() + rect.height() && y() + height() > rect.y());
865 }
866
871 static constexpr RectType merge(const RectType& lhs,
872 const RectType& rhs) noexcept
873 {
874 const auto xmin = std::min(lhs.x(), rhs.x());
875 const auto xmax = std::max(lhs.x() + lhs.width(),
876 rhs.x() + rhs.width());
877 const auto ymin = std::min(lhs.y(), rhs.y());
878 const auto ymax = std::max(lhs.y() + lhs.height(),
879 rhs.y() + rhs.height());
880
881 return RectType<Dim, DimCompat>(xmin, ymin, xmax - xmin, ymax - ymin);
882 }
883
887 static constexpr RectType intersection(const RectType& lhs,
888 const RectType& rhs) noexcept
889 {
890 const auto x0 = std::max(lhs.x(), rhs.x());
891 const auto y0 = std::max(lhs.y(), rhs.y());
892 const auto w0 = std::min(lhs.x() + lhs.width(), rhs.x() + rhs.width()) - x0;
893 const auto h0 = std::min(lhs.y() + lhs.height(), rhs.y() + rhs.height()) - y0;
894
895 if (w0 < 0 || h0 < 0)
897
898 return RectType<Dim, DimCompat>(x0, y0, w0, h0);
899 }
900
907 EGT_NODISCARD constexpr bool contains(const RectType& rhs) const noexcept
908 {
909 return rhs.right() < right() &&
910 rhs.bottom() < bottom() &&
911 rhs.left() > left() &&
912 rhs.top() > top();
913 }
914
916 EGT_NODISCARD constexpr Dim x() const noexcept { return m_origin.x(); }
918 EGT_NODISCARD constexpr Dim y() const noexcept { return m_origin.y(); }
919
921 constexpr void x(Dim x) noexcept { m_origin.x(x); }
923 constexpr void y(Dim y) noexcept { m_origin.y(y); }
924
926 EGT_NODISCARD constexpr Dim width() const noexcept { return m_size.width(); }
928 EGT_NODISCARD constexpr Dim height() const noexcept { return m_size.height(); }
929
931 constexpr void width(Dim width) noexcept { m_size.width(width); }
933 constexpr void height(Dim height) noexcept { m_size.height(height); }
934
935protected:
936
941};
942
944template<class Dim, detail::Compatible DimCompat>
945std::ostream& operator<<(std::ostream& os, const RectType<Dim, DimCompat>& rect)
946{
947 os << "[" << rect.x() << "," << rect.y() << "-" <<
948 rect.width() << "x" << rect.height() << "]";
949 return os;
950}
951
953template<class Dim, detail::Compatible DimCompat>
955{
956 lhs.size(lhs.size() - rhs);
957 return lhs;
958}
959
961template<class Dim, detail::Compatible DimCompat>
963{
964 lhs.size(lhs.size() + rhs);
965 return lhs;
966}
967
969template<class Dim, detail::Compatible DimCompat>
971{
972 lhs.size(lhs.size() * rhs);
973 return lhs;
974}
975
977template<class Dim, detail::Compatible DimCompat>
979{
980 lhs.size(lhs.size() / rhs);
981 return lhs;
982}
983
985template<class Dim, detail::Compatible DimCompat>
987{
988 lhs.point(lhs.point() + rhs);
989 return lhs;
990}
991
993template<class Dim, detail::Compatible DimCompat>
995{
996 lhs.point(lhs.point() - rhs);
997 return lhs;
998}
999
1001template<class Dim, detail::Compatible DimCompat>
1003{
1004 lhs.point(lhs.point() * rhs);
1005 return lhs;
1006}
1007
1009template<class Dim, detail::Compatible DimCompat>
1011{
1012 lhs.point(lhs.point() / rhs);
1013 return lhs;
1014}
1015
1017template<class Dim, detail::Compatible DimCompat>
1018constexpr bool operator==(const RectType<Dim, DimCompat>& lhs, const RectType<Dim, DimCompat>& rhs) noexcept
1019{
1020 return lhs.point() == rhs.point() &&
1021 lhs.size() == rhs.size();
1022}
1023
1025template<class Dim, detail::Compatible DimCompat>
1026constexpr bool operator!=(const RectType<Dim, DimCompat>& lhs, const RectType<Dim, DimCompat>& rhs) noexcept
1027{
1028 return !(lhs == rhs);
1029}
1030
1037
1038static_assert(detail::rule_of_5<Rect>(), "must fulfill rule of 5");
1039
1046
1054template<class Dim>
1056{
1057public:
1058
1062 using DimType = Dim;
1063
1068 constexpr explicit LineType(const PointType<Dim>& start, const PointType<Dim>& end) noexcept
1069 : m_start(start),
1070 m_end(end)
1071 {}
1072
1074 EGT_NODISCARD constexpr PointType<Dim> start() const noexcept { return m_start; }
1076 EGT_NODISCARD constexpr PointType<Dim> end() const noexcept { return m_end; }
1077
1079 constexpr void start(const PointType<Dim>& start) noexcept { m_start = start; }
1081 constexpr void end(const PointType<Dim>& end) noexcept { m_end = end; }
1082
1086 EGT_NODISCARD constexpr RectType<Dim> rect() const noexcept
1087 {
1088 const auto x = std::min(m_start.x(), m_end.x());
1089 const auto y = std::min(m_start.y(), m_end.y());
1090 const auto x2 = std::max(m_start.x(), m_end.x());
1091 const auto y2 = std::max(m_start.y(), m_end.y());
1092
1093 return RectType<Dim>(x, y, x2 - x, y2 - y);
1094 }
1095
1096protected:
1101};
1102
1104template<class Dim>
1105std::ostream& operator<<(std::ostream& os, const LineType<Dim>& line)
1106{
1107 os << "[" << line.start() << "-" << line.end() << "]";
1108 return os;
1109}
1110
1117
1124
1125static_assert(detail::rule_of_5<Line>(), "must fulfill rule of 5");
1126
1134template<class Dim>
1136{
1137public:
1138
1142 using DimType = Dim;
1143
1152 constexpr explicit ArcType(const PointType<Dim>& center = {}, Dim radius = {},
1153 float angle1 = 0.0f, float angle2 = 0.0f) noexcept
1154 : m_center(center),
1158 {
1159 }
1160
1161 template<class Dim2>
1162 constexpr ArcType(const ArcType<Dim2>& a)
1163 : m_center(a.center()),
1164 m_radius(a.radius()),
1165 m_angle1(a.angle1()),
1166 m_angle2(a.angle2())
1167 {
1168 }
1169
1173 EGT_NODISCARD EGT_API bool empty() const noexcept;
1174
1176 constexpr void radius(Dim radius) noexcept { m_radius = radius; }
1178 constexpr void angle1(float angle) noexcept { m_angle1 = angle; }
1180 constexpr void angle2(float angle) noexcept { m_angle2 = angle; }
1182 constexpr void center(const PointType<Dim>& center) noexcept { m_center = center; }
1183
1185 EGT_NODISCARD constexpr Dim radius() const noexcept { return m_radius; }
1187 EGT_NODISCARD constexpr float angle1() const noexcept { return m_angle1; }
1189 EGT_NODISCARD constexpr float angle2() const noexcept { return m_angle2; }
1191 EGT_NODISCARD constexpr PointType<Dim> center() const noexcept { return m_center; }
1192
1193protected:
1194
1197
1199 Dim m_radius{0};
1200
1202 float m_angle1{};
1203
1205 float m_angle2{};
1206};
1207
1214
1215static_assert(detail::rule_of_5<Arc>(), "must fulfill rule of 5");
1216
1223
1231template<class Dim>
1232class CircleType : public ArcType<Dim>
1233{
1234public:
1235
1239 using DimType = Dim;
1240
1247 constexpr explicit CircleType(const PointType<Dim>& center = {}, Dim radius = {}) noexcept
1248 : ArcType<Dim>(center, radius, 0, 2.f * detail::pi<float>())
1249 {
1250 }
1251
1252 template<class Dim2>
1253 constexpr CircleType(const CircleType<Dim2>& c)
1254 : CircleType(c.center(), c.radius())
1255 {
1256 }
1257
1261 EGT_NODISCARD constexpr RectType<Dim> rect() const noexcept
1262 {
1263 RectType<Dim> r(this->center() - Point(this->radius(), this->radius()),
1264 SizeType<Dim>(this->radius() * 2, this->radius() * 2));
1265 return r;
1266 }
1267
1273 template <class T>
1275 {
1276 return PointType<Dim>(this->x() + this->radius() * std::cos(angle),
1277 this->y() + this->radius() * std::sin(angle));
1278 }
1279};
1280
1282template<class Dim>
1283std::ostream& operator<<(std::ostream& os, const CircleType<Dim>& circle)
1284{
1285 os << "[" << circle.center() << "-" << circle.radius() << "]";
1286 return os;
1287}
1288
1295
1296static_assert(detail::rule_of_5<Circle>(), "must fulfill rule of 5");
1297
1304
1309template<class Dim>
1311{
1312public:
1316 using DimType = Dim;
1317
1323 explicit constexpr EllipseType(const PointType<Dim>& center = {},
1324 Dim radiusa = {},
1325 Dim radiusb = {}) noexcept
1326 : m_center(center),
1329 {
1330 }
1331
1332 template<class Dim2>
1333 constexpr EllipseType(const EllipseType<Dim2>& e)
1334 : EllipseType(e.center(), e.radiusa(), e.radiusb())
1335 {
1336 }
1337
1343 EGT_NODISCARD constexpr Dim perimeter() const noexcept
1344 {
1345 return 2.f * detail::pi<float>() * std::sqrt((m_radiusa * m_radiusa +
1346 m_radiusb * m_radiusb) / 2.f);
1347 }
1348
1355 template <class T>
1357 {
1358 const auto x = m_radiusa * std::cos(angle);
1359 const auto y = m_radiusb * std::sin(angle);
1360 return center() + PointType<Dim>(x, y);
1361 }
1362
1364 constexpr void radiusa(const Dim radiusa) noexcept { m_radiusa = radiusa; }
1366 constexpr void radiusb(const Dim radiusb) noexcept { m_radiusb = radiusb; }
1368 constexpr void center(const PointType<Dim>& center) noexcept { m_center = center; }
1369
1371 EGT_NODISCARD constexpr Dim radiusa() const noexcept { return m_radiusa; }
1373 EGT_NODISCARD constexpr Dim radiusb() const noexcept { return m_radiusb; }
1375 EGT_NODISCARD constexpr PointType<Dim> center() const noexcept { return m_center; }
1376
1377protected:
1378
1381
1384
1387};
1388
1395
1396static_assert(detail::rule_of_5<Ellipse>(), "must fulfill rule of 5");
1397
1404
1406template<class Dim>
1407std::ostream& operator<<(std::ostream& os, const EllipseType<Dim>& ellipse)
1408{
1409 os << "[" << ellipse.center() << "-" << ellipse.radiusa() <<
1410 "-" << ellipse.radiusb() << "]";
1411 return os;
1412}
1413
1414}
1415}
1416
1417#endif
An Arc consists of a radius and two angles.
Definition geometry.h:1136
Dim DimType
Helper to reference the dimension type.
Definition geometry.h:1142
EGT_NODISCARD constexpr float angle1() const noexcept
Get the angle1.
Definition geometry.h:1187
float m_angle2
Angle of the arc in radians.
Definition geometry.h:1205
constexpr void radius(Dim radius) noexcept
Set the radius.
Definition geometry.h:1176
constexpr ArcType(const PointType< Dim > &center={}, Dim radius={}, float angle1=0.0f, float angle2=0.0f) noexcept
Construct an Arc object.
Definition geometry.h:1152
Dim m_radius
Radius of the arc.
Definition geometry.h:1199
float m_angle1
Angle of the arc in radians.
Definition geometry.h:1202
EGT_NODISCARD constexpr Dim radius() const noexcept
Get the radius.
Definition geometry.h:1185
constexpr ArcType(const ArcType< Dim2 > &a)
Definition geometry.h:1162
EGT_NODISCARD constexpr float angle2() const noexcept
Get the angle2.
Definition geometry.h:1189
constexpr void angle1(float angle) noexcept
Set the angle1.
Definition geometry.h:1178
EGT_NODISCARD EGT_API bool empty() const noexcept
Returns true if the arc has no radius.
constexpr void center(const PointType< Dim > &center) noexcept
Set the center point.
Definition geometry.h:1182
EGT_NODISCARD constexpr PointType< Dim > center() const noexcept
Get the center point.
Definition geometry.h:1191
PointType< Dim > m_center
Center point of the arc.
Definition geometry.h:1196
constexpr void angle2(float angle) noexcept
Set the angle2.
Definition geometry.h:1180
A basic circle with a center point and radius.
Definition geometry.h:1233
PointType< Dim > point_on_circumference(T angle) const noexcept
Return the point on the circumference of the circle at the given angle.
Definition geometry.h:1274
Dim DimType
Helper to reference the dimension type.
Definition geometry.h:1239
constexpr CircleType(const PointType< Dim > &center={}, Dim radius={}) noexcept
Construct a Circle object.
Definition geometry.h:1247
EGT_NODISCARD constexpr RectType< Dim > rect() const noexcept
Get a Rect that covers the circle.
Definition geometry.h:1261
constexpr CircleType(const CircleType< Dim2 > &c)
Definition geometry.h:1253
A basic ellipse with a center and 2 radii.
Definition geometry.h:1311
Dim DimType
Helper to reference the dimension type.
Definition geometry.h:1316
EGT_NODISCARD constexpr Dim perimeter() const noexcept
Get the total perimeter of the ellipse.
Definition geometry.h:1343
Dim m_radiusa
A radius.
Definition geometry.h:1383
constexpr EllipseType(const EllipseType< Dim2 > &e)
Definition geometry.h:1333
EGT_NODISCARD constexpr Dim radiusa() const noexcept
Get the first radius of the ellipse.
Definition geometry.h:1371
EGT_NODISCARD constexpr Dim radiusb() const noexcept
Get the second radius of the ellipse.
Definition geometry.h:1373
constexpr void radiusa(const Dim radiusa) noexcept
Set the first radius of the ellipse.
Definition geometry.h:1364
constexpr void radiusb(const Dim radiusb) noexcept
Set the second radius of the ellipse.
Definition geometry.h:1366
Dim m_radiusb
B radius.
Definition geometry.h:1386
constexpr void center(const PointType< Dim > &center) noexcept
Set the center of the ellipse.
Definition geometry.h:1368
EGT_NODISCARD constexpr PointType< Dim > center() const noexcept
Get the center of the ellipse.
Definition geometry.h:1375
constexpr EllipseType(const PointType< Dim > &center={}, Dim radiusa={}, Dim radiusb={}) noexcept
Definition geometry.h:1323
PointType< Dim > m_center
Center point of the arc.
Definition geometry.h:1380
PointType< Dim > point_on_circumference(T angle) noexcept
Return the point on the circumference of the ellipse at the given angle.
Definition geometry.h:1356
A line, with a starting and ending point.
Definition geometry.h:1056
Dim DimType
Helper to reference the dimension type.
Definition geometry.h:1062
constexpr void end(const PointType< Dim > &end) noexcept
Set the end point of the line.
Definition geometry.h:1081
EGT_NODISCARD constexpr RectType< Dim > rect() const noexcept
Returns a rectangle containing the line.
Definition geometry.h:1086
PointType< Dim > m_end
End point of the line.
Definition geometry.h:1100
PointType< Dim > m_start
Start point of the line.
Definition geometry.h:1098
constexpr void start(const PointType< Dim > &start) noexcept
Set the start point of the line.
Definition geometry.h:1079
constexpr LineType(const PointType< Dim > &start, const PointType< Dim > &end) noexcept
Definition geometry.h:1068
EGT_NODISCARD constexpr PointType< Dim > start() const noexcept
Get the start point of the line.
Definition geometry.h:1074
EGT_NODISCARD constexpr PointType< Dim > end() const noexcept
Get the end point of the line.
Definition geometry.h:1076
Simple x,y coordinate.
Definition geometry.h:63
constexpr PointType & operator*=(const PointType &rhs) noexcept
PointType operator.
Definition geometry.h:105
constexpr PointType & operator-=(const PointType &rhs) noexcept
PointType operator.
Definition geometry.h:97
constexpr PointType & operator/=(const T &rhs) noexcept
PointType operator.
Definition geometry.h:149
Dim DimType
Helper to reference the dimension type.
Definition geometry.h:69
PointType point_on_circumference(T radius, T angle) const noexcept
If this point is the center of a circle, return a new point that is on the circumference of the circl...
Definition geometry.h:164
EGT_NODISCARD constexpr Dim x() const noexcept
Get the x value.
Definition geometry.h:192
constexpr void x(Dim x) noexcept
Set the x value.
Definition geometry.h:197
constexpr PointType & operator/=(const PointType &rhs) noexcept
PointType operator.
Definition geometry.h:113
constexpr PointType & operator*=(const T &rhs) noexcept
PointType operator.
Definition geometry.h:140
Dim m_y
Y value.
Definition geometry.h:205
constexpr PointType & operator+=(const PointType &rhs) noexcept
PointType operator.
Definition geometry.h:89
EGT_NODISCARD T angle_to(const PointType &point) const noexcept
Return the angle in radians from this point to get to another.
Definition geometry.h:176
constexpr PointType() noexcept=default
Dim m_x
X value.
Definition geometry.h:203
constexpr PointType & operator-=(const T &rhs) noexcept
PointType operator.
Definition geometry.h:131
EGT_NODISCARD Dim distance_to(const PointType &point) const noexcept
Calculate the straight line distance to another point.
Definition geometry.h:186
constexpr PointType(const PointType< Dim2 > &p)
Definition geometry.h:83
EGT_NODISCARD constexpr Dim y() const noexcept
Get the y value.
Definition geometry.h:194
constexpr void y(Dim y) noexcept
Set the y value.
Definition geometry.h:199
constexpr PointType & operator+=(const T &rhs) noexcept
PointType operator.
Definition geometry.h:122
A rectangle with a point and a size.
Definition geometry.h:595
constexpr RectType() noexcept=default
Dim DimType
Helper to reference the dimension type.
Definition geometry.h:601
constexpr RectType(const SizeType< Dim, DimCompat > &size) noexcept
Construct a rectangle with the specified size and the point being at the default origin 0,...
Definition geometry.h:622
constexpr RectType & operator-=(const SizeType< Dim, DimCompat > &rhs) noexcept
RectType operator.
Definition geometry.h:650
constexpr void grow_around_center(Dim radius) noexcept
Grow the rectangle around its center by the specified radius.
Definition geometry.h:702
EGT_NODISCARD constexpr Dim left() const noexcept
Get the left side the rectangle.
Definition geometry.h:762
EGT_NODISCARD constexpr Dim width() const noexcept
Get the width value.
Definition geometry.h:926
EGT_NODISCARD constexpr Dim x() const noexcept
Get the x value.
Definition geometry.h:916
constexpr void x(Dim x) noexcept
Set the x value.
Definition geometry.h:921
constexpr void shrink_around_center(Dim radius) noexcept
Shrink the rectangle around its center by the specified radius.
Definition geometry.h:713
constexpr RectType(Dim x, Dim y, Dim width, Dim height) noexcept
Definition geometry.h:632
constexpr void point(const PointType< Dim, DimCompat > &p) noexcept
Set the rectangle's origin to the specified point.
Definition geometry.h:730
SizeType< Dim, DimCompat > m_size
Size.
Definition geometry.h:940
static constexpr RectType merge(const RectType &lhs, const RectType &rhs) noexcept
Merge two rectangles together into one super rectangle that contains them both.
Definition geometry.h:871
EGT_NODISCARD constexpr bool empty() const noexcept
Returns true if the rectangle has no width or height.
Definition geometry.h:829
EGT_NODISCARD constexpr PointType< Dim, DimCompat > top_left() const noexcept
Get the top left point of the rectangle.
Definition geometry.h:788
constexpr void height(Dim height) noexcept
Set the height value.
Definition geometry.h:933
constexpr void width(Dim width) noexcept
Set the width value.
Definition geometry.h:931
constexpr RectType(const RectType< Dim2 > &r)
Definition geometry.h:637
EGT_NODISCARD constexpr Dim bottom() const noexcept
Get the bottom side the rectangle.
Definition geometry.h:770
EGT_NODISCARD constexpr PointType< Dim, DimCompat > top_right() const noexcept
Get the top right point of the rectangle.
Definition geometry.h:796
constexpr void move_to_center(const PointType< Dim, DimCompat > &center) noexcept
Move the rectangle's center to the specified point.
Definition geometry.h:689
EGT_NODISCARD constexpr Dim top() const noexcept
Get the top side of the rectangle.
Definition geometry.h:754
EGT_NODISCARD constexpr const SizeType< Dim, DimCompat > & size() const noexcept
Get the SizeType of the rectangle.
Definition geometry.h:738
constexpr void size(const SizeType< Dim, DimCompat > &size) noexcept
Set the SizeType of the rectangle.
Definition geometry.h:746
EGT_NODISCARD constexpr const PointType< Dim, DimCompat > & point() const noexcept
Get the PointType of the rectangle.
Definition geometry.h:722
EGT_NODISCARD constexpr PointType< Dim, DimCompat > bottom_right() const noexcept
Get the bottom right point of the rectangle.
Definition geometry.h:812
constexpr void clear() noexcept
Clear the rectangle by giving it no width or height.
Definition geometry.h:820
static constexpr RectType intersection(const RectType &lhs, const RectType &rhs) noexcept
Return the intersecting rectangle of two rectangles, if any.
Definition geometry.h:887
EGT_NODISCARD constexpr PointType< Dim, DimCompat > bottom_left() const noexcept
Get the bottom left point of the rectangle.
Definition geometry.h:804
constexpr RectType & operator+=(const SizeType< Dim, DimCompat > &rhs) noexcept
RectType operator.
Definition geometry.h:643
EGT_NODISCARD constexpr Dim height() const noexcept
Get the height value.
Definition geometry.h:928
EGT_NODISCARD constexpr Dim right() const noexcept
Get the right side the rectangle.
Definition geometry.h:778
EGT_NODISCARD constexpr bool intersect(const RectType &rect) const noexcept
Determine if two rectangles intersect, or, overlap.
Definition geometry.h:861
PointType< Dim, DimCompat > m_origin
Origin.
Definition geometry.h:938
EGT_NODISCARD constexpr bool contains(const RectType &rhs) const noexcept
Returns true if this rectangle contains the specified one.
Definition geometry.h:907
EGT_NODISCARD constexpr PointType< Dim, DimCompat > center() const noexcept
Return the center point of the rectangle.
Definition geometry.h:681
constexpr RectType & operator+=(const PointType< Dim, DimCompat > &rhs) noexcept
RectType operator.
Definition geometry.h:657
EGT_NODISCARD constexpr Dim y() const noexcept
Get the y value.
Definition geometry.h:918
constexpr RectType & operator-=(const PointType< Dim, DimCompat > &rhs) noexcept
RectType operator.
Definition geometry.h:664
constexpr void y(Dim y) noexcept
Set the y value.
Definition geometry.h:923
EGT_NODISCARD constexpr bool intersect(const PointType< Dim, DimCompat > &point) const noexcept
Returns true if the specified point is inside the rectangle.
Definition geometry.h:851
EGT_NODISCARD constexpr Dim area() const noexcept
Calculate the area of the rectangle.
Definition geometry.h:673
Simple width and height.
Definition geometry.h:341
Dim DimType
Helper to reference the dimension type.
Definition geometry.h:347
constexpr SizeType & operator-=(const SizeType &rhs) noexcept
SizeType operator.
Definition geometry.h:397
constexpr SizeType & operator+=(const SizeType &rhs) noexcept
SizeType operator.
Definition geometry.h:389
EGT_NODISCARD constexpr Dim width() const noexcept
Get the width value.
Definition geometry.h:457
constexpr SizeType & operator-=(const T &rhs) noexcept
SizeType operator.
Definition geometry.h:431
EGT_NODISCARD constexpr bool empty() const noexcept
Returns true if the size has no width or height.
Definition geometry.h:372
constexpr void height(Dim height) noexcept
Set the height value.
Definition geometry.h:464
constexpr void width(Dim width) noexcept
Set the width value.
Definition geometry.h:462
constexpr SizeType(const SizeType< Dim2 > &s)
Definition geometry.h:361
Dim m_height
Height.
Definition geometry.h:468
constexpr SizeType & operator/=(const T &rhs) noexcept
SizeType operator.
Definition geometry.h:449
constexpr void clear() noexcept
Clear the size.
Definition geometry.h:383
EGT_NODISCARD constexpr Dim height() const noexcept
Get the height value.
Definition geometry.h:459
constexpr SizeType & operator+=(const T &rhs) noexcept
SizeType operator.
Definition geometry.h:422
constexpr SizeType() noexcept=default
constexpr SizeType & operator*=(const T &rhs) noexcept
SizeType operator.
Definition geometry.h:440
Dim m_width
Width.
Definition geometry.h:471
constexpr SizeType & operator/=(const SizeType &rhs) noexcept
SizeType operator.
Definition geometry.h:413
constexpr SizeType & operator*=(const SizeType &rhs) noexcept
SizeType operator.
Definition geometry.h:405
PointType< DefaultDim, detail::Compatible::normal > Point
Helper type alias.
Definition geometry.h:314
SizeType< float, detail::Compatible::normal > SizeF
Helper type alias.
Definition geometry.h:582
constexpr bool float_equal(const float f1, const float f2)
Safe equal comparison of float values.
Definition math.h:107
Compatible
Geometry types compatibility type.
Definition geometry.h:45
constexpr Color operator-(T scalar, const Color &rhs)
Color operator.
Definition color.h:526
constexpr bool operator!=(const Color &lhs, const Color &rhs)
Color operator.
Definition color.h:509
EGT_API std::ostream & operator<<(std::ostream &os, const Color &color)
Overloaded std::ostream insertion operator.
constexpr Color operator+(T scalar, const Color &rhs)
Color operator.
Definition color.h:516
constexpr Color operator/(T scalar, const Color &rhs)
Color operator.
Definition color.h:546
constexpr bool operator==(const Color &lhs, const Color &rhs)
Color operator.
Definition color.h:500
constexpr Color operator*(T scalar, const Color &rhs)
Color operator.
Definition color.h:536
int DefaultDim
Define the default dimension type used for geometry.
Definition geometry.h:34
EGT framework namespace.
Definition animation.h:24