PLaSK library
Loading...
Searching...
No Matches
primitives.hpp
Go to the documentation of this file.
1
/*
2
* This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3
* Copyright (c) 2022 Lodz University of Technology
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, version 3.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*/
14
#ifndef PLASK__PRIMITIVES_H
15
#define PLASK__PRIMITIVES_H
16
21
#include "../exceptions.hpp"
22
#include "../vec.hpp"
23
24
namespace
plask
{
25
26
constexpr
double
POINT_TOLLERANCE
= 1
e
-12;
27
28
extern
PLASK_API
const
char
*
const
DIRECTION_NAMES
[];
29
36
struct
PLASK_API
Box2D
{
38
Vec<2, double>
lower
;
39
41
Vec<2, double>
upper
;
42
47
constexpr
Vec<2, double>
size
()
const
{
return
upper - lower; }
48
53
constexpr
double
height
()
const
{
return
upper.vert() - lower.vert(); }
54
59
constexpr
double
width
()
const
{
return
upper.tran() - lower.tran(); }
60
65
constexpr
Vec<2, double>
center
()
const
{
return
0.5 * (upper + lower); }
66
68
Box2D
() {}
69
75
constexpr
Box2D
(
const
Vec<2, double>
& lower,
const
Vec<2, double>
& upper) : lower(lower), upper(upper) {}
76
82
constexpr
Box2D
(
double
x_lo
,
double
y_lo
,
double
x_up
,
double
y_up
) : lower(
x_lo
,
y_lo
), upper(
x_up
,
y_up
) {}
83
84
static
Box2D
invalidInstance
() {
85
Box2D
r;
86
r.
makeInvalid
();
87
return
r;
88
}
89
95
bool
operator==
(
const
Box2D
& r)
const
;
96
102
bool
operator!=
(
const
Box2D
& r)
const
;
103
108
void
fix();
109
115
bool
contains(
const
Vec<2, double>
& p)
const
;
116
122
bool
intersects(
const
Box2D
& other)
const
;
123
128
void
makeInclude(
const
Vec<2, double>
& p);
129
134
void
makeInclude(
const
Box2D
& other);
135
140
void
makeIntersection(
const
Box2D
& other);
141
147
Box2D
intersection(
Box2D
other)
const
;
148
154
Box2D
extension(
Box2D
other)
const
;
155
161
Box2D
translated
(
const
Vec<2, double>
&
translation_vec
)
const
{
162
return
Box2D
(lower +
translation_vec
, upper +
translation_vec
);
163
}
164
170
Box2D
operator+
(
const
Vec<2, double>
&
translation_vec
)
const
{
171
return
Box2D
(lower +
translation_vec
, upper +
translation_vec
);
172
}
173
179
Box2D
operator-
(
const
Vec<2, double>
&
translation_vec
)
const
{
180
return
Box2D
(lower -
translation_vec
, upper -
translation_vec
);
181
}
182
188
Box2D
translatedUp
(
const
double
trasnalation_in_up_dir
)
const
{
189
return
translated(
vec
(0.0,
trasnalation_in_up_dir
));
190
}
191
196
void
translate
(
const
Vec<2, double>
&
translation_vec
) {
197
lower +=
translation_vec
;
198
upper +=
translation_vec
;
199
}
200
205
Box2D
&
operator+=
(
const
Vec<2, double>
&
translation_vec
) {
206
lower +=
translation_vec
;
207
upper -=
translation_vec
;
208
return
*
this
;
209
}
210
215
Box2D
&
operator-=
(
const
Vec<2, double>
&
translation_vec
) {
216
lower -=
translation_vec
;
217
upper -=
translation_vec
;
218
return
*
this
;
219
}
220
225
void
translateUp
(
const
double
trasnalation_in_up_dir
) {
226
lower.vert() +=
trasnalation_in_up_dir
;
227
upper.vert() +=
trasnalation_in_up_dir
;
228
}
229
235
void
translateDir
(
unsigned
dir_index
,
const
double
trasnalation_in_dir
) {
236
lower[
dir_index
] +=
trasnalation_in_dir
;
237
upper[
dir_index
] +=
trasnalation_in_dir
;
238
}
239
246
Vec<2, double>
moveInside(
Vec<2, double>
p)
const
;
247
254
friend
inline
std::ostream&
operator<<
(std::ostream& out,
const
Box2D
&
to_print
) {
255
return
out <<
'['
<<
to_print
.lower <<
", "
<<
to_print
.upper <<
']'
;
256
}
257
264
bool
isValid
()
const
{
return
upper.c0 >= lower.c0 && upper.c1 >= lower.c1; }
265
270
void
makeInvalid
() {
271
lower =
vec
(0.0, 0.0);
272
upper =
vec
(-1.0, -1.0);
273
}
274
279
double
getArea
()
const
{
280
Vec<2, double>
v
= size();
281
return
v
.c0 *
v
.c1;
282
}
283
289
inline
void
flip
(
size_t
flipDir) {
290
assert
(flipDir < 2);
291
double
temp
= lower[flipDir];
292
lower[flipDir] = -upper[flipDir];
293
upper[flipDir] = -
temp
;
294
}
295
302
inline
Box2D
flipped
(
size_t
i)
const
{
303
Box2D
res
= *
this
;
304
res
.
flip
(i);
305
return
res
;
306
}
307
312
const
double
&
left
()
const
{
return
lower.c0; }
313
318
double
&
left
() {
return
lower.c0; }
319
324
const
double
&
right
()
const
{
return
upper.c0; }
325
330
double
&
right
() {
return
upper.c0; }
331
336
const
double
&
bottom
()
const
{
return
lower.c1; }
337
342
double
&
bottom
() {
return
lower.c1; }
343
348
const
double
&
top
()
const
{
return
upper.c1; }
349
354
double
&
top
() {
return
upper.c1; }
355
356
void
setLeft
(
double
v
) { lower.c0 =
v
; }
357
void
setRight
(
double
v
) { upper.c0 =
v
; }
358
void
setBottom
(
double
v
) { lower.c1 =
v
; }
359
void
setTop
(
double
v
) { upper.c1 =
v
; }
360
361
double
getLeft
()
const
{
return
lower.c0; }
362
double
getRight
()
const
{
return
upper.c0; }
363
double
getBottom
()
const
{
return
lower.c1; }
364
double
getTop
()
const
{
return
upper.c1; }
365
};
366
373
struct
PLASK_API
Box3D
{
375
Vec<3, double>
lower
;
376
378
Vec<3, double>
upper
;
379
384
constexpr
Vec<3, double>
size
()
const
{
return
upper - lower; }
385
390
constexpr
double
height
()
const
{
return
upper.vert() - lower.vert(); }
391
396
constexpr
double
width
()
const
{
return
upper.tran() - lower.tran(); }
397
402
constexpr
double
depth
()
const
{
return
upper.lon() - lower.lon(); }
403
408
constexpr
Vec<3, double>
center
()
const
{
return
0.5 * (upper + lower); }
409
411
Box3D
() {}
412
418
constexpr
Box3D
(
const
Vec<3, double>
& lower,
const
Vec<3, double>
& upper) : lower(lower), upper(upper) {}
419
425
constexpr
Box3D
(
double
x_lo
,
double
y_lo
,
double
z_lo
,
double
x_up
,
double
y_up
,
double
z_up
)
426
: lower(
x_lo
,
y_lo
,
z_lo
), upper(
x_up
,
y_up
,
z_up
) {}
427
428
static
Box3D
invalidInstance
() {
429
Box3D
r;
430
r.
makeInvalid
();
431
return
r;
432
}
433
439
bool
operator==
(
const
Box3D
& r)
const
;
440
446
bool
operator!=
(
const
Box3D
& r)
const
;
447
452
void
fix();
453
459
bool
contains(
const
Vec<3, double>
& p)
const
;
460
466
bool
intersects(
const
Box3D
& other)
const
;
467
472
void
makeInclude(
const
Vec<3, double>
& p);
473
478
void
makeInclude(
const
Box3D
& other);
479
484
void
makeIntersection(
const
Box3D
& other);
485
491
Box3D
extension(
Box3D
other)
const
;
492
498
Box3D
intersection(
Box3D
other)
const
;
499
505
Box3D
translated
(
const
Vec<3, double>
&
translation_vec
)
const
{
506
return
Box3D
(lower +
translation_vec
, upper +
translation_vec
);
507
}
508
514
Box3D
operator+
(
const
Vec<3, double>
&
translation_vec
)
const
{
515
return
Box3D
(lower +
translation_vec
, upper +
translation_vec
);
516
}
517
523
Box3D
operator-
(
const
Vec<3, double>
&
translation_vec
)
const
{
524
return
Box3D
(lower -
translation_vec
, upper -
translation_vec
);
525
}
526
532
Box3D
translatedUp
(
const
double
trasnalation_in_up_dir
)
const
{
533
Box3D
r = *
this
;
534
r.
translateUp
(
trasnalation_in_up_dir
);
535
return
r;
536
}
537
542
void
translate
(
const
Vec<3, double>
&
translation_vec
) {
543
lower +=
translation_vec
;
544
upper +=
translation_vec
;
545
}
546
551
Box3D
&
operator+=
(
const
Vec<3, double>
&
translation_vec
) {
552
lower +=
translation_vec
;
553
upper -=
translation_vec
;
554
return
*
this
;
555
}
556
561
Box3D
&
operator-=
(
const
Vec<3, double>
&
translation_vec
) {
562
lower -=
translation_vec
;
563
upper -=
translation_vec
;
564
return
*
this
;
565
}
566
571
void
translateUp
(
const
double
trasnalation_in_up_dir
) {
572
lower.vert() +=
trasnalation_in_up_dir
;
573
upper.vert() +=
trasnalation_in_up_dir
;
574
}
575
581
void
translateDir
(
unsigned
dir_index
,
const
double
trasnalation_in_dir
) {
582
lower[
dir_index
] +=
trasnalation_in_dir
;
583
upper[
dir_index
] +=
trasnalation_in_dir
;
584
}
585
590
void
makeInclude
(
const
Box2D
& other);
591
598
Vec<3, double>
moveInside(
Vec<3, double>
p)
const
;
599
606
friend
inline
std::ostream&
operator<<
(std::ostream& out,
const
Box3D
&
to_print
) {
607
return
out <<
'['
<<
to_print
.lower <<
", "
<<
to_print
.upper <<
']'
;
608
}
609
616
bool
isValid
()
const
{
return
upper.c0 >= lower.c0 && upper.c1 >= lower.c1 && upper.c2 >= lower.c2; }
617
622
void
makeInvalid
() {
623
lower =
vec
(0.0, 0.0, 0.0);
624
upper =
vec
(-1.0, -1.0, -1.0);
625
}
626
631
double
getArea
()
const
{
632
Vec<3, double>
v
= size();
633
return
v
.c0 *
v
.c1 *
v
.c2;
634
}
635
641
inline
void
flip
(
size_t
flipDir) {
642
assert
(flipDir < 3);
643
double
temp
= lower[flipDir];
644
lower[flipDir] = -upper[flipDir];
645
upper[flipDir] = -
temp
;
646
}
647
654
inline
Box3D
flipped
(
size_t
i)
const
{
655
Box3D
res
= *
this
;
656
res
.
flip
(i);
657
return
res
;
658
}
659
664
const
double
&
back
()
const
{
return
lower.c0; }
665
670
double
&
back
() {
return
lower.c0; }
671
676
const
double
&
front
()
const
{
return
upper.c0; }
677
682
double
&
front
() {
return
upper.c0; }
683
688
const
double
&
left
()
const
{
return
lower.c1; }
689
694
double
&
left
() {
return
lower.c1; }
695
700
const
double
&
right
()
const
{
return
upper.c1; }
701
706
double
&
right
() {
return
upper.c1; }
707
712
const
double
&
bottom
()
const
{
return
lower.c2; }
713
718
double
&
bottom
() {
return
lower.c2; }
719
724
const
double
&
top
()
const
{
return
upper.c2; }
725
730
double
&
top
() {
return
upper.c2; }
731
732
void
setBack
(
double
v
) { lower.c0 =
v
; }
733
void
setFront
(
double
v
) { upper.c0 =
v
; }
734
void
setLeft
(
double
v
) { lower.c1 =
v
; }
735
void
setRight
(
double
v
) { upper.c1 =
v
; }
736
void
setBottom
(
double
v
) { lower.c2 =
v
; }
737
void
setTop
(
double
v
) { upper.c2 =
v
; }
738
739
double
getBack
()
const
{
return
lower.c0; }
740
double
getFront
()
const
{
return
upper.c0; }
741
double
getLeft
()
const
{
return
lower.c1; }
742
double
getRight
()
const
{
return
upper.c1; }
743
double
getBottom
()
const
{
return
lower.c2; }
744
double
getTop
()
const
{
return
upper.c2; }
745
};
746
751
template
<
int
dim>
struct
Primitive
{};
752
756
template
<>
struct
PLASK_API
Primitive
<1> {
758
typedef
double
DVec
;
759
761
static
const
int
dim = 1;
762
764
static
const
DVec
ZERO_VEC
;
765
766
enum
Direction
{ DIRECTION = 0 };
767
769
inline
static
bool
vecFuzzyCompare
(
DVec
a
,
DVec
b
) {
return
b
-
a
>
POINT_TOLLERANCE
; }
770
};
771
775
template
<>
struct
PLASK_API
Primitive
<2> {
777
typedef
Box2D
Box
;
778
780
typedef
Vec<2, double>
DVec
;
781
783
static
const
int
dim = 2;
784
786
static
const
DVec
ZERO_VEC
;
787
789
static
const
DVec
NAN_VEC
;
790
792
static
const
Box
INF_BOX
;
793
794
enum
Direction
{ DIRECTION_TRAN = 0, DIRECTION_VERT = 1 };
795
796
static
void
ensureIsValidDirection
(
unsigned
direction) {
797
if
(direction > 1)
throw
Exception
(
"bad 2D direction index, {0} was given but allowed are: 0, 1."
, direction);
798
}
799
801
inline
static
bool
vecFuzzyCompare
(
const
DVec
&
a
,
const
DVec
&
b
) {
802
return
b
.c1 -
a
.c1 >
POINT_TOLLERANCE
|| (
a
.c1 -
b
.c1 <=
POINT_TOLLERANCE
&&
b
.c0 -
a
.c0 >
POINT_TOLLERANCE
);
803
}
804
};
805
809
template
<>
struct
PLASK_API
Primitive
<3> {
811
typedef
Box3D
Box
;
812
814
typedef
Vec<3, double>
DVec
;
815
817
static
const
int
dim = 3;
818
820
static
const
DVec
ZERO_VEC
;
821
823
static
const
DVec
NAN_VEC
;
824
826
static
const
Box
INF_BOX
;
827
828
enum
Direction
{ DIRECTION_LONG = 0, DIRECTION_TRAN = 1, DIRECTION_VERT = 2 };
829
830
static
void
ensureIsValidDirection
(
unsigned
direction) {
831
if
(direction > 2)
832
throw
DimensionError
(
"bad 3D direction index, {} was given but allowed are: 0, 1, 2."
, direction);
833
}
834
835
static
void
ensureIsValid2DDirection
(
unsigned
direction) {
836
if
(direction != DIRECTION_TRAN && direction != DIRECTION_VERT)
837
throw
DimensionError
(
838
"bad 2D direction index, {} was given but allowed are: 1 (DIRECTION_TRAN), 2 (DIRECTION_VERT)."
,
839
direction);
840
}
841
843
inline
static
bool
vecFuzzyCompare
(
const
DVec
&
a
,
const
DVec
&
b
) {
844
return
b
.c2 -
a
.c2 >
POINT_TOLLERANCE
|| (
a
.c2 -
b
.c2 <=
POINT_TOLLERANCE
&&
845
(
b
.c1 -
a
.c1 >
POINT_TOLLERANCE
|| (
a
.c1 -
b
.c1 <=
POINT_TOLLERANCE
&&
846
b
.c0 -
a
.c0 >
POINT_TOLLERANCE
)));
847
}
848
};
849
850
constexpr
inline
Primitive<3>::Direction
direction3D
(
Primitive<2>::Direction
dir2D
) {
851
return
Primitive<3>::Direction
(
dir2D
+ 1);
852
}
853
854
constexpr
inline
Primitive<3>::Direction
direction3D
(
Primitive<3>::Direction
dir3D
) {
return
dir3D
; }
855
856
template <int dim, typename Primitive<dim>::Direction
dirToSkip
>
struct
DirectionWithout
{};
857
858
template
<>
struct
DirectionWithout
<2,
Primitive
<2>::DIRECTION_TRAN> {
859
static
const
Primitive<2>::Direction
value =
Primitive<2>::DIRECTION_VERT
;
860
static
const
Primitive<3>::Direction
value3d =
Primitive<3>::DIRECTION_VERT
;
861
};
862
863
template
<>
struct
DirectionWithout
<2,
Primitive
<2>::DIRECTION_VERT> {
864
static
const
Primitive<2>::Direction
value =
Primitive<2>::DIRECTION_TRAN
;
865
static
const
Primitive<3>::Direction
value3d =
Primitive<3>::DIRECTION_TRAN
;
866
};
867
868
template
<>
struct
DirectionWithout
<3,
Primitive
<3>::DIRECTION_LONG> {
869
static
const
unsigned
value =
Primitive<3>::DIRECTION_TRAN
|
Primitive<3>::DIRECTION_VERT
;
870
static
const
Primitive<3>::Direction
valueLower =
Primitive<3>::DIRECTION_TRAN
;
871
static
const
Primitive<3>::Direction
valueHigher =
Primitive<3>::DIRECTION_VERT
;
872
873
// should be not usedm but sometimes it is useful to make compilation possible
874
static
const
Primitive<2>::Direction
value2D =
875
Primitive<2>::Direction
(
Primitive<2>::DIRECTION_VERT
|
Primitive<2>::DIRECTION_VERT
);
876
};
877
878
template
<>
struct
DirectionWithout
<3,
Primitive
<3>::DIRECTION_TRAN> {
879
static
const
unsigned
value =
Primitive<3>::DIRECTION_LONG
|
Primitive<3>::DIRECTION_VERT
;
880
static
const
Primitive<3>::Direction
valueLower =
Primitive<3>::DIRECTION_LONG
;
881
static
const
Primitive<3>::Direction
valueHigher =
Primitive<3>::DIRECTION_VERT
;
882
883
static
const
Primitive<2>::Direction
value2D =
Primitive<2>::DIRECTION_VERT
;
884
};
885
886
template
<>
struct
DirectionWithout
<3,
Primitive
<3>::DIRECTION_VERT> {
887
static
const
unsigned
value =
Primitive<3>::DIRECTION_LONG
|
Primitive<3>::DIRECTION_TRAN
;
888
static
const
Primitive<3>::Direction
valueLower =
Primitive<3>::DIRECTION_LONG
;
889
static
const
Primitive<3>::Direction
valueHigher =
Primitive<3>::DIRECTION_TRAN
;
890
891
static
const
Primitive<2>::Direction
value2D =
Primitive<2>::DIRECTION_TRAN
;
892
};
893
894
}
// namespace plask
895
896
#if FMT_VERSION >= 90000
897
template
<>
struct
fmt::formatter<
plask
::Box2D> : ostream_formatter {};
898
template
<>
struct
fmt::formatter<
plask
::Box3D> : ostream_formatter {};
899
#endif
900
901
#endif
plask
geometry
primitives.hpp
Generated by
1.9.8