HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
point.hpp
1// Copyright Take Vos 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../rapid/numeric_array.hpp"
8#include "vector.hpp"
9#include <format>
10
11namespace tt {
12namespace geo {
13
21template<int D>
22class point {
23public:
24 static_assert(D == 2 || D == 3, "Only 2D or 3D points are supported");
25
26 constexpr point(point const &) noexcept = default;
27 constexpr point(point &&) noexcept = default;
28 constexpr point &operator=(point const &) noexcept = default;
29 constexpr point &operator=(point &&) noexcept = default;
30
33 template<int E>
34 requires(E < D) [[nodiscard]] constexpr point(point<E> const &other) noexcept : _v(static_cast<f32x4>(other))
35 {
36 tt_axiom(is_valid());
37 }
38
42 template<int E>
43 requires(E > D) [[nodiscard]] constexpr explicit point(point<E> const &other) noexcept : _v(static_cast<f32x4>(other))
44 {
45 for (size_t i = D; i != E; ++i) {
46 _v[i] = 0.0f;
47 }
48 tt_axiom(is_valid());
49 }
50
53 [[nodiscard]] constexpr explicit operator f32x4() const noexcept
54 {
55 tt_axiom(is_valid());
56 return _v;
57 }
58
61 [[nodiscard]] constexpr explicit point(f32x4 const &other) noexcept : _v(other)
62 {
63 tt_axiom(is_valid());
64 }
65
68 [[nodiscard]] constexpr point() noexcept : _v(0.0, 0.0, 0.0, 1.0) {}
69
74 [[nodiscard]] constexpr point(float x, float y) noexcept requires(D == 2) : _v(x, y, 0.0, 1.0) {}
75
81 [[nodiscard]] constexpr point(float x, float y, float z = 0.0) noexcept requires(D == 3) : _v(x, y, z, 1.0) {}
82
86 [[nodiscard]] constexpr float &x() noexcept
87 {
88 return _v.x();
89 }
90
94 [[nodiscard]] constexpr float &y() noexcept
95 {
96 return _v.y();
97 }
98
102 [[nodiscard]] constexpr float &z() noexcept requires(D == 3)
103 {
104 return _v.z();
105 }
106
110 [[nodiscard]] constexpr float const &x() const noexcept
111 {
112 return _v.x();
113 }
114
118 [[nodiscard]] constexpr float const &y() const noexcept
119 {
120 return _v.y();
121 }
122
126 [[nodiscard]] constexpr float const &z() const noexcept requires(D == 3)
127 {
128 return _v.z();
129 }
130
131 template<int E>
132 requires(E <= D) constexpr point &operator+=(vector<E> const &rhs) noexcept
133 {
134 tt_axiom(is_valid() && rhs.is_valid());
135 _v = _v + static_cast<f32x4>(rhs);
136 return *this;
137 }
138
144 template<int E>
145 [[nodiscard]] constexpr friend point<std::max(D, E)> operator+(point const &lhs, vector<E> const &rhs) noexcept
146 {
147 tt_axiom(lhs.is_valid() && rhs.is_valid());
148 return point<std::max(D, E)>{lhs._v + static_cast<f32x4>(rhs)};
149 }
150
156 template<int E>
157 [[nodiscard]] constexpr friend point<std::max(D, E)> operator+(vector<E> const &rhs, point const &lhs) noexcept
158 {
159 tt_axiom(lhs.is_valid() && rhs.is_valid());
160 return point<std::max(D, E)>{lhs._v + static_cast<f32x4>(rhs)};
161 }
162
168 template<int E>
169 [[nodiscard]] constexpr friend point<std::max(D, E)> operator-(point const &lhs, vector<E> const &rhs) noexcept
170 {
171 tt_axiom(lhs.is_valid() && rhs.is_valid());
172 return point<std::max(D, E)>{lhs._v - static_cast<f32x4>(rhs)};
173 }
174
180 [[nodiscard]] constexpr friend vector<D> operator-(point const &lhs, point const &rhs) noexcept
181 {
182 tt_axiom(lhs.is_valid() && rhs.is_valid());
183 return vector<D>{lhs._v - rhs._v};
184 }
185
191 [[nodiscard]] constexpr friend bool operator==(point const &lhs, point const &rhs) noexcept
192 {
193 tt_axiom(lhs.is_valid() && rhs.is_valid());
194 return lhs._v == rhs._v;
195 }
196
197 template<int E>
198 [[nodiscard]] friend constexpr auto midpoint(point const &lhs, point<E> const &rhs) noexcept
199 {
200 return point<std::max(D, E)>{midpoint(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
201 }
202
203 template<int E>
204 [[nodiscard]] friend constexpr auto reflect(point const &lhs, point<E> const &rhs) noexcept
205 {
206 return point<std::max(D, E)>{reflect_point(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
207 }
208
214 template<int E>
215 [[nodiscard]] friend constexpr auto min(point const &lhs, point<E> const &rhs) noexcept
216 {
217 return point<std::max(D, E)>{min(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
218 }
219
225 template<int E>
226 [[nodiscard]] friend constexpr auto max(point const &lhs, point<E> const &rhs) noexcept
227 {
228 return point<std::max(D, E)>{max(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
229 }
230
233 [[nodiscard]] friend constexpr point round(point const &rhs) noexcept
234 {
235 return point{round(static_cast<f32x4>(rhs))};
236 }
237
240 [[nodiscard]] friend constexpr point ceil(point const &rhs) noexcept
241 {
242 return point{ceil(static_cast<f32x4>(rhs))};
243 }
244
247 [[nodiscard]] friend constexpr point floor(point const &rhs) noexcept
248 {
249 return point{floor(static_cast<f32x4>(rhs))};
250 }
251
255 [[nodiscard]] constexpr bool is_valid() const noexcept
256 {
257 return _v.w() != 0.0f && (D == 3 || _v.z() == 0.0f);
258 }
259
260 [[nodiscard]] friend std::string to_string(point const &rhs) noexcept
261 {
262 if constexpr (D == 2) {
263 return std::format("<{}, {}>", rhs._v.x(), rhs._v.y());
264 } else if constexpr (D == 3) {
265 return std::format("<{}, {}, {}>", rhs._v.x(), rhs._v.y(), rhs._v.z());
266 } else {
267 tt_static_no_default();
268 }
269 }
270
271 friend std::ostream &operator<<(std::ostream &lhs, point const &rhs) noexcept
272 {
273 return lhs << to_string(rhs);
274 }
275
276private:
277 f32x4 _v;
278};
279
280} // namespace geo
281
282using point2 = geo::point<2>;
283using point3 = geo::point<3>;
284
285} // namespace tt
286
287namespace std {
288
289template<typename CharT>
290struct formatter<tt::geo::point<2>, CharT> {
291 auto parse(auto &pc)
292 {
293 return pc.end();
294 }
295
296 auto format(tt::geo::point<2> const &t, auto &fc)
297 {
298 return std::vformat_to(fc.out(), "<{}, {}>", std::make_format_args(t.x(), t.y()));
299 }
300};
301
302template<typename CharT>
303struct formatter<tt::geo::point<3>, CharT> : formatter<float, CharT> {
304 auto parse(auto &pc)
305 {
306 return pc.end();
307 }
308
309 auto format(tt::geo::point<3> const &t, auto &fc)
310 {
311 return std::vformat_to(fc.out(), "<{}, {}, {}>", std::make_format_args(t.x(), t.y(), t.z()));
312 }
313};
314
315} // namespace std
STL namespace.
A high-level geometric point Part of the high-level vec, point, mat and color types.
Definition point.hpp:22
constexpr friend point< std::max(D, E)> operator+(vector< E > const &rhs, point const &lhs) noexcept
Move a point along a vector.
Definition point.hpp:157
friend constexpr auto max(point const &lhs, point< E > const &rhs) noexcept
Mix the two points and get the heighest value of each element.
Definition point.hpp:226
constexpr float & x() noexcept
Access the x element from the point.
Definition point.hpp:86
constexpr float const & y() const noexcept
Access the y element from the point.
Definition point.hpp:118
constexpr point(point< E > const &other) noexcept
Construct a point from a higher dimension point.
Definition point.hpp:43
constexpr point(float x, float y) noexcept
Construct a 2D point from x and y elements.
Definition point.hpp:74
constexpr friend point< std::max(D, E)> operator+(point const &lhs, vector< E > const &rhs) noexcept
Move a point along a vector.
Definition point.hpp:145
friend constexpr point round(point const &rhs) noexcept
Round the coordinates of a point toward nearest integer.
Definition point.hpp:233
constexpr point(float x, float y, float z=0.0) noexcept
Construct a 3D point from x, y and z elements.
Definition point.hpp:81
friend constexpr point ceil(point const &rhs) noexcept
Round the coordinates of a point toward the right-top.
Definition point.hpp:240
constexpr point(point< E > const &other) noexcept
Construct a point from a lower dimension point.
Definition point.hpp:34
constexpr point(f32x4 const &other) noexcept
Construct a point from a f32x4-numeric_array.
Definition point.hpp:61
constexpr float const & z() const noexcept
Access the z element from the point.
Definition point.hpp:126
constexpr friend vector< D > operator-(point const &lhs, point const &rhs) noexcept
Find the vector between two points.
Definition point.hpp:180
friend constexpr auto min(point const &lhs, point< E > const &rhs) noexcept
Mix the two points and get the lowest value of each element.
Definition point.hpp:215
constexpr point() noexcept
Construct a point at the origin of the coordinate system.
Definition point.hpp:68
constexpr friend bool operator==(point const &lhs, point const &rhs) noexcept
Compare if two points are equal.
Definition point.hpp:191
constexpr bool is_valid() const noexcept
Check if the point is valid.
Definition point.hpp:255
constexpr friend point< std::max(D, E)> operator-(point const &lhs, vector< E > const &rhs) noexcept
Move a point backward along the vector.
Definition point.hpp:169
constexpr float const & x() const noexcept
Access the x element from the point.
Definition point.hpp:110
constexpr float & z() noexcept
Access the z element from the point.
Definition point.hpp:102
friend constexpr point floor(point const &rhs) noexcept
Round the coordinates of a point toward the left-bottom.
Definition point.hpp:247
constexpr float & y() noexcept
Access the y element from the point.
Definition point.hpp:94
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector.hpp:20
T max(T... args)