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