acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
sequence.h
1/*
2 NanoGUI was developed by Wenzel Jakob <[email protected]>.
3 The widget drawing code is based on the NanoVG demo application
4 by Mikko Mononen.
5
6 All rights reserved. Use of this source code is governed by a
7 BSD-style license that can be found in the LICENSE.txt file.
8*/
9// Merge with estamira/particle/vec4:minimum_maximum_rand
10#pragma once
11
12
13//#include "common.h"
14//#include "traits.h"
15//#include <cassert>
16#include <cmath>
17//#include <iosfwd>
18//#include <string.h> // ::memory_set
19
20
21template<prototype_number NUMBER, ::i32 t_iSize >
23{
24
25
26 using sequence_tag = sequence_t;
27 using sequence_size = sequence_size_t<t_iSize>;
28 using COORDINATE = NUMBER;
29 using UNIT_TYPE = NUMBER;
30 static const ::i32 SIZE = t_iSize;
31
32
33};
34
35
36template<prototype_number NUMBER>
37struct sequence_t_type<NUMBER, 1>
38{
39
40
41 using COORDINATE = NUMBER;
42 using UNIT_TYPE = NUMBER;
43 static const ::i32 SIZE = 1;
44
45
46 union
47 {
48 struct
49 {
50 union
51 {
52 COORDINATE x, r, s;
53 };
54 };
55 COORDINATE m_coordinatea[SIZE];
56 };
57
58
59};
60
61
62template<prototype_number NUMBER>
63struct std::hash<::sequence_t_type<NUMBER, 1>>
64{
65 std::size_t operator()(const ::sequence_t_type<NUMBER, 1> &s) const noexcept
66 {
67 std::size_t h1 = std::hash<NUMBER>{}(s.x);
68 return h1;
69 }
70};
71
72
73
74template < prototype_number NUMBER >
75struct sequence_t_type<NUMBER, 2>
76{
77
78
79 using COORDINATE = NUMBER;
80 using UNIT_TYPE = NUMBER;
81 static const ::i32 SIZE = 2;
82
83 union
84 {
85 struct
86 {
87 union
88 {
89 COORDINATE x, r, s, cx, width;
90 };
91 union
92 {
93 COORDINATE y, g, t, cy, height;
94 };
95 };
96 COORDINATE m_coordinatea[SIZE];
97 };
98
99
100};
101
102
103template<prototype_number NUMBER>
104struct std::hash<::sequence_t_type<NUMBER, 2>>
105{
106 std::size_t operator()(const ::sequence_t_type<NUMBER, 2> &s) const noexcept
107 {
108 std::size_t h1 = std::hash<NUMBER>{}(s.x);
109 std::size_t h2 = std::hash<NUMBER>{}(s.y);
110 return h1 ^ (h2 << 1);
111 }
112};
113
114
115
116template<prototype_number NUMBER>
117struct sequence_t_type<NUMBER, 3>
118{
119
120
121 using COORDINATE = NUMBER;
122 using UNIT_TYPE = NUMBER;
123 static const ::i32 SIZE = 3;
124
125
126 union
127 {
128 struct
129 {
130 union
131 {
132 COORDINATE x, r, s, red;
133 };
134 union
135 {
136 COORDINATE y, g, t, green;
137 };
138 union
139 {
140 COORDINATE z, b, p, blue;
141 };
142 };
143 COORDINATE m_coordinatea[SIZE];
144 };
145
146
147};
148
149
150template<prototype_number NUMBER>
151struct std::hash<::sequence_t_type<NUMBER, 3>>
152{
153 std::size_t operator()(const ::sequence_t_type<NUMBER, 3> &s) const noexcept
154 {
155 std::size_t h1 = std::hash<NUMBER>{}(s.x);
156 std::size_t h2 = std::hash<NUMBER>{}(s.y);
157 std::size_t h3 = std::hash<NUMBER>{}(s.z);
158 return h1 ^ (h2 << 1) ^ (h3 << 2);
159 }
160};
161
162
163template<prototype_number NUMBER>
164struct sequence_t_type<NUMBER, 4>
165{
166
167
168 using COORDINATE = NUMBER;
169 using UNIT_TYPE = NUMBER;
170 static const ::i32 SIZE = 4;
171
172
173 union
174 {
175 struct
176 {
177 union
178 {
179 COORDINATE x, r, s, left, red;
180 };
181 union
182 {
183 COORDINATE y, g, t, top, green;
184 };
185 union
186 {
187 COORDINATE z, b, p, right, blue;
188 };
189 union
190 {
191 COORDINATE w, a, q, bottom, opacity;
192 };
193 };
194 COORDINATE m_coordinatea[SIZE];
195 };
196
197};
198
199template<prototype_number NUMBER>
200struct std::hash<::sequence_t_type<NUMBER, 4>>
201{
202 std::size_t operator()(const ::sequence_t_type<NUMBER, 4> &s) const noexcept
203 {
204 std::size_t h1 = std::hash<NUMBER>{}(s.x);
205 std::size_t h2 = std::hash<NUMBER>{}(s.y);
206 std::size_t h3 = std::hash<NUMBER>{}(s.z);
207 std::size_t h4 = std::hash<NUMBER>{}(s.w);
208 return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 2);
209 }
210};
211
212using i32_sequence2_t = sequence_t_type<::i32, 2>;
213using i32_sequence3_t = sequence_t_type<::i32, 3>;
214using i32_sequence4_t = sequence_t_type<::i32, 4>;
215
216
217using i64_sequence2_t = sequence_t_type<::i64, 2>;
218using i64_sequence3_t = sequence_t_type<::i64, 3>;
219using i64_sequence4_t = sequence_t_type<::i64, 4>;
220
221
222using f32_sequence2_t = sequence_t_type<::f32, 2>;
223using f32_sequence3_t = sequence_t_type<::f32, 3>;
224using f32_sequence4_t = sequence_t_type<::f32, 4>;
225
226
227using f64_sequence2_t = sequence_t_type<::f64, 2>;
228using f64_sequence3_t = sequence_t_type<::f64, 3>;
229using f64_sequence4_t = sequence_t_type<::f64, 4>;
230
231
232
233template < prototype_number NUMBER, ::i32 t_iSize >
234struct sequence_type :
235 public sequence_t_type<NUMBER, t_iSize>
236{
237
238 using sequence_tag = sequence_t;
239 using sequence_size = sequence_size_t < t_iSize >;
240 using SEQUENCE_T = sequence_t_type< NUMBER, t_iSize >;
241 using COORDINATE = typename SEQUENCE_T::COORDINATE;
242 using UNIT_TYPE = typename SEQUENCE_T::COORDINATE;
243 static const ::i32 SIZE = t_iSize;
244
245
246 static constexpr bool IS_MATRIX = false;
247
248
249 constexpr sequence_type()
250 {
251
252 set_null();
253
254 }
255
256 sequence_type(no_initialize_t)
257 {
258
259
260 }
261
262
263 constexpr sequence_type(UNIT_TYPE n)
264 {
265
266 set_all(n);
267
268 }
269
270
271 template < prototype_sequence2 S2 >
272 constexpr sequence_type(const S2 & s2)
273 requires(SIZE == 2)
274 {
275 this->m_coordinatea[0] = (UNIT_TYPE) s2.x;
276 this->m_coordinatea[1] = (UNIT_TYPE) s2.y;
277 }
278
279
280 template < prototype_sequence3 S3 >
281 constexpr sequence_type(const S3 & s3)
282 requires(SIZE == 3)
283 {
284 this->m_coordinatea[0] = (UNIT_TYPE) s3.x;
285 this->m_coordinatea[1] = (UNIT_TYPE) s3.y;
286 this->m_coordinatea[2] = (UNIT_TYPE) s3.z;
287 }
288
289
290 template<prototype_sequence4 S4>
291 constexpr sequence_type(const S4 &s4)
292 requires(SIZE >= 4)
293 {
294 this->m_coordinatea[0] = (UNIT_TYPE)s4.x;
295 this->m_coordinatea[1] = (UNIT_TYPE)s4.y;
296 this->m_coordinatea[2] = (UNIT_TYPE)s4.z;
297 this->m_coordinatea[3] = (UNIT_TYPE)s4.w;
298 }
299
300 template<prototype_number NUMBER1>
301 constexpr sequence_type(const NUMBER1 *p) // expects p to point to an array of at least SIZE elements
302 {
303 for (::collection::count i = 0; i < SIZE; ++i)
304 this->m_coordinatea[i] = (UNIT_TYPE)p[i];
305 }
306
307
308 template < prototype_number NUMBER1 >
309 constexpr sequence_type(const sequence_t_type < NUMBER1, 4 > & sequence)
310 requires(SIZE >= 4)
311 {
312 this->m_coordinatea[0] = (UNIT_TYPE) sequence.m_coordinatea[0];
313 this->m_coordinatea[1] = (UNIT_TYPE) sequence.m_coordinatea[1];
314 this->m_coordinatea[2] = (UNIT_TYPE) sequence.m_coordinatea[2];
315 this->m_coordinatea[3] = (UNIT_TYPE) sequence.m_coordinatea[3];
316 }
317
318
319 template<prototype_number NUMBER0, prototype_number NUMBER1>
320 constexpr sequence_type(NUMBER0 coordinate0, NUMBER1 coordinate1)
321 requires(SIZE == 2)
322 {
323 this->m_coordinatea[0] = (UNIT_TYPE)coordinate0;
324 this->m_coordinatea[1] = (UNIT_TYPE)coordinate1;
325 }
326
327
328 template<prototype_number NUMBER0, prototype_number NUMBER1, prototype_number NUMBER2>
329 constexpr sequence_type(NUMBER0 coordinate0, NUMBER1 coordinate1, NUMBER2 coordinate2)
330 requires(SIZE == 3)
331 {
332 this->m_coordinatea[0] = (UNIT_TYPE)coordinate0;
333 this->m_coordinatea[1] = (UNIT_TYPE)coordinate1;
334 this->m_coordinatea[2] = (UNIT_TYPE)coordinate2;
335 }
336
337 template<prototype_number NUMBER0, prototype_number NUMBER1, prototype_number NUMBER2, prototype_number NUMBER3>
338 constexpr sequence_type(NUMBER0 coordinate0, NUMBER1 coordinate1, NUMBER2 coordinate2, NUMBER3 coordinate3)
339 requires(SIZE == 4)
340 {
341 this->m_coordinatea[0] = (UNIT_TYPE)coordinate0;
342 this->m_coordinatea[1] = (UNIT_TYPE)coordinate1;
343 this->m_coordinatea[2] = (UNIT_TYPE)coordinate2;
344 this->m_coordinatea[3] = (UNIT_TYPE)coordinate3;
345 }
346
347 template<prototype_number NUMBER0, prototype_number NUMBER3>
348 constexpr sequence_type(const sequence_type<NUMBER0, 3> &seq3, NUMBER3 coordinate3)
349 requires(SIZE == 4)
350 {
351 this->m_coordinatea[0] = (UNIT_TYPE)seq3[0];
352 this->m_coordinatea[1] = (UNIT_TYPE)seq3[1];
353 this->m_coordinatea[2] = (UNIT_TYPE)seq3[2];
354 this->m_coordinatea[3] = (UNIT_TYPE) coordinate3;
355 }
356
357 template<prototype_number NUMBER0, prototype_number NUMBER1>
358 constexpr sequence_type(NUMBER0 coordinate0, const sequence_type<NUMBER1, 3> &seq3)
359 requires(SIZE == 4)
360 {
361 this->m_coordinatea[0] = (UNIT_TYPE)coordinate0;
362 this->m_coordinatea[1] = (UNIT_TYPE)seq3[0];
363 this->m_coordinatea[2] = (UNIT_TYPE)seq3[1];
364 this->m_coordinatea[3] = (UNIT_TYPE)seq3[2];
365 }
366
367 constexpr ::collection::count get_size() const { return SIZE; }
368 constexpr ::collection::count get_count() const { return this->get_size(); }
369
370
371
372
373 void set_null() { set_all(0); }
374
375
376 sequence_type &null()
377 {
378
379 set_null();
380
381 return *this;
382 }
383
384 static sequence_type Null() { return {}; }
385
386 constexpr COORDINATE & set_coordinate(::collection::index i, COORDINATE coordinate)
387 {
388
389 return this->m_coordinatea[i] = coordinate;
390
391 }
392
393
394 constexpr COORDINATE coordinate(::collection::index i) const
395 {
396
397 return this->m_coordinatea[i];
398
399 }
400
401
402 constexpr COORDINATE & coordinate(::collection::index i)
403 {
404
405 return this->m_coordinatea[i];
406
407 }
408
409
410 void set_all(COORDINATE coordinate)
411 {
412
413 for (::collection::count i = 0; i < SIZE; ++i)
414 {
415
416 this->m_coordinatea[i] = coordinate;
417
418 }
419
420 }
421
422 bool is_all(COORDINATE coordinate) const
423 {
424
425 for (::collection::count i = 0; i < SIZE; ++i)
426 {
427
428 if(this->m_coordinatea[i] != coordinate)
429 {
430
431 return false;
432
433 }
434
435 }
436
437 return true;
438
439 }
440
441
442
443 // simple menthods: operates on x, y
444 template < ::collection::count S = SIZE, std::enable_if_t<S <= 2, ::i32> = 0 >
445 inline void add2(const sequence_type & a)
446 {
447 this->x += a.x;
448 this->y += a.y;
449 }
450 template < ::collection::count S = SIZE, std::enable_if_t<S <= 2, ::i32> = 0 >
451 inline void sub2(const sequence_type & a)
452 {
453 this->x -= a.x;
454 this->y -= a.y;
455 }
456 template < ::collection::count S = SIZE, std::enable_if_t<S <= 2, ::i32> = 0 >
457 inline void mul2(UNIT_TYPE n)
458 {
459 this->x *= n;
460 this->y *= n;
461 }
462 template < ::collection::count S = SIZE, std::enable_if_t<S <= 2, ::i32> = 0 >
463 inline void set2(UNIT_TYPE a, UNIT_TYPE b)
464 {
465 this->x = a;
466 this->y = b;
467 }
468
469 template < ::collection::count S = SIZE, std::enable_if_t<S <= 2, ::i32> = 0 >
470 static inline void mix2(const sequence_type &a, const sequence_type &b, UNIT_TYPE t, sequence_type &c)
471 {
472 c.x = a.x*((UNIT_TYPE)1.0 - t) + b.x*t;
473 c.y = a.y*((UNIT_TYPE)1.0 - t) + b.y*t;
474 }
475
476 // simple menthods: operates on x, y, z
477 template < ::collection::count S = SIZE, std::enable_if_t<S <= 3, ::i32> = 0 >
478 inline void add3(const sequence_type & a)
479 {
480 this->x += a.x;
481 this->y += a.y;
482 this->z += a.z;
483 }
484 template < ::collection::count S = SIZE, std::enable_if_t<S <= 3, ::i32> = 0 >
485 inline void sub3(const sequence_type & a)
486 {
487 this->x -= a.x;
488 this->y -= a.y;
489 this->z -= a.z;
490 }
491 template < ::collection::count S = SIZE, std::enable_if_t<S <= 3, ::i32> = 0 >
492 inline void mul3(UNIT_TYPE n)
493 {
494 this->x *= n;
495 this->y *= n;
496 this->z *= n;
497 }
498 template < ::collection::count S = SIZE, std::enable_if_t<S <= 3, ::i32> = 0 >
499 inline void set3(UNIT_TYPE a, UNIT_TYPE b, UNIT_TYPE c)
500 {
501 this->x = a;
502 this->y = b;
503 this->z = c;
504 }
505
506 template < ::collection::count S = SIZE, std::enable_if_t<S <= 3, ::i32> = 0 >
507 static inline void mix3(const sequence_type &a, const sequence_type &b, UNIT_TYPE t, sequence_type &c)
508 {
509 c.x = a.x*((UNIT_TYPE)1.0 - t) + b.x*t;
510 c.y = a.y*((UNIT_TYPE)1.0 - t) + b.y*t;
511 c.z = a.z*((UNIT_TYPE)1.0 - t) + b.z*t;
512 }
513
514 // simple menthods: operates on x, y, z, w
515 template < ::collection::count S = SIZE, std::enable_if_t<S <= 4, ::i32> = 0 >
516 inline void add4(const sequence_type & q)
517 {
518 this->x += q.x;
519 this->y += q.y;
520 this->z += q.z;
521 this->w += q.w;
522 }
523 template < ::collection::count S = SIZE, std::enable_if_t<S <= 4, ::i32> = 0 >
524 inline void sub4(const sequence_type & q)
525 {
526 this->x -= q.x;
527 this->y -= q.y;
528 this->w -= q.w;
529 this->z -= q.z;
530 }
531 template < ::collection::count S = SIZE, std::enable_if_t<S <= 4, ::i32> = 0 >
532 inline void mul4(UNIT_TYPE n)
533 {
534 this->x *= n;
535 this->y *= n;
536 this->w *= n;
537 this->z *= n;
538 }
539 template < ::collection::count S = SIZE, std::enable_if_t<S <= 4, ::i32> = 0 >
540 inline void set4(UNIT_TYPE a, UNIT_TYPE b, UNIT_TYPE c, UNIT_TYPE d)
541 {
542 this->x = a;
543 this->y = b;
544 this->y = c;
545 this->z = d;
546 }
547
548 template < ::collection::count S = SIZE, std::enable_if_t<S <= 4, ::i32> = 0 >
549 static inline void mix4(const sequence_type &a, const sequence_type &b, UNIT_TYPE t, sequence_type &c)
550 {
551 c.x = a.x*((UNIT_TYPE)1.0 - t) + b.x*t;
552 c.y = a.y*((UNIT_TYPE)1.0 - t) + b.y*t;
553 c.w = a.z*((UNIT_TYPE)1.0 - t) + b.z*t;
554 c.z = a.w*((UNIT_TYPE)1.0 - t) + b.w*t;
555 }
556
557
558 sequence_type operator-() const
559 {
560 sequence_type result;
561 for (::collection::count i = 0; i < SIZE; ++i)
562 result[i] = -this->m_coordinatea[i];
563 return result;
564 }
565
566
567 sequence_type operator +(const sequence_type& b) const
568 {
569 sequence_type result;
570 for (::collection::count i = 0; i < SIZE; ++i)
571 result[i] = this->m_coordinatea[i] + b.m_coordinatea[i];
572 return result;
573 }
574
575 sequence_type& operator +=(const sequence_type& a) {
576 for (::collection::count i = 0; i < SIZE; ++i)
577 this->m_coordinatea[i] += a.m_coordinatea[i];
578 return *this;
579 }
580
581 friend sequence_type operator-(const sequence_type& a, const sequence_type& b) {
582 sequence_type result;
583 for (::collection::count i = 0; i < SIZE; ++i)
584 result[i] = a.m_coordinatea[i] - b.m_coordinatea[i];
585 return result;
586 }
587
588 sequence_type& operator-=(const sequence_type& a) {
589 for (::collection::count i = 0; i < SIZE; ++i)
590 this->m_coordinatea[i] -= a.m_coordinatea[i];
591 return *this;
592 }
593
594 sequence_type operator *(const sequence_type& b) const {
595 const sequence_type &a = *this;
596 sequence_type result;
597 for (::collection::count i = 0; i < SIZE; ++i)
598 result[i] = a.m_coordinatea[i] * b.m_coordinatea[i];
599 return result;
600 }
601
602 template<prototype_floating FLOATING1>
603 inline sequence_type operator*(const matrix_type<FLOATING1, 3> &M) const
604 requires(t_iSize == 3 && ::std::is_same_v<FLOATING1, NUMBER>);
605
606 template<prototype_floating FLOATING1>
607 inline sequence_type operator*(const matrix_type<FLOATING1, 4> &M) const
608 requires(t_iSize == 4 && ::std::is_same_v<FLOATING1, NUMBER>);
609
610 template < prototype_number NUMBER1 >
611 sequence_type < largest_number < UNIT_TYPE, NUMBER1 >, SIZE > operator *(NUMBER1 n) const
612 {
613 sequence_type < largest_number < UNIT_TYPE, NUMBER1 >, SIZE > result;
614 for (::collection::count i = 0; i < SIZE; ++i)
615 result[i] = (largest_number < UNIT_TYPE, NUMBER1 >) (this->m_coordinatea[i] * n);
616 return result;
617 }
618
619
620 sequence_type& operator*=(const sequence_type& a) {
621 for (::collection::count i = 0; i < SIZE; ++i)
622 this->m_coordinatea[i] *= a.m_coordinatea[i];
623 return *this;
624 }
625
626
627 friend sequence_type operator/(const sequence_type& a, const sequence_type& b) {
628 sequence_type result;
629 for (::collection::count i = 0; i < SIZE; ++i)
630 result[i] = a.m_coordinatea[i] / b.m_coordinatea[i];
631 return result;
632 }
633
634
635 template < prototype_number NUMBER1 >
636 sequence_type < largest_number < UNIT_TYPE, NUMBER1 >, SIZE > operator /(NUMBER1 n) const
637 {
638 sequence_type < largest_number < UNIT_TYPE, NUMBER1 >, SIZE > result;
639 for (::collection::count i = 0; i < SIZE; ++i)
640 result[i] = (largest_number < UNIT_TYPE, NUMBER1 >) (this->m_coordinatea[i] / n);
641 return result;
642 }
643
644
645 sequence_type& operator/=(const sequence_type& a) {
646 for (::collection::count i = 0; i < SIZE; ++i)
647 this->m_coordinatea[i] /= a.m_coordinatea[i];
648 return *this;
649 }
650
651 template < prototype_number NUMBER1 >
652 sequence_type &operator/=(const NUMBER1 &n)
653 {
654 for (::collection::count i = 0; i < SIZE; ++i)
655 this->m_coordinatea[i] = (UNIT_TYPE) ((largest_number < UNIT_TYPE, NUMBER1 >)this->m_coordinatea[i] / (largest_number < UNIT_TYPE, NUMBER1 >)n);
656 return *this;
657 }
658
659 bool operator==(const sequence_type& a) const {
660 for (::collection::count i = 0; i < SIZE; ++i) {
661 if (this->m_coordinatea[i] != a.m_coordinatea[i])
662 return false;
663 }
664 return true;
665 }
666
667
668
669
670 template < typename PREDICATE >
671 bool is_every(PREDICATE predicate) const
672 {
673
674 for (::collection::count i = 0; i < SIZE; ++i)
675 {
676
677 if (!predicate(this->m_coordinatea[i]))
678 {
679
680 return false;
681
682 }
683
684 }
685
686 return true;
687
688 }
689
690
691 bool is_empty() const
692 {
693
694 return is_every([](auto coordinate) {return coordinate == COORDINATE{}; });
695
696 }
697
698
699 bool is_set() const
700 {
701
702 return !is_empty();
703
704 }
705
706
707 bool is_all_set() const
708 {
709
710 return is_every([](auto coordinate) {return coordinate != COORDINATE{}; });
711
712 }
713
714
715 bool is_all_positive() const
716 {
717
718 return is_every([](auto coordinate) {return coordinate > COORDINATE{}; });
719
720 }
721
722
723 template < typename PREDICATE >
724 sequence_type prefer_self_coordinate_if(const sequence_type &vectorOther, PREDICATE predicate) const
725 {
726
727 sequence_type vector;
728
729 for (::collection::count i = 0; i < SIZE; ++i)
730 {
731
732 if (predicate(this->m_coordinatea[i]))
733 {
734
735 vector[i] = this->m_coordinatea[i];
736
737 }
738 else
739 {
740
741 vector[i] = vectorOther.m_coordinatea[i];
742
743 }
744
745 }
746
747 return vector;
748
749 }
750
751
752 sequence_type prefer_self_coordinate_if_set(const sequence_type& vectorOther) const
753 {
754
755 return prefer_self_coordinate_if(vectorOther, [](auto coordinate) {return coordinate != 0; });
756
757 }
758
759
760 sequence_type prefer_self_coordinate_if_positive(const sequence_type& vectorOther) const
761 {
762
763 return prefer_self_coordinate_if(vectorOther, [](auto coordinate) {return coordinate > COORDINATE{}; });
764
765 }
766
767
768 template < typename PREDICATE, typename SOURCE_PREDICATE >
769 sequence_type pred_prefer_self_coordinate_if(PREDICATE predicate, SOURCE_PREDICATE sourcepredicate) const
770 {
771
772 if (is_every(predicate))
773 {
774
775 return *this;
776
777 }
778
779 auto vectorOther = sourcepredicate();
780
781 return prefer_self_coordinate_if(vectorOther, predicate);
782
783 }
784
785
786 template < typename SOURCE_PREDICATE >
787 sequence_type pred_prefer_self_coordinate_if_set(SOURCE_PREDICATE sourcepredicate) const
788 {
789
790 return pred_prefer_self_coordinate_if([](auto coordinate) {return coordinate != COORDINATE{}; }, sourcepredicate);
791
792 }
793
794
795 template < typename SOURCE_PREDICATE >
796 sequence_type pred_prefer_self_coordinate_if_positive(SOURCE_PREDICATE sourcepredicate) const
797 {
798
799 return pred_prefer_self_coordinate_if([](auto coordinate) {return coordinate > COORDINATE{}; }, sourcepredicate);
800
801 }
802
803
804
805 constexpr bool operator!=(const sequence_type& a) const { return !operator==(a); }
806
807 constexpr const COORDINATE& operator[](::collection::count i) const { return this->m_coordinatea[i]; }
808
809 constexpr COORDINATE& operator[](::collection::count i) { return this->m_coordinatea[i]; }
810
811 //template <::collection::count S = SIZE, std::enable_if_t<(S >= 1), ::i32> = 0>
812 //constexpr const COORDINATE& a const { return this->m_coordinatea[0]; }
813 //template <::collection::count S = SIZE, std::enable_if_t<(S >= 1), ::i32> = 0>
814 //COORDINATE& a { return this->m_coordinatea[0]; }
815
816 //template <::collection::count S = SIZE, std::enable_if_t<(S >= 2), ::i32> = 0>
817 //constexpr const COORDINATE& b const { return this->m_coordinatea[1]; }
818 //template <::collection::count S = SIZE, std::enable_if_t<(S >= 2), ::i32> = 0>
819 //COORDINATE& b { return this->m_coordinatea[1]; }
820
821 //template <::collection::count S = SIZE, std::enable_if_t<(S >= 3), ::i32> = 0>
822 //constexpr const COORDINATE& c const { return this->m_coordinatea[2]; }
823 //template <::collection::count S = SIZE, std::enable_if_t<(S >= 3), ::i32> = 0>
824 //COORDINATE& c { return this->m_coordinatea[2]; }
825
826 //template <::collection::count S = SIZE, std::enable_if_t<(S >= 4), ::i32> = 0>
827 //constexpr const COORDINATE& d const { return this->m_coordinatea[3]; }
828 //template <::collection::count S = SIZE, std::enable_if_t<(S >= 4), ::i32> = 0>
829 //COORDINATE& d { return this->m_coordinatea[3]; }
830
831
832 template <::collection::count S = SIZE, std::enable_if_t<(S == 2), ::i32> = 0>
833 COORDINATE dot_with_left_perpendicular_of(const sequence_type & b)
834 {
835
836 return (this->y * b.x) - (this->x * b.y);
837
838 }
839
840
841 template <::collection::count S = SIZE, std::enable_if_t<(S == 2), ::i32> = 0>
842 COORDINATE angle(const sequence_type & b)
843 {
844
845 return ::std::atan2(this->dot_with_left_perpendicular_of(b), this->dotted(b));
846
847 }
848
849
850 sequence_type maximum(const sequence_type & vector) const
851 {
852
853 sequence_type result;
854
855 for (::collection::count i = 0; i < SIZE; ++i)
856 {
857
858 result.m_coordinatea[i] = ::maximum(this->m_coordinatea[i], vector.m_coordinatea[i]);
859
860 }
861
862 return result;
863
864 }
865
866 sequence_type minimum(const sequence_type& vector) const
867 {
868
869 sequence_type result;
870
871 for (::collection::count i = 0; i < SIZE; ++i)
872 {
873
874 result.m_coordinatea[i] = ::minimum(this->m_coordinatea[i], vector.m_coordinatea[i]);
875
876 }
877
878 return result;
879
880 }
881
882 sequence_type & operator =(const sequence_type & sequence)
883 {
884
885 if (this != &sequence)
886 {
887
888 for (::collection::count i = 0; i < SIZE; ++i)
889 {
890
891 this->m_coordinatea[i] = sequence.m_coordinatea[i];
892
893 }
894
895 }
896
897 return *this;
898 }
899
900
901 UNIT_TYPE minimum() const
902 {
903
904 UNIT_TYPE nMinimum = this->m_coordinatea[0];
905
906 for (::collection::count i = 1; i < SIZE; ++i)
907 {
908
909 nMinimum = ::minimum(nMinimum, this->m_coordinatea[i]);
910
911 }
912
913 return nMinimum;
914
915 }
916
917
918 UNIT_TYPE maximum() const
919 {
920
921 UNIT_TYPE nMaximum = this->m_coordinatea[0];
922
923 for (::collection::count i = 1; i < SIZE; ++i)
924 {
925
926 nMaximum = ::maximum(nMaximum, this->m_coordinatea[i]);
927
928 }
929
930 return nMaximum;
931
932 }
933
934
935
936
937 COORDINATE dotted(const sequence_type & vector) const
938 {
939
940 COORDINATE result = this->m_coordinatea[0] * vector.m_coordinatea[0];
941
942 for (::collection::count i = 1; i < SIZE; ++i)
943 {
944
945 result += this->m_coordinatea[i] * vector.m_coordinatea[i];
946
947 }
948
949 return result;
950
951 }
952
953
954
955 sequence_type make_unitary() const
956 {
957
958 return *this / modulus();
959
960 }
961
962
963 const UNIT_TYPE & get_dimension(enum_orientation eorientation) const
964 {
965
966 return this->m_coordinatea[eorientation];
967
968 }
969
970 UNIT_TYPE & get_dimension(enum_orientation eorientation)
971 {
972
973 return this->m_coordinatea[eorientation];
974
975 }
976
977
978 template < ::collection::count S = SIZE, std::enable_if_t<S == 2, ::i32> = 0 >
979 const UNIT_TYPE & get_normal_dimension(enum_orientation eorientation) const
980 {
981
982 return this->m_coordinatea[orthogonal2_index_of(eorientation)];
983
984 }
985
986
987 template < ::collection::count S = SIZE, std::enable_if_t<S == 2, ::i32> = 0 >
988 UNIT_TYPE & get_normal_dimension(enum_orientation eorientation)
989 {
990
991 return this->m_coordinatea[orthogonal2_index_of(eorientation)];
992
993 }
994
995
996 inline UNIT_TYPE & set_dimension(enum_orientation eorientation, UNIT_TYPE l) noexcept
997 {
998
999 return this->m_coordinatea[eorientation] = l;
1000
1001 }
1002
1003
1004 inline UNIT_TYPE & set_orthogonal_dimension(enum_orientation eorientation, UNIT_TYPE l) noexcept
1005 {
1006
1007 return this->m_coordinatea[orthogonal2_index_of(eorientation)] = l;
1008
1009 }
1010
1012 requires(SIZE == 3)
1013 {
1014 const auto &a = *this;
1015 return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
1016 }
1017
1018 inline NUMBER squared_modulus() const
1019 requires(SIZE == 2)
1020 {
1021 return
1022 this->x * this->x +
1023 this->y * this->y;
1024 }
1025
1026 inline NUMBER squared_modulus() const
1027 requires(SIZE == 3)
1028 {
1029 return
1030 this->x * this->x +
1031 this->y * this->y +
1032 this->z * this->z;
1033 }
1034
1035 inline NUMBER squared_modulus() const
1036 requires(SIZE == 4)
1037 {
1038 return
1039 this->x * this->x +
1040 this->y * this->y +
1041 this->z * this->z +
1042 this->w * this->w;
1043 }
1044
1045 inline NUMBER modulus() const
1046 {
1047 return ::std::sqrt(squared_modulus());
1048 }
1049
1050
1051 inline NUMBER length() const
1052 {
1053
1054 return modulus();
1055
1056 }
1057
1058
1059 inline NUMBER distance(const sequence_type & b) const
1060 {
1061
1062 return (b - *this).modulus();
1063
1064 }
1065
1066
1067 sequence_type &normalize()
1068 {
1069
1070 auto modulus = this->modulus();
1071
1072 if (modulus > 0.0f)
1073 {
1074
1075 return *this /= modulus;
1076
1077 }
1078 else
1079 {
1080
1081 return null();
1082
1083 }
1084
1085 }
1086
1087
1088 sequence_type normalized() const
1089 {
1090
1091 sequence_type sequence = *this;
1092
1093 return sequence.normalize();
1094
1095 }
1096
1097
1098 template<prototype_floating FLOATING>
1099 inline sequence_type mix(const sequence_type &b, FLOATING t) const
1100 {
1101
1102 return *this * ((FLOATING)1 - t) + b * t;
1103
1104 }
1105
1106
1107 constexpr sequence_type front_right(const sequence_type & sequence3WorldUp)
1108 requires(SIZE == 3 && prototype_floating<UNIT_TYPE>)
1109 {
1110
1111 return this->crossed(sequence3WorldUp).normalized();
1112
1113 }
1114
1115
1116 constexpr sequence_type right_up(const sequence_type &front)
1117 requires(SIZE == 3 && prototype_floating<UNIT_TYPE>)
1118 {
1119
1120 return this->crossed(front).normalized();
1121
1122 }
1123
1124
1125 sequence_type cos() const
1126 {
1127 sequence_type result;
1128 for (::collection::count i = 0; i < SIZE; ++i)
1129 result[i] = ::std::cos(this->m_coordinatea[i]);
1130 return result;
1131 }
1132
1133
1134 sequence_type sin() const
1135 {
1136 sequence_type result;
1137 for (::collection::count i = 0; i < SIZE; ++i)
1138 result[i] = ::std::sin(this->m_coordinatea[i]);
1139 return result;
1140 }
1141
1142
1143 auto as_translation_matrix() const
1144 requires(t_iSize == 3 && prototype_floating<UNIT_TYPE>);
1145
1146 auto as_scaling_matrix() const
1147 requires(t_iSize == 3 && prototype_floating<UNIT_TYPE>);
1148
1149
1150};
1151
1152
1153
1154
1155
1156//template <typename COORDINATE, ::collection::count SIZE>
1157//sequence_type<COORDINATE, SIZE> min(const sequence_type<COORDINATE, SIZE>& a1, const sequence_type<COORDINATE, SIZE>& a2) {
1158// sequence_type<COORDINATE, SIZE> result;
1159// for (::collection::count i = 0; i < SIZE; ++i)
1160// result.m_coordinatea[i] = std::min(a1.m_coordinatea[i], a2.m_coordinatea[i]);
1161// return result;
1162//}
1163//
1164//template < prototype_number NUMBER >
1165//class sequence2_type :
1166// public sequence_type < NUMBER, 2 >
1167//{
1168//public:
1169//
1170//
1171// using sequence_type < NUMBER, 2 >::sequence_type;
1172//
1173//
1174// NUMBER dot_with_left_perpendicular_of(const sequence2_type & b)
1175// {
1176//
1177// return (this->y * b.x) - (this->x * b.y);
1178//
1179// }
1180//
1181//
1182// NUMBER angle(const sequence2_type & b)
1183// {
1184//
1185// return atan2f(this->dot_with_left_perpendicular_of(b), this->dot(b));
1186//
1187// }
1188//
1189//
1190//
1191//};
1192
1193// Import some common Enoki types
1194using i32_sequence2 = sequence_type<::i32, 2>;
1195using i32_sequence3 = sequence_type<::i32, 3>;
1196using i32_sequence4 = sequence_type<::i32, 4>;
1197
1198using i64_sequence2 = sequence_type<::i64, 2>;
1199using i64_sequence3 = sequence_type<::i64, 3>;
1200using i64_sequence4 = sequence_type<::i64, 4>;
1201
1202using f32_sequence2 = sequence_type<::f32, 2>;
1203using f32_sequence3 = sequence_type<::f32, 3>;
1204using f32_sequence4 = sequence_type<::f32, 4>;
1205
1206using f64_sequence2 = sequence_type<::f64, 2>;
1207using f64_sequence3 = sequence_type<::f64, 3>;
1208using f64_sequence4 = sequence_type<::f64, 4>;
1209
1210
1211
1212
1214//inline Color::operator const ::color::color & () const {
1215// return reinterpret_cast<const ::color::color &>(*(this->m_coordinatea));
1216//}
1217
1218template < prototype_sequence SEQUENCE, typename COORDINATE_TRANSFORM >
1219auto transform(const SEQUENCE& sequence, COORDINATE_TRANSFORM coordinatetransform)
1220{
1221
1222 SEQUENCE sequenceResult(no_initialize_t{});
1223
1224 for (::collection::count i = 0; i < sequence.get_size(); ++i)
1225 {
1226
1227 sequenceResult.set_coordinate(i, coordinatetransform(sequence.coordinate(i)));
1228
1229 }
1230
1231 return sequenceResult;
1232
1233}
1234
1235
1236template < prototype_sequence SEQUENCE >
1237auto floor(const SEQUENCE& sequence)
1238{
1239
1240 return transform(sequence, [](auto a) {return floor(a); });
1241
1242}
1243
1244
1245template < prototype_sequence SEQUENCE >
1246auto ceil(const SEQUENCE& sequence)
1247{
1248
1249 return transform(sequence, [](auto a) {return ceil(a); });
1250
1251}
1252
1253
1254
1255//
1256//template<prototype_number COORDINATE, ::collection::count t_iDimension>
1257//struct matrix_type
1258//{
1259//
1260// using matrix_tag = matrix_t;
1261// using BASE_COORDINATE = COORDINATE;
1262// using UNIT_TYPE = COORDINATE;
1263//
1264//
1265// COORDINATE this->m_coordinatea[t_iDimension * t_iDimension];
1266//
1267//
1268//};
1269//
1270
1271
1272
1273template<prototype_number NUMBER, ::i32 t_iSize>
1274struct std::hash<::sequence_type<NUMBER, t_iSize>>
1275{
1276 std::size_t operator()(const ::sequence_type<NUMBER, t_iSize> &s) const noexcept
1277 {
1278 return std::hash<::sequence_t_type<NUMBER, t_iSize>>{}(
1279 (const ::sequence_t_type<NUMBER, t_iSize> & )(s));
1280 }
1281};
1282
1283//
1284//namespace geometry
1285//{
1286//
1287//
1288// template<prototype_number NUMBER>
1289// sequence_type<NUMBER, 3> normalize(const sequence_type<NUMBER, 3> &v)
1290// {
1291//
1292// ::f32 length = std::sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
1293//
1294// if (length > 0.0f)
1295// {
1296//
1297// return v / length;
1298//
1299// }
1300// else
1301// {
1302//
1303// return sequence_type<NUMBER, 3>(0.0f); // or return v (undefined direction)
1304//
1305// }
1306//
1307//
1308// }
1309//
1310//
1311//} // namespace geometry
1312//
1313
1314
1315template < prototype_number NUMBER, prototype_number NUMBER1, ::i32 t_iSize >
1317operator *(NUMBER n, const sequence_type< NUMBER1, t_iSize> & s)
1318{
1320 for (::collection::count i = 0; i < t_iSize; ++i)
1321 result[i] = (largest_number<NUMBER, NUMBER1>)(n * s.m_coordinatea[i]);
1322 return result;
1323}
1324
1325
1326
1327
1328
Definition _initial_concepts.h:106
Definition _initial_concepts.h:28
Matrix class.
Definition matrix.h:73
Definition _tags.h:5
Definition _structures.h:16
Definition sequence.h:23
Definition _structures.h:11
Definition sequence.h:236