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