openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
vect.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) NumeriCor GmbH
2 // SPDX-License-Identifier: Apache-2.0
3 
12 #ifndef VECT_H
13 #define VECT_H
14 
15 #include <cstdio>
16 #include <cmath>
17 
18 namespace opencarp {
19 
20 #define POINT_REAL double
21 
22 template<typename V>
23 struct vec3 {
24  V x, y, z;
25 
26  vec3() : x(0), y(0), z(0)
27  {}
28 
29  template<typename S>
30  void assign(S ix, S iy, S iz)
31  {x = ix, y = iy, z = iz;}
32 
33  template<typename S>
34  vec3(S ix, S iy, S iz) : x(ix), y(iy), z(iz)
35  {}
36  template<class VEC>
37  vec3(VEC & v) {
38  x = v.x; y = v.y; z = v.z;
39  }
40  template<typename S>
41  void operator= (const S* v)
42  {
43  x = v[0], y = v[1], z = v[2];
44  }
45  template<typename S>
46  void operator= (const vec3<S> & v)
47  {
48  x = v.x, y = v.y, z = v.z;
49  }
50 
51  void operator+= (const vec3<V> & v)
52  {
53  x += v.x;
54  y += v.y;
55  z += v.z;
56  }
57  void operator-= (const vec3<V> & v)
58  {
59  x -= v.x;
60  y -= v.y;
61  z -= v.z;
62  }
63  void operator*= (const V s)
64  {
65  x *= s;
66  y *= s;
67  z *= s;
68  }
69 
70  void operator/= (const V s)
71  {
72  x /= s;
73  y /= s;
74  z /= s;
75  }
76 };
77 
79 
80 template<typename V>
81 inline V det3(const vec3<V> & a, const vec3<V> & b, const vec3<V> & c) /* return determinate of 3x3 matrix */
82 {
83  return (a.x*b.y*c.z + a.y*b.z*c.x + a.z*b.x*c.y - a.x*b.z*c.y - a.y*b.x*c.z - a.z*b.y*c.x);
84 }
85 
86 template<typename V>
87 inline V dist_2(const vec3<V> & p1, const vec3<V> & p2) /* square of distance between points*/
88 {
89  V d =
90  (p1.x-p2.x)*(p1.x-p2.x) +
91  (p1.y-p2.y)*(p1.y-p2.y) +
92  (p1.z-p2.z)*(p1.z-p2.z);
93 
94  if (d<0 || d!= d) return 0. ;
95  else return d ;
96 }
97 
98 template<typename V>
99 inline V dist(const vec3<V> & p1, const vec3<V> & p2) /* distance between points*/
100 {
101  return sqrt(dist_2(p1, p2));
102 }
103 
104 template<typename V>
105 inline V angle(const vec3<V> & v1, const vec3<V> & v2) { /* return angle between vectors in rad*/
106  return fabs(dot(v1, v2)) / (mag(v1)*mag(v2));
107 }
108 
109 template<typename V>
110 inline V dot(const vec3<V> & p1, const vec3<V> & p2) /* perform dot prduct operation */
111 {
112  return p1.x*p2.x + p1.y*p2.y + p1.z*p2.z;
113 }
114 
115 template<typename V>
116 inline V mag(const vec3<V> & vect) /* determine magnitude of a vector */
117 {
118  return sqrt(vect.x*vect.x + vect.y*vect.y + vect.z*vect.z);
119 }
120 
121 
122 template<typename V>
123 inline V mag2(const vec3<V> & vect) /* determine magnitude of a vector */
124 {
125  return vect.x*vect.x + vect.y*vect.y + vect.z*vect.z;
126 }
127 
128 template<typename V>
129 inline vec3<V> cross(const vec3<V> & a, const vec3<V> & b) /* cross product aXb */
130 {
131  return {a.y*b.z - b.y*a.z, b.x*a.z - a.x*b.z, a.x*b.y - a.y*b.x};
132 }
133 
134 template<typename V, typename S>
135 inline vec3<V> scal_X(const vec3<V> & a, S k)/* scalar multiplication of vector a by k */
136 {
137  return {a.x * k, a.y * k, a.z * k};
138 }
139 
140 template<typename V>
141 inline vec3<V> operator* (const vec3<V> & a, V k)/* scalar multiplication of vector a by k */
142 {
143  return {a.x * k, a.y * k, a.z * k};
144 }
145 
146 template<typename V>
147 inline vec3<V> operator/ (const vec3<V> & a, V k)/* scalar multiplication of vector a by k */
148 {
149  return {a.x / k, a.y / k, a.z / k};
150 }
151 
152 template<typename V>
153 inline vec3<V> scale3(const vec3<V> & a, const vec3<V> & k) /* anisotropic scalar mult. of vector a */
154 {
155  vec3<V> r = a;
156  r.x *= k.x;
157  r.y *= k.y;
158  r.z *= k.z;
159 
160  return r;
161 }
162 
163 template<typename V>
164 inline vec3<V> operator- (const vec3<V> & a, const vec3<V> & b)
165 {
166  vec3<V> r;
167  r.x = a.x - b.x;
168  r.y = a.y - b.y;
169  r.z = a.z - b.z;
170  return r;
171 }
172 template<typename V>
173 inline vec3<V> operator+ (const vec3<V> & a, const vec3<V> & b)
174 {
175  vec3<V> r;
176  r.x = a.x + b.x;
177  r.y = a.y + b.y;
178  r.z = a.z + b.z;
179  return r;
180 }
181 
182 template<typename V>
183 inline vec3<V> normalize(vec3<V> a) /* return unit vector in direction of a */
184 {
185  double magnitude = mag(a);
186  a.x /= magnitude;
187  a.y /= magnitude;
188  a.z /= magnitude;
189  return a;
190 }
191 
192 
193 template<typename V>
194 inline double *v_scale(int n, double *a, double k, double *b)
195 /*scale vector by a constant*/
196 {
197  for (n--; n>=0; n--)
198  b[n] = k*a[n];
199 
200  return b;
201 }
202 
203 
204 template<typename V>
205 inline float *v_scale_f(int n, float *a, double k, double *b)
206 /*scale vector by a constant*/
207 {
208  for (n--; n>=0; n--)
209  b[n] = k*a[n];
210 
211  return a;
212 }
213 
214 
215 template<typename V>
216 inline vec3<V> mid_point(vec3<V> a, vec3<V> b) /* return midpoint of line ab */
217 {
218  return {(a.x + b.x)/2.0, (a.y + b.y)/2.0, (a.z + b.z)/2.0};
219 }
220 
221 
222 template<typename V>
223 inline vec3<V> rotate_z(vec3<V> p, double theta) /* rotate about z_axis */
224 {
225  double cost = cos(theta);
226  double sint = sin(theta);
227  return {cost*p.x+sint*p.y, -sint*p.x+cost*p.y, p.z};
228 }
229 
230 
231 template<typename V>
232 inline vec3<V> rotate_y(vec3<V> p, double theta) /* rotate about y_axis */
233 {
234  double cost = cos(theta);
235  double sint = sin(theta);
236  return {cost*p.x-sint*p.z, p.y, sint*p.x+cost*p.z};
237 }
238 
239 
240 template<typename V>
241 inline vec3<V> rotate_x(vec3<V> p, double theta) /* rotate about x_axis */
242 {
243  double cost = cos(theta);
244  double sint = sin(theta);
245  return { p.x, cost*p.y+sint*p.z, -sint*p.y+cost*p.z};
246 }
247 
248 
249 inline void matrix_mathematica(int n, double **a, char *outfile)
250 /* output a matrix in matematica form */
251 {
252  FILE *out;
253  int i, j;
254 
255  out = fopen(outfile, "w");
256  fprintf(out, "%s = {\n", outfile);
257  for (i=0 ; i<n; i++) {
258  fprintf(out, "{ ");
259  for (j=0 ; j<n; j++) {
260  fprintf(out, "%.12f 10^%.0f", a[i][j] != 0.0 ?
261  a[i][j]/pow(10.0, floor(log10(fabs(a[i][j])))) : 0.0,
262  a[i][j] != 0.0 ?floor(log10(fabs(a[i][j]))) : 0.0) ;
263  if (j != n-1)
264  fprintf(out, ", \n");
265  }
266  fprintf(out, "}");
267  if (i!= n-1)
268  fprintf(out, ", ");
269  fprintf(out, "\n");
270  }
271  fprintf(out, "}\n");
272  fclose(out);
273 }
274 
276 template<typename V>
278 {
279  return scal_X(A, dot(normalize(A), normalize(B)));
280 }
281 
282 
284 template<typename V>
286 {
287  return p_sub(A, p_project(A, B));
288 }
289 
292 template<typename V>
293 inline double triple_prod(vec3<V> a, vec3<V> b, vec3<V> c)
294 {
295  return dot(a, cross(b, c));
296 }
297 
299 template<typename V>
300 inline bool isNaN(vec3<V> a)
301 {
302  return ((a.x != a.x) || (a.y != a.y) || (a.z != a.z));
303 }
304 
305 // inf norm of a point
306 template<typename V>
307 inline double infnorm(const vec3<V> & a)
308 {
309  double max = std::abs(a.x);
310  max = std::max(std::abs(a.y),max);
311  max = std::max(std::abs(a.z),max);
312  return max;
313 }
314 
315 } // namespace opencarp
316 
317 #endif
string outfile(string specified, enum_format format, int s=-1)
Definition: IGBextract.cc:157
void magnitude(data_t *x, int n, int nc, FILE *out)
determine magnitude at each point
Definition: IGBops.cc:529
constexpr T max(T a, T b)
Definition: ion_type.h:16
vec3< V > scale3(const vec3< V > &a, const vec3< V > &k)
Definition: vect.h:153
V det3(const vec3< V > &a, const vec3< V > &b, const vec3< V > &c)
Definition: vect.h:81
double triple_prod(vec3< V > a, vec3< V > b, vec3< V > c)
Definition: vect.h:293
vec3< V > scal_X(const vec3< V > &a, S k)
Definition: vect.h:135
void matrix_mathematica(int n, double **a, char *outfile)
Definition: vect.h:249
vec3< V > operator+(const vec3< V > &a, const vec3< V > &b)
Definition: vect.h:173
V dot(const vec3< V > &p1, const vec3< V > &p2)
Definition: vect.h:110
vec3< V > operator*(const vec3< V > &a, V k)
Definition: vect.h:141
vec3< V > normalize(vec3< V > a)
Definition: vect.h:183
double * v_scale(int n, double *a, double k, double *b)
Definition: vect.h:194
vec3< V > rotate_x(vec3< V > p, double theta)
Definition: vect.h:241
vec3< V > p_project(vec3< V > A, vec3< V > B)
Definition: vect.h:277
vec3< V > cross(const vec3< V > &a, const vec3< V > &b)
Definition: vect.h:129
V dist(const vec3< V > &p1, const vec3< V > &p2)
Definition: vect.h:99
vec3< V > p_transverse(vec3< V > A, vec3< V > B)
Definition: vect.h:285
bool isNaN(vec3< V > a)
Definition: vect.h:300
vec3< V > mid_point(vec3< V > a, vec3< V > b)
Definition: vect.h:216
V mag(const vec3< V > &vect)
Definition: vect.h:116
V dist_2(const vec3< V > &p1, const vec3< V > &p2)
Definition: vect.h:87
vec3< V > operator-(const vec3< V > &a, const vec3< V > &b)
Definition: vect.h:164
float * v_scale_f(int n, float *a, double k, double *b)
Definition: vect.h:205
vec3< V > rotate_z(vec3< V > p, double theta)
Definition: vect.h:223
double infnorm(const vec3< V > &a)
Definition: vect.h:307
vec3< V > operator/(const vec3< V > &a, V k)
Definition: vect.h:147
vec3< V > rotate_y(vec3< V > p, double theta)
Definition: vect.h:232
V angle(const vec3< V > &v1, const vec3< V > &v2)
Definition: vect.h:105
vec3< POINT_REAL > Point
Definition: vect.h:78
V mag2(const vec3< V > &vect)
Definition: vect.h:123
void operator+=(const vec3< V > &v)
Definition: vect.h:51
void operator/=(const V s)
Definition: vect.h:70
void assign(S ix, S iy, S iz)
Definition: vect.h:30
vec3(VEC &v)
Definition: vect.h:37
vec3(S ix, S iy, S iz)
Definition: vect.h:34
void operator-=(const vec3< V > &v)
Definition: vect.h:57
void operator=(const S *v)
Definition: vect.h:41
void operator*=(const V s)
Definition: vect.h:63