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
34
struct
PLASK_API
Box2D
{
36
Vec<2, double>
lower
;
37
39
Vec<2, double>
upper
;
40
45
constexpr
Vec<2, double>
size
()
const
{
return
upper - lower; }
46
51
constexpr
double
height
()
const
{
return
upper.vert() - lower.vert(); }
52
57
constexpr
double
width
()
const
{
return
upper.tran() - lower.tran(); }
58
63
constexpr
Vec<2, double>
center
()
const
{
return
0.5 * (upper + lower); }
64
66
Box2D
() {}
67
73
constexpr
Box2D
(
const
Vec<2, double>
& lower,
const
Vec<2, double>
& upper) : lower(lower), upper(upper) {}
74
80
constexpr
Box2D
(
double
x_lo
,
double
y_lo
,
double
x_up
,
double
y_up
) : lower(
x_lo
,
y_lo
), upper(
x_up
,
y_up
) {}
81
82
static
Box2D
invalidInstance
() {
83
Box2D
r;
84
r.
makeInvalid
();
85
return
r;
86
}
87
93
bool
operator==
(
const
Box2D
& r)
const
;
94
100
bool
operator!=
(
const
Box2D
& r)
const
;
101
106
void
fix();
107
113
bool
contains(
const
Vec<2, double>
& p)
const
;
114
120
bool
intersects(
const
Box2D
& other)
const
;
121
126
void
makeInclude(
const
Vec<2, double>
& p);
127
132
void
makeInclude(
const
Box2D
& other);
133
138
void
makeIntersection(
const
Box2D
& other);
139
145
Box2D
intersection(
Box2D
other)
const
;
146
152
Box2D
extension(
Box2D
other)
const
;
153
159
Box2D
translated
(
const
Vec<2, double>
&
translation_vec
)
const
{
160
return
Box2D
(lower +
translation_vec
, upper +
translation_vec
);
161
}
162
168
Box2D
operator+
(
const
Vec<2, double>
&
translation_vec
)
const
{
169
return
Box2D
(lower +
translation_vec
, upper +
translation_vec
);
170
}
171
177
Box2D
operator-
(
const
Vec<2, double>
&
translation_vec
)
const
{
178
return
Box2D
(lower -
translation_vec
, upper -
translation_vec
);
179
}
180
186
Box2D
translatedUp
(
const
double
trasnalation_in_up_dir
)
const
{
187
return
translated(
vec
(0.0,
trasnalation_in_up_dir
));
188
}
189
194
void
translate
(
const
Vec<2, double>
&
translation_vec
) {
195
lower +=
translation_vec
;
196
upper +=
translation_vec
;
197
}
198
203
Box2D
&
operator+=
(
const
Vec<2, double>
&
translation_vec
) {
204
lower +=
translation_vec
;
205
upper -=
translation_vec
;
206
return
*
this
;
207
}
208
213
Box2D
&
operator-=
(
const
Vec<2, double>
&
translation_vec
) {
214
lower -=
translation_vec
;
215
upper -=
translation_vec
;
216
return
*
this
;
217
}
218
223
void
translateUp
(
const
double
trasnalation_in_up_dir
) {
224
lower.vert() +=
trasnalation_in_up_dir
;
225
upper.vert() +=
trasnalation_in_up_dir
;
226
}
227
233
void
translateDir
(
unsigned
dir_index
,
const
double
trasnalation_in_dir
) {
234
lower[
dir_index
] +=
trasnalation_in_dir
;
235
upper[
dir_index
] +=
trasnalation_in_dir
;
236
}
237
244
Vec<2, double>
moveInside(
Vec<2, double>
p)
const
;
245
252
friend
inline
std::ostream&
operator<<
(std::ostream& out,
const
Box2D
&
to_print
) {
253
return
out <<
'['
<<
to_print
.lower <<
", "
<<
to_print
.upper <<
']'
;
254
}
255
262
bool
isValid
()
const
{
return
upper.c0 >= lower.c0 && upper.c1 >= lower.c1; }
263
268
void
makeInvalid
() {
269
lower =
vec
(0.0, 0.0);
270
upper =
vec
(-1.0, -1.0);
271
}
272
277
double
getArea
()
const
{
278
Vec<2, double>
v
= size();
279
return
v
.c0 *
v
.c1;
280
}
281
287
inline
void
flip
(
size_t
flipDir) {
288
assert
(flipDir < 2);
289
double
temp
= lower[flipDir];
290
lower[flipDir] = -upper[flipDir];
291
upper[flipDir] = -
temp
;
292
}
293
300
inline
Box2D
flipped
(
size_t
i)
const
{
301
Box2D
res
= *
this
;
302
res
.
flip
(i);
303
return
res
;
304
}
305
310
const
double
&
left
()
const
{
return
lower.c0; }
311
316
double
&
left
() {
return
lower.c0; }
317
322
const
double
&
right
()
const
{
return
upper.c0; }
323
328
double
&
right
() {
return
upper.c0; }
329
334
const
double
&
bottom
()
const
{
return
lower.c1; }
335
340
double
&
bottom
() {
return
lower.c1; }
341
346
const
double
&
top
()
const
{
return
upper.c1; }
347
352
double
&
top
() {
return
upper.c1; }
353
354
void
setLeft
(
double
v
) { lower.c0 =
v
; }
355
void
setRight
(
double
v
) { upper.c0 =
v
; }
356
void
setBottom
(
double
v
) { lower.c1 =
v
; }
357
void
setTop
(
double
v
) { upper.c1 =
v
; }
358
359
double
getLeft
()
const
{
return
lower.c0; }
360
double
getRight
()
const
{
return
upper.c0; }
361
double
getBottom
()
const
{
return
lower.c1; }
362
double
getTop
()
const
{
return
upper.c1; }
363
};
364
371
struct
PLASK_API
Box3D
{
373
Vec<3, double>
lower
;
374
376
Vec<3, double>
upper
;
377
382
constexpr
Vec<3, double>
size
()
const
{
return
upper - lower; }
383
388
constexpr
double
height
()
const
{
return
upper.vert() - lower.vert(); }
389
394
constexpr
double
width
()
const
{
return
upper.tran() - lower.tran(); }
395
400
constexpr
double
depth
()
const
{
return
upper.lon() - lower.lon(); }
401
406
constexpr
Vec<3, double>
center
()
const
{
return
0.5 * (upper + lower); }
407
409
Box3D
() {}
410
416
constexpr
Box3D
(
const
Vec<3, double>
& lower,
const
Vec<3, double>
& upper) : lower(lower), upper(upper) {}
417
423
constexpr
Box3D
(
double
x_lo
,
double
y_lo
,
double
z_lo
,
double
x_up
,
double
y_up
,
double
z_up
)
424
: lower(
x_lo
,
y_lo
,
z_lo
), upper(
x_up
,
y_up
,
z_up
) {}
425
426
static
Box3D
invalidInstance
() {
427
Box3D
r;
428
r.
makeInvalid
();
429
return
r;
430
}
431
437
bool
operator==
(
const
Box3D
& r)
const
;
438
444
bool
operator!=
(
const
Box3D
& r)
const
;
445
450
void
fix();
451
457
bool
contains(
const
Vec<3, double>
& p)
const
;
458
464
bool
intersects(
const
Box3D
& other)
const
;
465
470
void
makeInclude(
const
Vec<3, double>
& p);
471
476
void
makeInclude(
const
Box3D
& other);
477
482
void
makeIntersection(
const
Box3D
& other);
483
489
Box3D
extension(
Box3D
other)
const
;
490
496
Box3D
intersection(
Box3D
other)
const
;
497
503
Box3D
translated
(
const
Vec<3, double>
&
translation_vec
)
const
{
504
return
Box3D
(lower +
translation_vec
, upper +
translation_vec
);
505
}
506
512
Box3D
operator+
(
const
Vec<3, double>
&
translation_vec
)
const
{
513
return
Box3D
(lower +
translation_vec
, upper +
translation_vec
);
514
}
515
521
Box3D
operator-
(
const
Vec<3, double>
&
translation_vec
)
const
{
522
return
Box3D
(lower -
translation_vec
, upper -
translation_vec
);
523
}
524
530
Box3D
translatedUp
(
const
double
trasnalation_in_up_dir
)
const
{
531
Box3D
r = *
this
;
532
r.
translateUp
(
trasnalation_in_up_dir
);
533
return
r;
534
}
535
540
void
translate
(
const
Vec<3, double>
&
translation_vec
) {
541
lower +=
translation_vec
;
542
upper +=
translation_vec
;
543
}
544
549
Box3D
&
operator+=
(
const
Vec<3, double>
&
translation_vec
) {
550
lower +=
translation_vec
;
551
upper -=
translation_vec
;
552
return
*
this
;
553
}
554
559
Box3D
&
operator-=
(
const
Vec<3, double>
&
translation_vec
) {
560
lower -=
translation_vec
;
561
upper -=
translation_vec
;
562
return
*
this
;
563
}
564
569
void
translateUp
(
const
double
trasnalation_in_up_dir
) {
570
lower.vert() +=
trasnalation_in_up_dir
;
571
upper.vert() +=
trasnalation_in_up_dir
;
572
}
573
579
void
translateDir
(
unsigned
dir_index
,
const
double
trasnalation_in_dir
) {
580
lower[
dir_index
] +=
trasnalation_in_dir
;
581
upper[
dir_index
] +=
trasnalation_in_dir
;
582
}
583
588
void
makeInclude
(
const
Box2D
& other);
589
596
Vec<3, double>
moveInside(
Vec<3, double>
p)
const
;
597
604
friend
inline
std::ostream&
operator<<
(std::ostream& out,
const
Box3D
&
to_print
) {
605
return
out <<
'['
<<
to_print
.lower <<
", "
<<
to_print
.upper <<
']'
;
606
}
607
614
bool
isValid
()
const
{
return
upper.c0 >= lower.c0 && upper.c1 >= lower.c1 && upper.c2 >= lower.c2; }
615
620
void
makeInvalid
() {
621
lower =
vec
(0.0, 0.0, 0.0);
622
upper =
vec
(-1.0, -1.0, -1.0);
623
}
624
629
double
getArea
()
const
{
630
Vec<3, double>
v
= size();
631
return
v
.c0 *
v
.c1 *
v
.c2;
632
}
633
639
inline
void
flip
(
size_t
flipDir) {
640
assert
(flipDir < 3);
641
double
temp
= lower[flipDir];
642
lower[flipDir] = -upper[flipDir];
643
upper[flipDir] = -
temp
;
644
}
645
652
inline
Box3D
flipped
(
size_t
i)
const
{
653
Box3D
res
= *
this
;
654
res
.
flip
(i);
655
return
res
;
656
}
657
662
const
double
&
back
()
const
{
return
lower.c0; }
663
668
double
&
back
() {
return
lower.c0; }
669
674
const
double
&
front
()
const
{
return
upper.c0; }
675
680
double
&
front
() {
return
upper.c0; }
681
686
const
double
&
left
()
const
{
return
lower.c1; }
687
692
double
&
left
() {
return
lower.c1; }
693
698
const
double
&
right
()
const
{
return
upper.c1; }
699
704
double
&
right
() {
return
upper.c1; }
705
710
const
double
&
bottom
()
const
{
return
lower.c2; }
711
716
double
&
bottom
() {
return
lower.c2; }
717
722
const
double
&
top
()
const
{
return
upper.c2; }
723
728
double
&
top
() {
return
upper.c2; }
729
730
void
setBack
(
double
v
) { lower.c0 =
v
; }
731
void
setFront
(
double
v
) { upper.c0 =
v
; }
732
void
setLeft
(
double
v
) { lower.c1 =
v
; }
733
void
setRight
(
double
v
) { upper.c1 =
v
; }
734
void
setBottom
(
double
v
) { lower.c2 =
v
; }
735
void
setTop
(
double
v
) { upper.c2 =
v
; }
736
737
double
getBack
()
const
{
return
lower.c0; }
738
double
getFront
()
const
{
return
upper.c0; }
739
double
getLeft
()
const
{
return
lower.c1; }
740
double
getRight
()
const
{
return
upper.c1; }
741
double
getBottom
()
const
{
return
lower.c2; }
742
double
getTop
()
const
{
return
upper.c2; }
743
};
744
749
template
<
int
dim>
struct
Primitive
{};
750
754
template
<>
struct
PLASK_API
Primitive
<1> {
756
typedef
double
DVec
;
757
759
static
const
int
dim = 1;
760
762
static
const
DVec
ZERO_VEC
;
763
764
enum
Direction
{ DIRECTION = 0 };
765
767
inline
static
bool
vecFuzzyCompare
(
DVec
a
,
DVec
b
) {
return
b
-
a
>
POINT_TOLLERANCE
; }
768
};
769
773
template
<>
struct
PLASK_API
Primitive
<2> {
775
typedef
Box2D
Box
;
776
778
typedef
Vec<2, double>
DVec
;
779
781
static
const
int
dim = 2;
782
784
static
const
DVec
ZERO_VEC
;
785
787
static
const
DVec
NAN_VEC
;
788
790
static
const
Box
INF_BOX
;
791
792
enum
Direction
{ DIRECTION_TRAN = 0, DIRECTION_VERT = 1 };
793
794
static
void
ensureIsValidDirection
(
unsigned
direction) {
795
if
(direction > 1)
throw
Exception
(
"bad 2D direction index, {0} was given but allowed are: 0, 1."
, direction);
796
}
797
799
inline
static
bool
vecFuzzyCompare
(
const
DVec
&
a
,
const
DVec
&
b
) {
800
return
b
.c1 -
a
.c1 >
POINT_TOLLERANCE
|| (
a
.c1 -
b
.c1 <=
POINT_TOLLERANCE
&&
b
.c0 -
a
.c0 >
POINT_TOLLERANCE
);
801
}
802
};
803
807
template
<>
struct
PLASK_API
Primitive
<3> {
809
typedef
Box3D
Box
;
810
812
typedef
Vec<3, double>
DVec
;
813
815
static
const
int
dim = 3;
816
818
static
const
DVec
ZERO_VEC
;
819
821
static
const
DVec
NAN_VEC
;
822
824
static
const
Box
INF_BOX
;
825
826
enum
Direction
{ DIRECTION_LONG = 0, DIRECTION_TRAN = 1, DIRECTION_VERT = 2 };
827
828
static
void
ensureIsValidDirection
(
unsigned
direction) {
829
if
(direction > 2)
830
throw
DimensionError
(
"bad 3D direction index, {} was given but allowed are: 0, 1, 2."
, direction);
831
}
832
833
static
void
ensureIsValid2DDirection
(
unsigned
direction) {
834
if
(direction != DIRECTION_TRAN && direction != DIRECTION_VERT)
835
throw
DimensionError
(
836
"bad 2D direction index, {} was given but allowed are: 1 (DIRECTION_TRAN), 2 (DIRECTION_VERT)."
,
837
direction);
838
}
839
841
inline
static
bool
vecFuzzyCompare
(
const
DVec
&
a
,
const
DVec
&
b
) {
842
return
b
.c2 -
a
.c2 >
POINT_TOLLERANCE
|| (
a
.c2 -
b
.c2 <=
POINT_TOLLERANCE
&&
843
(
b
.c1 -
a
.c1 >
POINT_TOLLERANCE
|| (
a
.c1 -
b
.c1 <=
POINT_TOLLERANCE
&&
844
b
.c0 -
a
.c0 >
POINT_TOLLERANCE
)));
845
}
846
};
847
848
constexpr
inline
Primitive<3>::Direction
direction3D
(
Primitive<2>::Direction
dir2D
) {
849
return
Primitive<3>::Direction
(
dir2D
+ 1);
850
}
851
852
constexpr
inline
Primitive<3>::Direction
direction3D
(
Primitive<3>::Direction
dir3D
) {
return
dir3D
; }
853
854
template <int dim, typename Primitive<dim>::Direction
dirToSkip
>
struct
DirectionWithout
{};
855
856
template
<>
struct
DirectionWithout
<2,
Primitive
<2>::DIRECTION_TRAN> {
857
static
const
Primitive<2>::Direction
value =
Primitive<2>::DIRECTION_VERT
;
858
static
const
Primitive<3>::Direction
value3d =
Primitive<3>::DIRECTION_VERT
;
859
};
860
861
template
<>
struct
DirectionWithout
<2,
Primitive
<2>::DIRECTION_VERT> {
862
static
const
Primitive<2>::Direction
value =
Primitive<2>::DIRECTION_TRAN
;
863
static
const
Primitive<3>::Direction
value3d =
Primitive<3>::DIRECTION_TRAN
;
864
};
865
866
template
<>
struct
DirectionWithout
<3,
Primitive
<3>::DIRECTION_LONG> {
867
static
const
unsigned
value =
Primitive<3>::DIRECTION_TRAN
|
Primitive<3>::DIRECTION_VERT
;
868
static
const
Primitive<3>::Direction
valueLower =
Primitive<3>::DIRECTION_TRAN
;
869
static
const
Primitive<3>::Direction
valueHigher =
Primitive<3>::DIRECTION_VERT
;
870
871
// should be not usedm but sometimes it is useful to make compilation possible
872
static
const
Primitive<2>::Direction
value2D =
873
Primitive<2>::Direction
(
Primitive<2>::DIRECTION_VERT
|
Primitive<2>::DIRECTION_VERT
);
874
};
875
876
template
<>
struct
DirectionWithout
<3,
Primitive
<3>::DIRECTION_TRAN> {
877
static
const
unsigned
value =
Primitive<3>::DIRECTION_LONG
|
Primitive<3>::DIRECTION_VERT
;
878
static
const
Primitive<3>::Direction
valueLower =
Primitive<3>::DIRECTION_LONG
;
879
static
const
Primitive<3>::Direction
valueHigher =
Primitive<3>::DIRECTION_VERT
;
880
881
static
const
Primitive<2>::Direction
value2D =
Primitive<2>::DIRECTION_VERT
;
882
};
883
884
template
<>
struct
DirectionWithout
<3,
Primitive
<3>::DIRECTION_VERT> {
885
static
const
unsigned
value =
Primitive<3>::DIRECTION_LONG
|
Primitive<3>::DIRECTION_TRAN
;
886
static
const
Primitive<3>::Direction
valueLower =
Primitive<3>::DIRECTION_LONG
;
887
static
const
Primitive<3>::Direction
valueHigher =
Primitive<3>::DIRECTION_TRAN
;
888
889
static
const
Primitive<2>::Direction
value2D =
Primitive<2>::DIRECTION_TRAN
;
890
};
891
892
}
// namespace plask
893
894
#endif
plask
geometry
primitives.hpp
Generated by
1.9.8