Mesh Oriented datABase
(version 5.5.1)
An array-based unstructured mesh library
OrientedBox.hpp
Go to the documentation of this file.
1
/*
2
* MOAB, a Mesh-Oriented datABase, is a software component for creating,
3
* storing and accessing finite element mesh data.
4
*
5
* Copyright 2004 Sandia Corporation. Under the terms of Contract
6
* DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7
* retains certain rights in this software.
8
*
9
* This library is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU Lesser General Public
11
* License as published by the Free Software Foundation; either
12
* version 2.1 of the License, or (at your option) any later version.
13
*
14
*/
15
16
/**\file OrientedBox.hpp
17
*\author Jason Kraftcheck (
[email protected]
)
18
*\date 2006-07-18
19
*/
20
21
#ifndef MB_ORIENTED_BOX_HPP
22
#define MB_ORIENTED_BOX_HPP
23
24
#include "
moab/Forward.hpp
"
25
#include "
moab/CartVect.hpp
"
26
#include "
moab/Matrix3.hpp
"
27
28
#include <iosfwd>
29
30
namespace
moab
31
{
32
33
#define MB_ORIENTED_BOX_UNIT_VECTORS 1
34
#define MB_ORIENTED_BOX_OUTER_RADIUS 1
35
36
class
Range;
37
38
/**\brief Oriented bounding box
39
*/
40
class
OrientedBox
41
{
42
private
:
43
void
order_axes_by_length
(
double
ax1_len,
44
double
ax2_len,
45
double
ax3_len );
//!< orders the box axes by the given lengths for each axis
46
47
public
:
48
CartVect
center
;
//!< Box center
49
Matrix3
axes
;
//!< Box axes, unit vectors sorted by extent of box along axis
50
#if MB_ORIENTED_BOX_UNIT_VECTORS
51
CartVect
length
;
//!< distance from center to plane along each axis
52
#endif
53
#if MB_ORIENTED_BOX_OUTER_RADIUS
54
double
radius
;
//!< outer radius (1/2 diagonal length) of box
55
#endif
56
57
inline
OrientedBox
() :
radius
( 0.0 ) {}
58
59
OrientedBox
(
const
Matrix3
& axes_mat,
const
CartVect
&
center
);
60
OrientedBox
(
const
CartVect
axes_in[3],
const
CartVect
&
center
);
61
62
inline
double
inner_radius
()
const
;
//!< radius of inscribed sphere
63
inline
double
outer_radius
()
const
;
//!< radius of circumscribed sphere
64
inline
double
outer_radius_squared
(
65
const
double
reps )
const
;
//!< square of (radius+at least epsilon) of circumsphere
66
inline
double
inner_radius_squared
(
const
double
reps )
const
;
//!< square of (radius-epsilon) of inscribed sphere
67
inline
double
volume
()
const
;
//!< volume of box
68
inline
CartVect
dimensions
()
const
;
//!< number of dimensions for which box is not flat
69
inline
double
area
()
const
;
//!< largest side area
70
inline
CartVect
axis
(
int
index )
const
;
//!< get unit vector in direction of axis
71
inline
CartVect
scaled_axis
(
int
index )
const
;
//!< get vector in direction of axis, scaled to its true length
72
73
/** Test if point is contained in box */
74
bool
contained
(
const
CartVect
& point,
double
tolerance
)
const
;
75
76
// bool contained( const OrientedBox& other, double tolerance ) const;
77
78
/**\brief get tag handle for storing oriented box
79
*
80
* Get the handle for the tag with the specified name and
81
* check that the tag is appropriate for storing instances
82
* of OrientedBox. The resulting tag may be used to store
83
* instances of OrientedBox directly.
84
*
85
*\param handle_out The TagHandle, passed back to caller
86
*\param name The tag name
87
*\param create If true, tag will be created if it does not exist
88
*/
89
static
ErrorCode
tag_handle
(
Tag
& handle_out,
Interface
* instance,
const
char
* name );
90
91
/**\brief Calculate an oriented box from a set of vertices */
92
static
ErrorCode
compute_from_vertices
(
OrientedBox
& result,
Interface
* instance,
const
Range
& vertices );
93
94
/**\brief Calculate an oriented box from a set of 2D elements */
95
static
ErrorCode
compute_from_2d_cells
(
OrientedBox
& result,
Interface
* instance,
const
Range
& elements );
96
97
/** Structure to hold temporary accumulated triangle data for
98
* calculating box orientation. See box_from_covariance_data
99
* to see how this is used to calculate the final covariance matrix
100
* and resulting box orientation.
101
*/
102
struct
CovarienceData
103
{
104
CovarienceData
() :
area
( 0.0 ) {}
105
CovarienceData
(
const
Matrix3
& m,
const
CartVect
& c,
double
a ) :
matrix
( m ),
center
( c ),
area
( a ) {}
106
Matrix3
matrix
;
//!< Running sum for covariance matrix
107
CartVect
center
;
//!< Sum of triangle centroids weighted by 2*triangle area
108
double
area
;
//!< 2x the sum of the triangle areas
109
};
110
111
/** Calculate a CovarienceData struct from a list of triangles */
112
static
ErrorCode
covariance_data_from_tris
(
CovarienceData
& result,
113
Interface
* moab_instance,
114
const
Range
& elements );
115
116
/** Calculate an OrientedBox given an array of CovarienceData and
117
* the list of vertices the box is to bound.
118
*/
119
static
ErrorCode
compute_from_covariance_data
(
OrientedBox
& result,
120
Interface
* moab_instance,
121
const
CovarienceData
* orient_array,
122
unsigned
orient_array_length,
123
const
Range
& vertices );
124
125
/** Test for intersection of a ray (or line segment) with this box.
126
* Ray length limits are used to optimize Monte Carlo particle tracking.
127
*\param ray_start_point The base point of the ray
128
*\param ray_unit_direction The direction of the ray (must be unit length)
129
*\param distance_tolerance Tolerance to use in intersection checks
130
*\param nonnegative_ray_len Optional length of ray in forward direction
131
*\param negative_ray_len Optional length of ray in reverse direction
132
*/
133
bool
intersect_ray
(
const
CartVect
& ray_start_point,
134
const
CartVect
& ray_unit_direction,
135
const
double
distance_tolerance,
136
const
double
* nonnegatve_ray_len = 0,
137
const
double
* negative_ray_len = 0 )
const
;
138
139
/**\brief Find closest position on/within box to input position.
140
*
141
* Find the closest position in the solid box to the input position.
142
* If the input position is on or within the box, then the output
143
* position will be the same as the input position. If the input
144
* position is outside the box, the outside position will be the
145
* closest point on the box boundary to the input position.
146
*/
147
void
closest_location_in_box
(
const
CartVect
& input_position,
CartVect
& output_position )
const
;
148
149
//! Construct a hexahedral element with the same shape as this box.
150
ErrorCode
make_hex
(
EntityHandle
& hex,
Interface
* instance );
151
152
/** Calculate an OrientedBox given a CovarienceData struct and
153
* the list of points the box is to bound.
154
*/
155
static
ErrorCode
compute_from_covariance_data
(
OrientedBox
& result,
156
Interface
* moab_instance,
157
CovarienceData
& orientation_data,
158
const
Range
& vertices );
159
};
160
161
std::ostream&
operator<<
( std::ostream&,
const
OrientedBox
& );
162
163
double
OrientedBox::inner_radius
()
const
164
{
165
#if MB_ORIENTED_BOX_UNIT_VECTORS
166
return
length
[0];
167
#else
168
return
axes
.
col
( 0 ).
length
();
169
#endif
170
}
171
172
double
OrientedBox::outer_radius
()
const
173
{
174
#if MB_ORIENTED_BOX_OUTER_RADIUS
175
return
radius
;
176
#elif MB_ORIENTED_BOX_UNIT_VECTORS
177
return
length
.
length
();
178
#else
179
return
(
axes
.
col
( 0 ) +
axes
.
col
( 1 ) +
axes
.
col
( 2 ) ).length();
180
#endif
181
}
182
183
// Add at least epsilon to the radius, before squaring it.
184
double
OrientedBox::outer_radius_squared
(
const
double
reps )
const
185
{
186
#if MB_ORIENTED_BOX_OUTER_RADIUS
187
return
(
radius
+ reps ) * (
radius
+ reps );
188
#elif MB_ORIENTED_BOX_UNIT_VECTORS
189
CartVect
tmp(
length
[0] + reps,
length
[1] + reps,
length
[2] + reps );
190
return
tmp % tmp;
191
#else
192
CartVect
half_diag =
axes
.
col
( 0 ) +
axes
.
col
( 1 ) +
axes
.
col
( 2 );
193
half_diag +=
CartVect
( reps, reps, reps );
194
return
half_diag % half_diag;
195
#endif
196
}
197
198
// Subtract epsilon from the length of the shortest axis, before squaring it.
199
double
OrientedBox::inner_radius_squared
(
const
double
reps )
const
200
{
201
#if MB_ORIENTED_BOX_UNIT_VECTORS
202
return
(
length
[0] - reps ) * (
length
[0] - reps );
203
#else
204
CartVect
tmp =
axes
.
col
( 0 );
205
tmp -=
CartVect
( reps, reps, reps );
206
return
( tmp % tmp );
207
#endif
208
}
209
210
double
OrientedBox::volume
()
const
211
{
212
#if MB_ORIENTED_BOX_UNIT_VECTORS
213
return
8 *
length
[0] *
length
[1] *
length
[2];
214
#else
215
return
fabs( 8 *
axes
.
col
( 0 ) % (
axes
.
col
( 1 ) *
axes
.
col
( 2 ) ) );
216
#endif
217
}
218
219
CartVect
OrientedBox::dimensions
()
const
220
{
221
#if MB_ORIENTED_BOX_UNIT_VECTORS
222
return
2.0 *
length
;
223
#else
224
return
2.0 *
CartVect
(
axes
.
col
( 0 ).
length
(),
axes
.
col
( 1 ).
length
(),
axes
.
col
( 2 ).
length
() );
225
#endif
226
}
227
228
double
OrientedBox::area
()
const
229
{
230
#if MB_ORIENTED_BOX_UNIT_VECTORS
231
return
4 *
length
[1] *
length
[2];
232
#else
233
return
4 * (
axes
.
col
( 1 ) *
axes
.
col
( 2 ) ).
length
();
234
#endif
235
}
236
237
CartVect
OrientedBox::axis
(
int
index )
const
238
{
239
return
axes
.
col
( index );
240
}
241
242
CartVect
OrientedBox::scaled_axis
(
int
index )
const
243
{
244
#if MB_ORIENTED_BOX_UNIT_VECTORS
245
return
length
[index] *
axes
.
col
( index );
246
#else
247
return
axes
.
col
( index );
248
#endif
249
}
250
251
}
// namespace moab
252
253
#endif
src
moab
OrientedBox.hpp
Generated on Tue Oct 29 2024 02:05:45 for Mesh Oriented datABase by
1.9.1.