acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
point.h
1#pragma once
2
3
4#include "acme/prototype/geometry/sequence.h"
5
6
7
8
9template < prototype_number NUMBER >
11 public sequence_type < NUMBER, 2 >
12{
13public:
14
15
16 using UNIT_TYPE = NUMBER;
17 //using SIZE_TYPE = size_type < NUMBER >;
18 //using RECTANGLE_TYPE = rectangle_type < NUMBER >;
19
20
22
23
24 constexpr point_type() {}
26
27
28
29 consteval point2_t semantic_t() const { return {}; }
30
31 //point_type(nullptr_t) : sequence_type < NUMBER, 2 >(nullptr) {}
32
33// sequence_type(const sequence_type&) = default;
34
35// template <prototype_number T,
36// std::enable_if_t<T::SIZE == SIZE &&
37// std::is_same_v<typename T::COORDINATE, COORDINATE>, ::i32> = 0>
38 template < prototype_number A >
39 constexpr point_type(A a)
40 {
41
42 this->set_all(a);
43
44 }
45
46 template < prototype_number X, prototype_number Y >
47 constexpr point_type(X x, Y y)
48 {
49 this->m_coordinatea[0] = (UNIT_TYPE) x;
50 this->m_coordinatea[1] = (UNIT_TYPE) y;
51 }
52
53 template < prototype_number NUMBER1 >
54 constexpr point_type(const sequence_type < NUMBER1, 2 > & sequence) :
55 sequence_type < UNIT_TYPE, 2 >(sequence)
56 {
57
58 }
59
60
61 constexpr point_type(const lparam & lparam);
62
63
64// sequence_type(COORDINATE s) {
65// for (size_t i = 0; i < SIZE; ++i)
66// m_coordinatea[i] = s;
67// }
68
69
70// void set_all(COORDINATE coordinate)
71// {
72//
73// for (size_t i = 0; i < SIZE; ++i)
74// {
75//
76// m_coordinatea[i] = coordinate;
77//
78// }
79//
80// }
81
82
83// point_type() noexcept { this->x = (UNIT_TYPE)0; this->y = (UNIT_TYPE)0; }
84// point_type(no_initialize_t) noexcept { }
85// point_type(nullptr_t) noexcept { this->x = (UNIT_TYPE)0; this->y = (UNIT_TYPE)0; }
86// point_type(UNIT_TYPE x, UNIT_TYPE y) noexcept { this->x = x; this->y = y; }
87// ///point_type(const ::lparam& lparam) noexcept : point_type(lparam.x, lparam.y) {}
88// //point_type(const ::u32 u) noexcept : point_type((UNIT_TYPE) u32_x(u), (UNIT_TYPE)u32_y(u)) {}
89// //point_type(const ::u64 u) noexcept : point_type((UNIT_TYPE)u64_x(u), (UNIT_TYPE)u64_y(u)) {}
90// //point_type(const SIZE_TYPE & size) noexcept : point_type(size.cx, size.cy) {}
91//
92//
101//
102//
103// point_type(const sequence_type < UNIT_TYPE, 2 > & sequence)
104// {
105//
106// this->x = sequence.x;
107// this->y = sequence.y;
108//
109// }
110//
111//
120//
121//
122// ///point_type(const ::sequence_type < NUMBER, 2 > & point) noexcept { this->x = (UNIT_TYPE) point.x; this->y = (UNIT_TYPE) point.y; }
123//
125// // point_type(const SIZE & size) noexcept { ::copy(*this, size); }
126//
127//#ifdef WINDOWS
128// //rectangle_type(const Gdiplus::Rect& t) noexcept : { ::copy(this, &t); }
129// //rectangle_type(const Gdiplus::RectF& t) noexcept : { ::copy(this, &t); }
130// //rectangle_type(const Gdiplus::Rect* p) noexcept : { ::copy(this, p); }
131// //rectangle_type(const Gdiplus::RectF* p) noexcept : { ::copy(this, p); }
132//#endif
133//#ifdef __APPLE__
136//#endif
137
138 //constexpr const UNIT_TYPE & x() const {return this->x;}
139 //UNIT_TYPE & x() {return this->x;}
140 //constexpr const UNIT_TYPE & y() const {return this->y;}
141 //UNIT_TYPE & y() {return this->y;}
142
143// template < raw_primitive_point RAW_PRIMITIVE_POINT >
144// inline point_type& operator = (const RAW_PRIMITIVE_POINT& point) { this->x = (UNIT_TYPE)point.x; this->y = (UNIT_TYPE)point.y; return *this; }
145
146
147// template < prototype_size PRIMITIVE_SIZE >
148// inline point_type & operator = (const PRIMITIVE_SIZE & point) { this->x = (UNIT_TYPE) point.x; this->y = (UNIT_TYPE)point.y; return *this; }
149 //template < prototype_number E >
150 constexpr bool is_same_by(UNIT_TYPE e, const point_type & p) const
151 {
152
153 return ::std::abs(this->x - p.x) < ::std::abs(e)
154 && ::std::abs(this->y - p.y) < ::std::abs(e);
155
156 }
157
158
159 inline point_type & operator = (const ::point_type < UNIT_TYPE > & point) { this->x = point.x; this->y = point.y; return *this; }
160
161 //operator POINT_BASE_TYPE*() noexcept { return this; }
162 //operator const POINT_BASE_TYPE*() const noexcept { return this; }
163 //operator ::lparam() const { return lparam(); }
164
165 ::u32 as_u32() const noexcept { return as_u32(this->x, this->y); }
166 ::u64 as_u64() const noexcept { return as_u64(this->x, this->y); }
167 //::lparam lparam() const noexcept { return { this->x, this->y }; }
168
169 point_type& clear() { this->x = (UNIT_TYPE)0; this->y = (UNIT_TYPE) 0; return *this; }
170
171
172 point_type & offset(UNIT_TYPE xOffset, UNIT_TYPE yOffset) noexcept { this->x += xOffset; this->y += yOffset; return *this; }
173 point_type & offset(const sequence_type < UNIT_TYPE, 2 > & sequence) noexcept { this->x += sequence.x; this->y += sequence.y; return *this; }
174// point_type & offset(const SIZE_TYPE& size) noexcept { this->x += size.cx; this->y += size.cy; return *this; }
175 point_type & set(UNIT_TYPE x, UNIT_TYPE y) noexcept { this->x = x; this->y = y; return *this; }
176
177
178
179// inline UNIT_TYPE get_dimension(enum_orientation eorientation) const noexcept { return get_dimension(eorientation, this->x, this->y); }
180// inline UNIT_TYPE get_orthogonal_dimension(enum_orientation eorientation) const noexcept { return get_normal_dimension(eorientation, this->x, this->y); }
181// inline UNIT_TYPE get_orthogonal(enum_orientation eorientation)const noexcept { return get_orthogonal_dimension(eorientation); }
182// inline UNIT_TYPE get_normal_dimension(enum_orientation eorientation) const noexcept { return get_orthogonal_dimension(eorientation); }
183// inline UNIT_TYPE get_normal(enum_orientation eorientation) const noexcept { return get_orthogonal_dimension(eorientation); }
184
185
186// inline UNIT_TYPE set_dimension(enum_orientation eorientation, UNIT_TYPE l) noexcept;
187// inline UNIT_TYPE set_orthogonal_dimension(enum_orientation eorientation, UNIT_TYPE l) noexcept;
188// inline UNIT_TYPE set_orthogonal(enum_orientation eorientation, UNIT_TYPE l) noexcept { return set_orthogonal_dimension(eorientation,l); }
189// inline UNIT_TYPE set_normal_dimension(enum_orientation eorientation, UNIT_TYPE l) noexcept { return set_orthogonal_dimension(eorientation,l); }
190// inline UNIT_TYPE set_normal(enum_orientation eorientation, UNIT_TYPE l) noexcept { return set_orthogonal_dimension(eorientation,l); }
191
192 template < prototype_point POINT >
193 ::f64 distance(const POINT& point) const { auto s = *this - point; return sqrt((::f64) (s.cx * s.cx + s.cy * s.cy)); }
194
195 template < prototype_point POINT >
196 point_type mid(const POINT& point) const
197 {
198 return { (UNIT_TYPE)((this->x + point.x) / (UNIT_TYPE)2), (UNIT_TYPE)((this->y + point.y) / (UNIT_TYPE)2) };
199 }
200
201
202 template < prototype_point POINT >
203 inline bool operator==(const POINT & point) const noexcept { return (this->x == (UNIT_TYPE) point.x && this->y == (UNIT_TYPE) point.y); }
204
205 //template < prototype_point POINT >
206 //inline bool operator!=(const POINT & point) const noexcept { return (this->x != (UNIT_TYPE) point.x || this->y != (UNIT_TYPE) point.y); }
207
208
209 inline bool operator==(nullptr_t) const noexcept { return ::is_null(this); }
210 //inline bool operator!=(nullptr_t) const noexcept { return !::is_null(this); }
211
212 template < prototype_number NUMBER1 >
213 point_type < largest_number < UNIT_TYPE, NUMBER1 > > operator *(NUMBER1 n) const
214 {
216 result[0] = (largest_number < UNIT_TYPE, NUMBER1 >) (this->m_coordinatea[0] * n);
217 result[1] = (largest_number < UNIT_TYPE, NUMBER1 >) (this->m_coordinatea[1] * n);
218 return result;
219 }
220
221
222 template < prototype_number NUMBER1 >
223 point_type < largest_number < UNIT_TYPE, NUMBER1 > > operator /(NUMBER1 n) const
224 {
226 result[0] = (largest_number < UNIT_TYPE, NUMBER1 >) (this->m_coordinatea[0] / n);
227 result[1] = (largest_number < UNIT_TYPE, NUMBER1 >) (this->m_coordinatea[1] / n);
228 return result;
229 }
230
231
232 template < prototype_size SIZE >
233 inline point_type& operator +=(const SIZE& size) noexcept { this->x = (UNIT_TYPE) (this->x + size.cx); this->y = (UNIT_TYPE)(this->y + size.cy); return *this; }
234
235 template < prototype_size SIZE >
236 inline point_type& operator -=(const SIZE& size) noexcept { this->x = (UNIT_TYPE)(this->x - size.cx); this->y = (UNIT_TYPE)(this->y - size.cy); return *this; }
237
238 template < prototype_point POINT >
239 inline point_type& operator +=(const POINT& point) noexcept { this->x = (UNIT_TYPE)(this->x + point.x); this->y = (UNIT_TYPE)(this->y + point.y); return *this; }
240
241 template < prototype_point POINT >
242 inline point_type& operator -=(const POINT& point) noexcept { this->x = (UNIT_TYPE)(this->x - point.x); this->y = (UNIT_TYPE)(this->y - point.y); return *this; }
243
244 template < prototype_number NUMBER1 >
245 inline point_type < largest_number < UNIT_TYPE, NUMBER1 > > operator +(const sequence_type < NUMBER1, 2 > & sequence) const noexcept { return point_type < largest_number < UNIT_TYPE, NUMBER1 > >(this->x + sequence.x, this->y + sequence.y); }
246
247// template < prototype_point POINT >
248// inline point_type operator +(const POINT & point) const noexcept { return point_type(this->x + point.x, this->y + point.y); }
249
250
251 template < prototype_number NUMBER1 >
252 inline point_type < largest_number < UNIT_TYPE, NUMBER1 > > operator-(const sequence_type < NUMBER1, 2 > & sequence) const noexcept { return point_type < largest_number < UNIT_TYPE, NUMBER1 > >(this->x - sequence.x, this->y - sequence.y); }
253
254 inline point_type operator-() const noexcept { return point_type(-this->x, -this->y); }
255 inline point_type operator +() const noexcept { return point_type(this->x, this->y); }
256 //inline point_type operator +(const point_type& point) const noexcept { return point_type(this->x + point.x, this->y + point.y); }
257 //inline SIZE_TYPE operator-(const point_type& point) const noexcept { return SIZE_TYPE(this->x - point.x, this->y - point.y); }
258
259// inline RECTANGLE_TYPE operator +(const RECTANGLE_TYPE & rectangle) const noexcept { return RECTANGLE_TYPE(rectangle) + *this; }
260// inline RECTANGLE_TYPE operator-(const RECTANGLE_TYPE & rectangle) const noexcept { return RECTANGLE_TYPE(rectangle) - *this; }
261
262
263// inline point_type& operator +=(const SHIFT_I32& shift) noexcept { this->x = (UNIT_TYPE)(this->x + shift.Δx); this->y = (UNIT_TYPE)(this->y + shift.Δy); return *this; }
264// inline point_type& operator-=(const SHIFT_I32& shift) noexcept { this->x = (UNIT_TYPE)(this->x - shift.Δx); this->y = (UNIT_TYPE)(this->y - shift.Δy); return *this; }
265//
266// inline point_type operator +(const SHIFT_I32& shift) noexcept { return { (UNIT_TYPE)(this->x + shift.Δx), (UNIT_TYPE)(this->y + shift.Δy) }; }
267// inline point_type operator-(const SHIFT_I32& shift) noexcept { return { (UNIT_TYPE)(this->x - shift.Δx), (UNIT_TYPE)(this->y - shift.Δy) }; }
268
269
270
271// void x_constraint(const RECTANGLE_TYPE& rectangle) noexcept
272// {
273//
274// if (this->x < rectangle.left)
275// {
276//
277// this->x = rectangle.left;
278//
279// }
280// else if (this->x > rectangle.right)
281// {
282//
283// this->x = rectangle.right;
284//
285// }
286//
287// }
288//
289// void y_constraint(const RECTANGLE_TYPE& rectangle) noexcept
290// {
291//
292// if (this->y < rectangle.top)
293// {
294//
295// this->y = rectangle.top;
296//
297// }
298// else if (this->y > rectangle.bottom)
299// {
300//
301// this->y = rectangle.bottom;
302//
303// }
304//
305// }
306//
307// void constraint(const RECTANGLE_TYPE & rectangle) noexcept
308// {
309//
310// x_constraint(rectangle);
311//
312// y_constraint(rectangle);
313//
314// }
315
316
317
318 inline bool operator < (const point_type& point) const noexcept
319 {
320
321 auto d = this->y - point.y;
322
323 if (d < 0) return true;
324
325 if (d > 0) return false;
326
327 return this->x < point.x;
328
329 }
330
331
332 bool is_null() const
333 {
334
335 return this->x == 0 && this->y == 0;
336
337 }
338
339
340 template < prototype_point POINT >
341 void expand_bounding_box(POINT & top_left, POINT & bottom_right) const
342 {
343
344 expand_minimum_maximum(top_left.x, bottom_right.x, this->x);
345
346 expand_minimum_maximum(top_left.y, bottom_right.y, this->y);
347
348 }
349
350
351 template < prototype_point POINT >
352 static void expand_bounding_box(POINT & top_left, POINT & bottom_right, const point_type * ppoint, ::collection::count count)
353 {
354
355 while(count > 0)
356 {
357
358 ppoint->expand_bounding_box(top_left, bottom_right);
359
360 count--;
361
362 ppoint++;
363
364 }
365
366 }
367
368
369};
370
371
372
373
374
375//inline auto as_i32_point(const ::lparam & lparam) noexcept { return ::i32_point(lparam.x, lparam.y); }
376inline auto as_i32_point(const ::u32 u) noexcept { return ::i32_point((::i32)u32_x(u), (::i32)u32_y(u)); }
377inline auto as_i32_point(const ::u64 u) noexcept { return ::i32_point((::i32)u64_x(u), (::i32)u64_y(u)); }
378
379
380//inline auto as_i64_point(const ::lparam & lparam) noexcept { return ::i64_point(lparam.x, lparam.y); }
381inline auto as_i64_point(const ::u32 u) noexcept { return ::i64_point((::i64)u32_x(u), (::i64)u32_y(u)); }
382inline auto as_i64_point(const ::u64 u) noexcept { return ::i64_point((::i64)u64_x(u), (::i64)u64_y(u)); }
383
384
385//inline auto as_f32_point(const ::lparam & lparam) noexcept { return ::f32_point((::f32)lparam.x, (::f32)lparam.y); }
386inline auto as_f32_point(const ::u32 u) noexcept { return ::f32_point((::f32)u32_x(u), (::f32)u32_y(u)); }
387inline auto as_f32_point(const ::u64 u) noexcept { return ::f32_point((::f32)u64_x(u), (::f32)u64_y(u)); }
388
389
390//inline auto as_f64_point(const ::lparam & lparam) noexcept { return ::f64_point(lparam.x, lparam.y); }
391inline auto as_f64_point(const ::u32 u) noexcept { return ::f64_point((::f64)u32_x(u), (::f64)u32_y(u)); }
392inline auto as_f64_point(const ::u64 u) noexcept { return ::f64_point((::f64)u64_x(u), (::f64)u64_y(u)); }
393
394
395inline bool is_almost_equal(const ::f64_point& p1, const ::f64_point& p2, ::f64 dTolerance)
396{
397
398 return is_almost_equal(p1.x, p2.x, dTolerance) && is_almost_equal(p1.y, p2.y, dTolerance);
399
400}
401
402
403inline bool is_different(const ::f64_point& p1, const ::f64_point& p2, ::f64 dTolerance)
404{
405
406 return !is_almost_equal(p1, p2, dTolerance);
407
408}
409
410
411template < prototype_number NUMBER1, prototype_number NUMBER2 >
412inline ::size_type < largest_number < NUMBER1, NUMBER2 > > operator -(const ::point_type < NUMBER1 > & point1, const ::point_type < NUMBER2 > & point2) noexcept
413{
414
415 return ::size_type < largest_number < NUMBER1, NUMBER2 > >((largest_number < NUMBER1, NUMBER2 >) (point1.x - point2.x),
416 (largest_number < NUMBER1, NUMBER2 >)(point1.y - point2.y));
417
418}
419
420
421
422
423
424#include "acme/platform/lparam.h"
425
426
427template < prototype_number NUMBER >
428constexpr point_type<NUMBER>::point_type(const lparam &lparam) : sequence_type<UNIT_TYPE, 2>(lparam.x(), lparam.y())
429{
430
431
432}
433
434
435template < prototype_point POINT >
436constexpr lparam::lparam(const POINT & point) : lparam((::i32)point.x, (::i32)point.y)
437{
438
439
440}
441
442
443constexpr ::i32_point lparam::point() const
444{
445
446 return {(::i32)this->x(), (::i32)this->y()};
447
448}
449
450
451
452
453
454template <prototype_number NUMBER>
455struct std::formatter<point_type<NUMBER>>
456{
457 bool m_bIncludeParenthesis = false; // p
458 bool m_bIncludeNames = false; // n
459
460
461 constexpr bool check_option(auto &it, const auto & end)
462 {
463
464 if (it != end)
465 {
466
467 if (*it == 'p')
468 {
469 m_bIncludeParenthesis = true;
470 it++;
471 return true;
472 }
473 else if (*it == 'n')
474 {
475 m_bIncludeNames = true;
476 it++;
477 return true;
478 }
479 else if (*it != '}')
480 {
481
482 throw std::format_error("Invalid format specifier for Point.");
483
484 }
485
486 }
487
488 return false;
489
490 }
491
492
493
494 // Parses the format specifier
495 constexpr auto parse(std::format_parse_context& ctx) {
496 auto it = ctx.begin(), end = ctx.end();
497 while (check_option(it, end));
498 return it;
499 }
500
501 // Formats the Point based on the flag set in parse()
502 auto format(const point_type<NUMBER> & point, std::format_context& ctx) const {
503 if (m_bIncludeNames)
504 {
505 if (m_bIncludeParenthesis) {
506 return std::format_to(ctx.out(), "(x:{}, y:{})", point.x, point.y);
507 } else {
508 return std::format_to(ctx.out(), "x:{}, y:{}", point.x, point.y);
509 }
510 }
511 else
512 {
513 if (m_bIncludeParenthesis) {
514 return std::format_to(ctx.out(), "({}, {})", point.x, point.y);
515 } else {
516 return std::format_to(ctx.out(), "{}, {}", point.x, point.y);
517 }
518 }
519 }
520};
521
522
523
Definition lparam.h:9
Definition point.h:12
constexpr point_type()
using sequence_type < NUMBER, 2 >sequence_type;
Definition point.h:24
Definition _tags.h:5
Definition sequence.h:236