Documentation 6b54b78464
Loading...
Searching...
No Matches
geometry_toolbox.hpp
Go to the documentation of this file.
1/*!
2 * \file geometry_toolbox.hpp
3 * \brief Collection of common lightweight geometry-oriented methods.
4 * \version 8.5.0 "Harrier"
5 *
6 * SU2 Project Website: https://su2code.github.io
7 *
8 * The SU2 Project is maintained by the SU2 Foundation
9 * (http://su2foundation.org)
10 *
11 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
12 *
13 * SU2 is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 * SU2 is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
25 */
26
27#pragma once
28
29#include <cmath>
30#include <algorithm>
31
32namespace GeometryToolbox {
33/// \addtogroup GeometryToolbox
34/// @{
35
36/*! \return ||a-b||^2 */
37template <class T, class U, typename Int>
38inline T SquaredDistance(Int nDim, const T* a, const U* b) {
39 T d(0);
40 for (Int i = 0; i < nDim; i++) d += pow(a[i] - b[i], 2);
41 return d;
42}
43
44/*! \return ||a-b|| */
45template <class T, class U, typename Int>
46inline T Distance(Int nDim, const T* a, const U* b) {
47 return sqrt(SquaredDistance(nDim, a, b));
48}
49
50/*! \brief d = a-b */
51template <class T, typename Int>
52inline void Distance(Int nDim, const T* a, const T* b, T* d) {
53 for (Int i = 0; i < nDim; i++) d[i] = a[i] - b[i];
54}
55
56/*! \brief Reflect a at b: c = 2*b - a
57 */
58template <class T, typename Int>
59inline void PointPointReflect(Int nDim, const T* a, const T* b, T* d) {
60 for (Int i = 0; i < nDim; i++) d[i] = 2 * b[i] - a[i];
61}
62
63/*! \return a.b */
64template <class T, typename Int>
65inline T DotProduct(Int nDim, const T* a, const T* b) {
66 T d(0);
67 for (Int i = 0; i < nDim; ++i) d += a[i] * b[i];
68 return d;
69}
70
71/*! \return ||a||^2 */
72template <class T, typename Int>
73inline T SquaredNorm(Int nDim, const T* a) {
74 return DotProduct(nDim, a, a);
75}
76
77/*! \return ||a|| */
78template <class T, typename Int>
79inline T Norm(Int nDim, const T* a) {
80 return sqrt(SquaredNorm(nDim, a));
81}
82
83/*! \brief dn = max(abs(n.(a-b)), 0.05 * ||a-b|| */
84template <class T, typename Int>
85inline T NormalDistance(Int nDim, const T* n, const T* a, const T* b) {
86 T d[3] = {0};
87 Distance(nDim, a, b, d);
88 return fmax(fabs(DotProduct(nDim, n, d)), 0.05 * Norm(nDim, d));
89}
90
91/*! \brief c = a x b */
92template <class T>
93inline void CrossProduct(const T* a, const T* b, T* c) {
94 c[0] = a[1] * b[2] - a[2] * b[1];
95 c[1] = a[2] * b[0] - a[0] * b[2];
96 c[2] = a[0] * b[1] - a[1] * b[0];
97}
98
99/*!
100 * \brief Compute the coordinate (c) where the line defined by coordinate l0 and
101 * direction d intersects the plane defined by point p0 and normal n.
102 * \return The intersection distance.
103 */
104template <class T, int nDim>
105inline T LinePlaneIntersection(const T* l0, const T* d, const T* p0, const T* n, T* c) {
106 T dist[nDim] = {0.0};
107 Distance(nDim, p0, l0, dist);
108 T alpha = DotProduct(nDim, dist, n) / DotProduct(nDim, d, n);
109 for (int iDim = 0; iDim < nDim; ++iDim) c[iDim] = l0[iDim] + alpha * d[iDim];
110 return fabs(alpha) * Norm(nDim, d);
111}
112
113/*!
114 * \brief Compute the coordinate (c) where point p1 intersects the plane defined
115 * by point p0 and normal n if projected perpendicular to it.
116 * \return The normal distance.
117 */
118template <class T, int nDim>
119inline T PointPlaneProjection(const T* p1, const T* p0, const T* n, T* c) {
120 return LinePlaneIntersection<T, nDim>(p1, n, p0, n, c);
121}
122
123/*! \brief Set U as the normal to a 2D line defined by coords[iPoint][iDim]. */
124template <class T, class U>
125inline void LineNormal(const T& coords, U* normal) {
126 normal[0] = coords[0][1] - coords[1][1];
127 normal[1] = coords[1][0] - coords[0][0];
128}
129
130/*! \brief Normal vector of a triangle, cross product of two sides. */
131template <class T, class U>
132inline void TriangleNormal(const T& coords, U* normal) {
133 U a[3], b[3];
134
135 for (int iDim = 0; iDim < 3; iDim++) {
136 a[iDim] = coords[1][iDim] - coords[0][iDim];
137 b[iDim] = coords[2][iDim] - coords[0][iDim];
138 }
139
140 CrossProduct(a, b, normal);
141 normal[0] *= 0.5;
142 normal[1] *= 0.5;
143 normal[2] *= 0.5;
144}
145
146/*! \brief Normal vector of a quadrilateral, cross product of the two diagonals. */
147template <class T, class U>
148inline void QuadrilateralNormal(const T& coords, U* normal) {
149 U a[3], b[3];
150
151 for (int iDim = 0; iDim < 3; iDim++) {
152 a[iDim] = coords[2][iDim] - coords[0][iDim];
153 b[iDim] = coords[3][iDim] - coords[1][iDim];
154 }
155
156 CrossProduct(a, b, normal);
157 normal[0] *= 0.5;
158 normal[1] *= 0.5;
159 normal[2] *= 0.5;
160}
161
162/*! \brief Signed distance from a point to a plane defined by 3 coordinates. */
163template <class T, class U>
164inline U PointToPlaneDistance(const T& coords, const U* point) {
165 U normal[3], distance[3];
166 TriangleNormal(coords, normal);
167 Distance(3, point, coords[0], distance);
168 return DotProduct(3, distance, normal) / Norm(3, normal);
169}
170
171/*!
172 * \brief Compute a 3D rotation matrix.
173 * \note The implicit ordering is rotation about the x, y, and then z axis.
174 */
175template <class Scalar, class Matrix>
176inline void RotationMatrix(Scalar theta, Scalar phi, Scalar psi, Matrix& mat) {
177 Scalar cosTheta = cos(theta);
178 Scalar cosPhi = cos(phi);
179 Scalar cosPsi = cos(psi);
180 Scalar sinTheta = sin(theta);
181 Scalar sinPhi = sin(phi);
182 Scalar sinPsi = sin(psi);
183
184 mat[0][0] = cosPhi * cosPsi;
185 mat[1][0] = cosPhi * sinPsi;
186 mat[2][0] = -sinPhi;
187
188 mat[0][1] = sinTheta * sinPhi * cosPsi - cosTheta * sinPsi;
189 mat[1][1] = sinTheta * sinPhi * sinPsi + cosTheta * cosPsi;
190 mat[2][1] = sinTheta * cosPhi;
191
192 mat[0][2] = cosTheta * sinPhi * cosPsi + sinTheta * sinPsi;
193 mat[1][2] = cosTheta * sinPhi * sinPsi - sinTheta * cosPsi;
194 mat[2][2] = cosTheta * cosPhi;
195}
196
197/*! \brief Compute a 2D rotation matrix. */
198template <class Scalar, class Matrix>
199inline void RotationMatrix(Scalar psi, Matrix& mat) {
200 Scalar cosPsi = cos(psi);
201 Scalar sinPsi = sin(psi);
202
203 mat[0][0] = cosPsi;
204 mat[0][1] = -sinPsi;
205 mat[1][0] = sinPsi;
206 mat[1][1] = cosPsi;
207}
208
209/*! \brief Apply a rotation matrix (R) about origin (O) to a point at
210 * distance (d) from it to obtain new coordinate (c). */
211template <class Scalar, int nDim>
212inline void Rotate(const Scalar R[][nDim], const Scalar* O, const Scalar* d, Scalar* c) {
213 for (int iDim = 0; iDim < nDim; ++iDim) {
214 c[iDim] = O[iDim];
215 for (int k = 0; k < nDim; ++k) c[iDim] += R[iDim][k] * d[k];
216 }
217}
218
219/*! \return Whether any of the three supplied rotation angles is nonzero. */
220template <class Scalar>
221inline bool HasRotation(const Scalar* angles) {
222 // Configured zero stays exact after degree conversion and negation; retain every nonzero rotation.
223 return angles[0] != 0.0 || angles[1] != 0.0 || angles[2] != 0.0;
224}
225
226/*! \brief Rotate component bounds in place, enclosing the rotated box. */
227template <class Scalar, int nDim>
228inline void RotateBox(const Scalar R[][nDim], Scalar* vMin, Scalar* vMax) {
229 using std::max;
230 using std::min;
231 Scalar rotMin[nDim] = {0.0}, rotMax[nDim] = {0.0};
232 for (int iDim = 0; iDim < nDim; ++iDim) {
233 for (int jDim = 0; jDim < nDim; ++jDim) {
234 const Scalar fromMin = R[iDim][jDim] * vMin[jDim];
235 const Scalar fromMax = R[iDim][jDim] * vMax[jDim];
236 rotMin[iDim] += min(fromMin, fromMax);
237 rotMax[iDim] += max(fromMin, fromMax);
238 }
239 }
240 std::copy_n(rotMin, nDim, vMin);
241 std::copy_n(rotMax, nDim, vMax);
242}
243
244/*! \brief Tangent projection */
245template <class Mat, class Scalar, class Int>
246inline void TangentProjection(Int nDim, const Mat& tensor, const Scalar* vector, Scalar* proj) {
247 for (Int iDim = 0; iDim < nDim; iDim++) proj[iDim] = DotProduct(nDim, tensor[iDim], vector);
248
249 auto normalProj = DotProduct(nDim, proj, vector);
250
251 for (Int iDim = 0; iDim < nDim; iDim++) proj[iDim] -= normalProj * vector[iDim];
252}
253/// @}
254} // namespace GeometryToolbox
CNewtonIntegration::Scalar Scalar
Definition CNewtonIntegration.cpp:31
A templated matrix/vector-like object.
Definition C2DContainer.hpp:374
A simple SIMD type relying on implicit vectorization, i.e. done by the compiler, explicitly vectorize...
Definition vectorization.hpp:89
void Rotate(const Scalar R[][nDim], const Scalar *O, const Scalar *d, Scalar *c)
Apply a rotation matrix (R) about origin (O) to a point at distance (d) from it to obtain new coordin...
Definition geometry_toolbox.hpp:212
U PointToPlaneDistance(const T &coords, const U *point)
Signed distance from a point to a plane defined by 3 coordinates.
Definition geometry_toolbox.hpp:164
void CrossProduct(const T *a, const T *b, T *c)
c = a x b
Definition geometry_toolbox.hpp:93
void QuadrilateralNormal(const T &coords, U *normal)
Normal vector of a quadrilateral, cross product of the two diagonals.
Definition geometry_toolbox.hpp:148
void RotateBox(const Scalar R[][nDim], Scalar *vMin, Scalar *vMax)
Rotate component bounds in place, enclosing the rotated box.
Definition geometry_toolbox.hpp:228
void RotationMatrix(Scalar theta, Scalar phi, Scalar psi, Matrix &mat)
Compute a 3D rotation matrix.
Definition geometry_toolbox.hpp:176
T SquaredDistance(Int nDim, const T *a, const U *b)
Definition geometry_toolbox.hpp:38
T Distance(Int nDim, const T *a, const U *b)
Definition geometry_toolbox.hpp:46
void LineNormal(const T &coords, U *normal)
Set U as the normal to a 2D line defined by coords[iPoint][iDim].
Definition geometry_toolbox.hpp:125
T PointPlaneProjection(const T *p1, const T *p0, const T *n, T *c)
Compute the coordinate (c) where point p1 intersects the plane defined by point p0 and normal n if pr...
Definition geometry_toolbox.hpp:119
T DotProduct(Int nDim, const T *a, const T *b)
Definition geometry_toolbox.hpp:65
void TangentProjection(Int nDim, const Mat &tensor, const Scalar *vector, Scalar *proj)
Tangent projection
Definition geometry_toolbox.hpp:246
T SquaredNorm(Int nDim, const T *a)
Definition geometry_toolbox.hpp:73
bool HasRotation(const Scalar *angles)
Definition geometry_toolbox.hpp:221
void TriangleNormal(const T &coords, U *normal)
Normal vector of a triangle, cross product of two sides.
Definition geometry_toolbox.hpp:132
T Norm(Int nDim, const T *a)
Definition geometry_toolbox.hpp:79
T LinePlaneIntersection(const T *l0, const T *d, const T *p0, const T *n, T *c)
Compute the coordinate (c) where the line defined by coordinate l0 and direction d intersects the pla...
Definition geometry_toolbox.hpp:105
T NormalDistance(Int nDim, const T *n, const T *a, const T *b)
dn = max(abs(n.(a-b)), 0.05 * ||a-b||
Definition geometry_toolbox.hpp:85
void PointPointReflect(Int nDim, const T *a, const T *b, T *d)
Reflect a at b: c = 2*b - a.
Definition geometry_toolbox.hpp:59
FORCEINLINE ARRAY_T sqrt(const ARRAY_T &x)
Definition special_vectorization.hpp:116
FORCEINLINE ARRAY_T pow(const ARRAY_T &a, const ARRAY_T &b)
Definition special_vectorization.hpp:179
Definition geometry_toolbox.hpp:32