HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
point.hpp
1// Copyright Take Vos 2021-2022.
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 "extent.hpp"
10#include <format>
11
12namespace hi::inline v1 {
13namespace geo {
14
22template<int D>
23class point {
24public:
25 static_assert(D == 2 || D == 3, "Only 2D or 3D points are supported");
26
27 constexpr point(point const &) noexcept = default;
28 constexpr point(point &&) noexcept = default;
29 constexpr point &operator=(point const &) noexcept = default;
30 constexpr point &operator=(point &&) noexcept = default;
31
34 template<int E>
35 requires(E < D) [[nodiscard]] constexpr point(point<E> const &other) noexcept : _v(static_cast<f32x4>(other))
36 {
37 hi_axiom(holds_invariant());
38 }
39
42 [[nodiscard]] constexpr point(point<2> const &other, float z) noexcept requires(D == 3) : _v(static_cast<f32x4>(other))
43 {
44 _v.z() = z;
45 hi_axiom(holds_invariant());
46 }
47
48
52 template<int E>
53 requires(E > D) [[nodiscard]] constexpr explicit point(point<E> const &other) noexcept : _v(static_cast<f32x4>(other))
54 {
55 for (std::size_t i = D; i != E; ++i) {
56 _v[i] = 0.0f;
57 }
58 hi_axiom(holds_invariant());
59 }
60
63 [[nodiscard]] constexpr explicit operator f32x4() const noexcept
64 {
65 hi_axiom(holds_invariant());
66 return _v;
67 }
68
71 [[nodiscard]] constexpr explicit point(f32x4 const &other) noexcept : _v(other)
72 {
73 hi_axiom(holds_invariant());
74 }
75
78 [[nodiscard]] constexpr point() noexcept : _v(0.0, 0.0, 0.0, 1.0) {}
79
84 [[nodiscard]] constexpr point(float x, float y) noexcept requires(D == 2) : _v(x, y, 0.0, 1.0) {}
85
91 [[nodiscard]] constexpr point(float x, float y, float z = 0.0) noexcept requires(D == 3) : _v(x, y, z, 1.0) {}
92
96 [[nodiscard]] constexpr float &x() noexcept
97 {
98 return _v.x();
99 }
100
104 [[nodiscard]] constexpr float &y() noexcept
105 {
106 return _v.y();
107 }
108
112 [[nodiscard]] constexpr float &z() noexcept requires(D == 3)
113 {
114 return _v.z();
115 }
116
120 [[nodiscard]] constexpr float const &x() const noexcept
121 {
122 return _v.x();
123 }
124
128 [[nodiscard]] constexpr float const &y() const noexcept
129 {
130 return _v.y();
131 }
132
136 [[nodiscard]] constexpr float const &z() const noexcept requires(D == 3)
137 {
138 return _v.z();
139 }
140
141 template<int E>
142 requires(E <= D) constexpr point &operator+=(vector<E> const &rhs) noexcept
143 {
144 hi_axiom(holds_invariant() && rhs.holds_invariant());
145 _v = _v + static_cast<f32x4>(rhs);
146 return *this;
147 }
148
149 template<int E>
150 requires(E <= D) constexpr point &operator-=(vector<E> const &rhs) noexcept
151 {
152 hi_axiom(holds_invariant() && rhs.holds_invariant());
153 _v = _v - static_cast<f32x4>(rhs);
154 return *this;
155 }
156
162 template<int E>
163 [[nodiscard]] constexpr friend auto operator+(point const &lhs, vector<E> const &rhs) noexcept
164 {
165 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
166 return point<std::max(D, E)>{lhs._v + static_cast<f32x4>(rhs)};
167 }
168
174 template<int E>
175 [[nodiscard]] constexpr friend auto operator+(vector<E> const &rhs, point const &lhs) noexcept
176 {
177 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
178 return point<std::max(D, E)>{lhs._v + static_cast<f32x4>(rhs)};
179 }
180
186 template<int E>
187 [[nodiscard]] constexpr friend auto operator-(point const &lhs, vector<E> const &rhs) noexcept
188 {
189 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
190 return point<std::max(D, E)>{lhs._v - static_cast<f32x4>(rhs)};
191 }
192
198 [[nodiscard]] constexpr friend vector<D> operator-(point const &lhs, point const &rhs) noexcept
199 {
200 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
201 return vector<D>{lhs._v - rhs._v};
202 }
203
209 [[nodiscard]] constexpr friend bool operator==(point const &lhs, point const &rhs) noexcept
210 {
211 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
212 return lhs._v == rhs._v;
213 }
214
215 template<int E>
216 [[nodiscard]] friend constexpr auto midpoint(point const &lhs, point<E> const &rhs) noexcept
217 {
218 return point<std::max(D, E)>{midpoint(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
219 }
220
221 template<int E>
222 [[nodiscard]] friend constexpr auto reflect(point const &lhs, point<E> const &rhs) noexcept
223 {
224 return point<std::max(D, E)>{reflect_point(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
225 }
226
232 template<int E>
233 [[nodiscard]] friend constexpr auto min(point const &lhs, point<E> const &rhs) noexcept
234 {
235 return point<std::max(D, E)>{min(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
236 }
237
243 template<int E>
244 [[nodiscard]] friend constexpr auto max(point const &lhs, point<E> const &rhs) noexcept
245 {
246 return point<std::max(D, E)>{max(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
247 }
248
251 [[nodiscard]] friend constexpr point round(point const &rhs) noexcept
252 {
253 return point{round(static_cast<f32x4>(rhs))};
254 }
255
258 [[nodiscard]] friend constexpr point ceil(point const &rhs) noexcept
259 {
260 return point{ceil(static_cast<f32x4>(rhs))};
261 }
262
265 [[nodiscard]] friend constexpr point floor(point const &rhs) noexcept
266 {
267 return point{floor(static_cast<f32x4>(rhs))};
268 }
269
272 [[nodiscard]] friend constexpr point ceil(point const &lhs, extent2 rhs) noexcept
273 {
274 hilet rhs_ = f32x4{rhs}.xy11();
275 return point{ceil(f32x4{lhs} / rhs_) * rhs_};
276 }
277
280 [[nodiscard]] friend constexpr point floor(point const &lhs, extent2 rhs) noexcept
281 {
282 hilet rhs_ = f32x4{rhs}.xy11();
283 return point{floor(f32x4{lhs} / rhs_) * rhs_};
284 }
285
286 [[nodiscard]] friend constexpr float distance(point const &lhs, point const &rhs) noexcept
287 {
288 return hypot(rhs - lhs);
289 }
290
294 [[nodiscard]] constexpr bool holds_invariant() const noexcept
295 {
296 return _v.w() != 0.0f && (D == 3 || _v.z() == 0.0f);
297 }
298
299 [[nodiscard]] friend std::string to_string(point const &rhs) noexcept
300 {
301 if constexpr (D == 2) {
302 return std::format("<{}, {}>", rhs._v.x(), rhs._v.y());
303 } else if constexpr (D == 3) {
304 return std::format("<{}, {}, {}>", rhs._v.x(), rhs._v.y(), rhs._v.z());
305 } else {
307 }
308 }
309
310 friend std::ostream &operator<<(std::ostream &lhs, point const &rhs) noexcept
311 {
312 return lhs << to_string(rhs);
313 }
314
315private:
316 f32x4 _v;
317};
318
319} // namespace geo
320
321using point2 = geo::point<2>;
322using point3 = geo::point<3>;
323
324} // namespace hi::inline v1
325
326template<typename CharT>
327struct std::formatter<hi::geo::point<2>, CharT> {
328 auto parse(auto &pc)
329 {
330 return pc.end();
331 }
332
333 auto format(hi::geo::point<2> const &t, auto &fc)
334 {
335 return std::vformat_to(fc.out(), "<{}, {}>", std::make_format_args(t.x(), t.y()));
336 }
337};
338
339template<typename CharT>
340struct std::formatter<hi::geo::point<3>, CharT> : std::formatter<float, CharT> {
341 auto parse(auto &pc)
342 {
343 return pc.end();
344 }
345
346 auto format(hi::geo::point<3> const &t, auto &fc)
347 {
348 return std::vformat_to(fc.out(), "<{}, {}, {}>", std::make_format_args(t.x(), t.y(), t.z()));
349 }
350};
#define hi_axiom(expression)
Specify an axiom; an expression that is true.
Definition assert.hpp:133
#define hi_static_no_default()
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:172
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
The HikoGUI namespace.
Definition ascii.hpp:19
A high-level geometric point Part of the high-level vec, point, mat and color types.
Definition point.hpp:23
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:244
constexpr float const & y() const noexcept
Access the y element from the point.
Definition point.hpp:128
friend constexpr point floor(point const &lhs, extent2 rhs) noexcept
Round the coordinates of a point toward the left-bottom with the given granularity.
Definition point.hpp:280
constexpr friend auto operator-(point const &lhs, vector< E > const &rhs) noexcept
Move a point backward along the vector.
Definition point.hpp:187
constexpr point(point< E > const &other) noexcept
Construct a point from a lower dimension point.
Definition point.hpp:35
constexpr bool holds_invariant() const noexcept
Check if the point is valid.
Definition point.hpp:294
constexpr point(float x, float y, float z=0.0) noexcept
Construct a 3D point from x, y and z elements.
Definition point.hpp:91
constexpr float const & z() const noexcept
Access the z element from the point.
Definition point.hpp:136
constexpr friend auto operator+(point const &lhs, vector< E > const &rhs) noexcept
Move a point along a vector.
Definition point.hpp:163
constexpr friend auto operator+(vector< E > const &rhs, point const &lhs) noexcept
Move a point along a vector.
Definition point.hpp:175
constexpr point(point< E > const &other) noexcept
Construct a point from a higher dimension point.
Definition point.hpp:53
constexpr float & x() noexcept
Access the x element from the point.
Definition point.hpp:96
friend constexpr point round(point const &rhs) noexcept
Round the coordinates of a point toward nearest integer.
Definition point.hpp:251
friend constexpr point ceil(point const &rhs) noexcept
Round the coordinates of a point toward the right-top.
Definition point.hpp:258
constexpr point() noexcept
Construct a point at the origin of the coordinate system.
Definition point.hpp:78
constexpr friend vector< D > operator-(point const &lhs, point const &rhs) noexcept
Find the vector between two points.
Definition point.hpp:198
friend constexpr point ceil(point const &lhs, extent2 rhs) noexcept
Round the coordinates of a point toward the top-right with the given granularity.
Definition point.hpp:272
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:233
constexpr point(float x, float y) noexcept
Construct a 2D point from x and y elements.
Definition point.hpp:84
constexpr point(f32x4 const &other) noexcept
Construct a point from a f32x4-numeric_array.
Definition point.hpp:71
constexpr float & z() noexcept
Access the z element from the point.
Definition point.hpp:112
constexpr friend bool operator==(point const &lhs, point const &rhs) noexcept
Compare if two points are equal.
Definition point.hpp:209
constexpr point(point< 2 > const &other, float z) noexcept
Construct a point from a lower dimension point.
Definition point.hpp:42
constexpr float & y() noexcept
Access the y element from the point.
Definition point.hpp:104
friend constexpr point floor(point const &rhs) noexcept
Round the coordinates of a point toward the left-bottom.
Definition point.hpp:265
constexpr float const & x() const noexcept
Access the x element from the point.
Definition point.hpp:120
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector.hpp:21
T max(T... args)
T to_string(T... args)