7#ifndef ANALYTICGEOMETRY_H
8#define ANALYTICGEOMETRY_H
18template <
typename T, MInt nDim>
20 for(
MInt dim = 0; dim < nDim; dim++) {
21 if((
a[dim] >
b[dim + nDim]) ||
b[dim] >
a[dim + nDim]) {
28template <
typename T, MInt nDim>
30 for(
MInt dim = 0; dim < nDim; dim++) {
31 if((
a[dim] <
b[dim]) ||
a[dim + nDim] >
b[dim + nDim]) {
38template <
typename T, MInt nDim>
40 for(
MInt dim = 0; dim < nDim; dim++) {
41 if((p[dim] <
b[dim]) || p[dim] >
b[dim + nDim]) {
51 for(
MInt dim = 0; dim < nDim; dim++) {
52 r +=
POW2(p[dim] - c[dim]);
54 return std::sqrt(r) < R;
64 IF_CONSTEXPR(nDim == 2) {
65 std::cerr <<
"H-Patch not implemented for 2D, not refining any cells! Take care with the angle calculation in 2D "
71 std::array<MFloat, nDim> normalVector;
75 for(
MInt d = 0; d < nDim; d++) {
79 normalVector[d] = p[d] - c[d];
80 distance += normalVector[d] * normalVector[d];
85 distance = sqrt(distance);
86 if(distance < R[0] || distance > R[1])
return false;
89 MFloat angle = atan2(normalVector[(axis + 2) % nDim], normalVector[(axis + 1) % nDim]) * 180.0 / PI;
90 if(angle < phi[0] || angle > phi[1])
return false;
98 const MInt cornerCode[8][3] = {{0, 0, 0}, {nDim, 0, 0}, {0, nDim, 0}, {nDim, nDim, 0},
99 {0, 0, nDim}, {nDim, 0, nDim}, {0, nDim, nDim}, {nDim, nDim, nDim}};
100 for(
MInt corner = 0; corner <
IPOW2(nDim); corner++) {
101 for(
MInt dim = 0; dim < nDim; dim++) {
102 pp[dim] = p[dim + cornerCode[corner][dim]];
104 if(!(maia::geom::isPointInsideSphere<nDim>(pp, c, R))) {
111template <
typename T, MInt nDim>
114 for(
MInt dim = 0; dim < nDim; dim++) {
115 bbox[dim] = c[dim] - R;
116 bbox[dim + nDim] = c[dim] + R;
118 return maia::geom::isBoxInsideBox<T, nDim>(bbox, p);
125 const MInt cornerCode[8][3] = {{0, 0, 0}, {nDim, 0, 0}, {0, nDim, 0}, {nDim, nDim, 0},
126 {0, 0, nDim}, {nDim, 0, nDim}, {0, nDim, nDim}, {nDim, nDim, nDim}};
130 if(maia::geom::isPointInsideBox<MFloat, nDim>(c,
b)) {
135 for(
MInt corner = 0; corner <
IPOW2(nDim); corner++) {
136 for(
MInt dim = 0; dim < nDim; dim++) {
137 cp[dim] =
b[dim + cornerCode[corner][dim]];
139 if(maia::geom::isPointInsideSphere<nDim>(cp, c, R)) {
149 for(
MInt dim = 0; dim < nDim; dim++) {
150 if(c[dim] >
b[dim] && c[dim] <
b[dim + nDim]) {
156 p[dim] = (c[dim] <=
b[dim]) ?
b[dim] :
b[dim + nDim];
166 return maia::geom::isPointInsideSphere<nDim>(p, lc, R);
171 IF_CONSTEXPR(nDim > 3 || nDim < 2) {
mTerm(1, AT_,
"neither 2 nor 3 dimensional"); }
174 MFloat bbox_line[2 * nDim];
175 for(
MInt dim = 0; dim < nDim; dim++) {
176 if(line[dim] < line[dim + nDim]) {
177 bbox_line[dim] = line[dim];
178 bbox_line[dim + nDim] = line[dim + nDim];
180 bbox_line[dim] = line[dim + nDim];
181 bbox_line[dim + nDim] = line[dim];
187 if(!maia::geom::doBoxesOverlap<MFloat, nDim>(bbox_line, bbox)) {
193 for(
MInt dim = 0; dim < nDim; dim++) {
194 const MFloat halfLength = (bbox[dim + nDim] - bbox[dim]) / F2;
195 line_c[dim] = (line[dim] - bbox[dim]) / halfLength - 0.5;
196 line_c[dim + nDim] = (line[dim + nDim] - bbox[dim]) / halfLength - 0.5;
199 MFloat line_span[3] = {F0, F0, F0};
201 for(
MInt dim = 0; dim < nDim; dim++) {
202 line_span[dim] = line_c[dim + nDim] - line_c[dim];
203 lineLength +=
POW2(line_span[dim]);
205 lineLength = std::sqrt(lineLength);
206 for(
MInt dim = 0; dim < nDim; dim++) {
207 line_span[dim] /= lineLength;
210 const MFloat radius = nDim * F1B4;
211 for(
MInt e = 2; e > ((nDim == 2) ? 1 : -1); e--) {
214 MFloat e_vec[3] = {F0, F0, F0};
219 MFloat line_projection = F0;
220 for(
MInt dim = 0; dim < nDim; dim++) {
221 line_projection += axis[dim] * line_c[dim];
225 if(
POW2(line_projection) >= radius) {
231 MFloat corner_projection = F0;
232 for(
MInt dim = 0; dim < nDim; dim++) {
233 corner_projection += axis[dim] * ((axis[dim] > 0) ? 0.5 : -0.5);
237 if(std::fabs(line_projection) >= std::fabs(corner_projection)) {
248 const MBool p1_inside = maia::geom::isPointInsideSphere<nDim>(line, center, radius);
249 const MBool p2_inside = maia::geom::isPointInsideSphere<nDim>(line + nDim, center, radius);
251 if(p1_inside && p2_inside) {
255 if(p1_inside != p2_inside) {
262 MFloat bbox_line[2 * nDim];
263 MFloat bbox_sphere[2 * nDim];
264 for(
MInt dim = 0; dim < nDim; dim++) {
265 bbox_sphere[dim] = center[dim] - radius;
266 bbox_sphere[dim + nDim] = center[dim] + radius;
267 if(line[dim] < line[dim + nDim]) {
268 bbox_line[dim] = line[dim];
269 bbox_line[dim + nDim] = line[dim + nDim];
271 bbox_line[dim] = line[dim + nDim];
272 bbox_line[dim + nDim] = line[dim];
278 if(!maia::geom::doBoxesOverlap<MFloat, nDim>(bbox_line, bbox_sphere)) {
285 for(
MInt dim = 0; dim < nDim; dim++) {
286 const MFloat dl = line[dim + nDim] - line[dim];
287 const MFloat dlc = line[dim] - center[dim];
304 return (t_p <= F1) && (t_p >= F0);
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW2(const Real x)
constexpr MLong IPOW2(MInt x)
MBool doesLinePenetrateSphere(const MFloat *const line, const MFloat *const center, const MFloat radius)
MBool isSphereInsideBox(const T *const c, const T R, const T *const p)
MBool isPointInsideSphere(const MFloat *const p, const MFloat *const c, const MFloat R)
MBool isPointInsideRingSegment(const MFloat *const p, const MFloat *const c, const MFloat *const R, const MFloat *const phi, const MInt axis)
MBool doBoxesOverlap(const T *const a, const T *const b)
MBool doBoxAndSphereOverlap(const MFloat *const b, const MFloat *const c, const MFloat R)
MBool doesLinePenetrateBox(const MFloat *const line, const MFloat *const bbox)
MBool isBoxInsideSphere(const MFloat *const p, const MFloat *const c, const MFloat R)
MBool isPointInsideBox(const T *const p, const T *const b)
MBool isBoxInsideBox(const T *const a, const T *const b)
void cross(const T *const u, const T *const v, T *const c)
Namespace for auxiliary functions/classes.