VPTissue Reference Manual
array3.h
Go to the documentation of this file.
1 #ifndef MATH_ARRAY3_H_INCLUDED
2 #define MATH_ARRAY3_H_INCLUDED
3 /*
4  * Copyright 2011-2016 Universiteit Antwerpen
5  *
6  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
7  * the European Commission - subsequent versions of the EUPL (the "Licence");
8  * You may not use this work except in compliance with the Licence.
9  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the Licence is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the Licence for the specific language governing
15  * permissions and limitations under the Licence.
16  */
23 #include "constants.h"
24 #include "signum.h"
25 
26 #include <array>
27 #include <cmath>
28 #include <ostream>
29 
30 namespace std {
31 
32 
33 // ---------------------------------------------------------------------------------------------------
34 // Array's norm.
35 // ---------------------------------------------------------------------------------------------------
36 
38 inline double Norm(const std::array<double, 3>& u)
39 {
40  return std::sqrt( u[0] * u[0] + u[1] * u[1] + u[2] * u[2] );
41 }
42 
44 inline double Norm2(const std::array<double, 3>& u)
45 {
46  return u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
47 }
48 
49 // ---------------------------------------------------------------------------------------------------
50 // Unary, basic arithmetic.
51 // ---------------------------------------------------------------------------------------------------
52 
54 inline std::array<double, 3>& operator+=(std::array<double, 3>& u, const std::array<double, 3>& v)
55 {
56  u[0] += v[0];
57  u[1] += v[1];
58  u[2] += v[2];
59  return u;
60 }
61 
63 inline std::array<double, 3>& operator-=(std::array<double, 3>& u, const std::array<double, 3>& v)
64 {
65  u[0] -= v[0];
66  u[1] -= v[1];
67  u[2] -= v[2];
68  return u;
69 }
70 
72 inline std::array<double, 3>& operator*=(std::array<double, 3>& u, double m)
73 {
74  u[0] *= m;
75  u[1] *= m;
76  u[2] *= m;
77  return u;
78 }
79 
81 inline std::array<double, 3>& operator/=(std::array<double, 3>& u, double m)
82 {
83  u[0] /= m;
84  u[1] /= m;
85  u[2] /= m;
86  return u;
87 }
88 
89 // ---------------------------------------------------------------------------------------------------
90 // Binary, basic arithmetic.
91 // ---------------------------------------------------------------------------------------------------
92 
94 inline std::array<double, 3> operator+(const std::array<double, 3>& u, const std::array<double, 3>& v)
95 {
96  return {{ u[0] + v[0], u[1] + v[1], u[2] + v[2] }};
97 }
98 
100 inline std::array<double, 3> operator-(const std::array<double, 3>& u, const std::array<double, 3>& v)
101 {
102  return {{ u[0] - v[0], u[1] - v[1], u[2] - v[2] }};
103 }
104 
106 inline std::array<double, 3> operator* (const std::array<double, 3>& u, double m)
107 {
108  return {{u[0]*m, u[1]*m, u[2]*m}};
109 }
110 
112 inline std::array<double, 3> operator* (double m, const std::array<double, 3>& v)
113 {
114  return v * m;
115 }
116 
118 inline std::array<double, 3> operator/ (const std::array<double, 3>& u, double d)
119 {
120  return {{u[0]/d, u[1]/d, u[2]/d}};
121 }
122 
123 // ---------------------------------------------------------------------------------------------------
124 // Geometric ops.
125 // ---------------------------------------------------------------------------------------------------
126 
128 inline std::array<double, 3> Normalize(const std::array<double, 3>& u)
129 {
130  return u / Norm(u);
131 }
132 
133 
135 inline std::array<double, 3> CrossProduct(const std::array<double, 3>& u, const std::array<double, 3>& v)
136 {
137  return {{ u[1]*v[2] - u[2]*v[1], u[2]*v[0] - u[0]*v[2], u[0]*v[1] - u[1]*v[0] }};
138 }
139 
141 inline double InnerProduct(const std::array<double, 3>& u, const std::array<double, 3>& v)
142 {
143  return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]);
144 }
145 
147 inline std::array<double, 3> Orthogonalize(const std::array<double, 3>& u)
148 {
149  return {{ u[1], -u[0], 0.0 }};
150 }
151 
153 inline double Angle(const std::array<double, 3>& u, const std::array<double, 3>& v)
154 {
155  return std::acos(std::min(1.0, std::max(-1.0, InnerProduct(u, v) / (Norm(u) * Norm(v)))));
156 }
157 
159 inline bool IsSameDirection(const std::array<double, 3>& u, const std::array<double, 3>& v)
160 {
161  return (Angle(u, v) < 0.5 * SimPT_Sim::Util::pi());
162 }
163 
165 inline double SignedAngle(const std::array<double, 3>& u, const std::array<double, 3>& v)
166 {
167  double cos_angle = InnerProduct(u, v) / (Norm(u) * Norm(v));
168  double angle = 0.0;
169  // check for computational inaccuracies
170  if (cos_angle <= -1.0) {
171  angle = SimPT_Sim::Util::pi();
172  }
173  else if (cos_angle >= 1.0) {
174  angle = 0.0;
175  } else {
176  angle = acos(cos_angle) * SimPT_Sim::Util::signum(InnerProduct(Orthogonalize(u), v));
177  }
178  return angle;
179 }
180 
181 // ---------------------------------------------------------------------------------------------------
182 // I/O.
183 // ---------------------------------------------------------------------------------------------------
184 
186 inline std::ostream& operator<<(std::ostream& os, const std::array<double, 3>& v)
187 {
188  os << "(" << v[0] << ", " << v[1] << ", " << v[2] << ")";
189  return os;
190 }
191 
192 } // namespace std
193 
194 #endif // include guard
Math constants.
constexpr int signum(T x, std::false_type)
Overload for unsigned types.
Definition: signum.h:32
STL namespace.
Math signum function.
constexpr double pi()
Math constant pi.
Definition: constants.h:29