Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
vec.cpp
Go to the documentation of this file.
1#include <stdlib.h>
2#include <iomanip>
3#ifdef VISUAL_STUDIO
4#define _USE_MATH_DEFINES
5// see comment in math.h:
6/* Define _USE_MATH_DEFINES before including math.h to expose these macro
7 * definitions for common math constants. These are placed under an #ifdef
8 * since these commonly-defined names are not part of the C/C++ standards.
9 */
10#endif
11#include <cmath>
14
15/*
16Copyright (c) 2000 Igor B. Smirnov
17
18The file can be used, copied, modified, and distributed
19according to the terms of GNU Lesser General Public License version 2.1
20as published by the Free Software Foundation,
21and provided that the above copyright notice, this permission notice,
22and notices about any modifications of the original text
23appear in all copies and in supporting documentation.
24The file is provided "as is" without express or implied warranty.
25*/
26
27namespace Heed {
28
29int vecerror = 0;
30
31void absref_transmit::print(std::ostream& file, int l) const {
32 if (l <= 0) return;
33 Ifile << "absref_transmit::print(l=" << l << ") qaref=" << qaref
34 << " qaref_pointer=" << qaref_pointer << " qaref_other=" << qaref_other
35 << "\n";
36 file.flush();
37}
38
39absref* absref_transmit::get_other(int /*n*/) { return NULL; }
40
41// **** absref ****
42
43void absref::down(const abssyscoor* fasc) {
44 if (fasc == NULL) return; // considered to be unchanged
46}
47
48void absref::up(const abssyscoor* fasc) {
49 if (fasc == NULL) return; // considered to be unchanged
51}
52
53void absref::turn(const vec& dir, vfloat angle) {
55}
56
57void absref::shift(const vec& dir) {
59}
60
61absref_transmit absref::get_components() {
62 return absref_transmit();
63}
64
65// **** vector ****
66vfloat cos2vec(const vec& r1, const vec& r2) {
67 // cosinus of angle between vectors
68 // If one of vectors has zero length, it returns 2.
69 pvecerror("vfloat cos2vec(const vec& r1, const vec& r2)");
70 vfloat lr1 = r1.length2();
71 vfloat lr2 = r2.length2();
72 // mcout<<"cos2vec:\n";
73 // Iprintn(mcout, lr1);
74 // Iprintn(mcout, lr2);
75 if (lr1 == 0 || lr2 == 0) {
76 vecerror = 1;
77 return 0;
78 }
79 vfloat cs = r1 * r2;
80 int sign = 1;
81 if (cs < 0) sign = -1;
82 cs = cs * cs;
83 cs = sign * sqrt(cs / (lr1 * lr2));
84 // mcout<<"r1="<<r1<<"r2="<<r2<<"cos="<<cs<<'\n';
85 return cs;
86 // return r1*r2/(lr1*lr2);
87}
88
89vfloat ang2vec(const vec& r1, const vec& r2) {
90 // angle between vectors
91 // instead of return acos(cos2vec(r1,r2)); which produces NaN on linux at
92 // parallel vectors
93 vfloat cs = cos2vec(r1, r2);
94 if (vecerror != 0) return 0;
95 if (cs > 0.707106781187 || cs < -0.707106781187) { // 1.0/sqrt(2)
96 // pass to sin, it will be more exactly
97 vfloat sn = sin2vec(r1, r2);
98 if (vecerror != 0) return 0;
99 if (cs > 0.0)
100 return asin(sn);
101 else
102 return M_PI - asin(sn);
103 }
104 return acos(cs);
105}
106
107vfloat sin2vec(const vec& r1, const vec& r2) {
108 // sinus of angle between vectors
109 pvecerror("vfloat sin2vec(const vec& r1, const vec& r2)");
110 vfloat lr1 = r1.length2();
111 vfloat lr2 = r2.length2();
112 if (lr1 == 0 || lr2 == 0) {
113 vecerror = 1;
114 return 0;
115 }
116 vfloat sn = (r1 || r2).length();
117 sn = sn * sn;
118 sn = sqrt(sn / (lr1 * lr2));
119 // mcout<<"r1="<<r1<<"r2="<<r2<<"sin="<<sn<<'\n';
120 return sn;
121 // return sin(ang2vec(r1,r2));
122}
123
124vec project_to_plane(const vec& r, const vec& normal) {
125 pvecerror("vec project_to_plane(const vec& r, const vec& normal)");
126 vec per(normal || r);
127 if (per == dv0) {
128 // either one of vectors is 0 or they are parallel
129 return dv0;
130 }
131 vec ax = unit_vec(per || normal);
132 vfloat v = ax * r;
133 return v * ax;
134}
135
136vfloat ang2projvec(const vec& r1, const vec& r2, const vec& normal) {
137 pvecerror(
138 "vfloat ang2projvec(const vec& r1, const vec& r2, const vec& normal)");
139 vec rt1 = project_to_plane(r1, normal);
140 vec rt2 = project_to_plane(r2, normal);
141 if (rt1 == dv0 || rt2 == dv0) {
142 vecerror = 1;
143 return 0;
144 }
145 vfloat tang = ang2vec(rt1, rt2);
146 if (tang == 0) return tang; // projections are parallel
147 vec at = rt1 || rt2;
148 int i = check_par(at, normal, 0.0001);
149 // mcout<<"r1="<<r1<<"r2="<<r2<<"normal="<<normal
150 // <<"rt1="<<rt1<<"rt2="<<rt2<<"\ntang="<<tang
151 // <<"\nat="<<at<<" i="<<i<<'\n';
152 if (i == -1) return 2.0 * M_PI - tang;
153 return tang; // it works if angle <= PI
154}
155
156vec vec::down_new(const basis* fabas) {
157 // pvecerror("vec vec::down_new(void)");
158 vec r;
159 vec ex = fabas->Gex();
160 vec ey = fabas->Gey();
161 vec ez = fabas->Gez();
162 r.x = x * ex.x + y * ey.x + z * ez.x;
163 r.y = x * ex.y + y * ey.y + z * ez.y;
164 r.z = x * ex.z + y * ey.z + z * ez.z;
165 return r;
166}
167
168void vec::down(const basis* fabas) { *this = this->down_new(fabas); }
169
170vec vec::up_new(const basis* fabas_new) {
171 // it is assumed that fabas_new is derivative from old
172 pvecerrorp("vec vec::up_new((const basis *pbas)");
173 vec r;
174 // check_econd11(fabas_new , ==NULL, mcerr);
175 // not compiled in IRIX, reason is unkown
176 if (fabas_new == NULL) {
177 funnw.ehdr(mcerr);
178 mcerr << "fabas_new==NULL\n";
179 spexit(mcerr);
180 }
181 vec ex = fabas_new->Gex();
182 vec ey = fabas_new->Gey();
183 vec ez = fabas_new->Gez();
184 r.x = x * ex.x + y * ex.y + z * ex.z;
185 r.y = x * ey.x + y * ey.y + z * ey.z;
186 r.z = x * ez.x + y * ez.y + z * ez.z;
187 return r;
188}
189
190void vec::up(const basis* fabas_new) { *this = this->up_new(fabas_new); }
191
192vec vec::turn_new(const vec& dir, vfloat angle) {
193 pvecerror("vec turn(vec& dir, vfloat& angle)");
194 if ((*this).length() == 0) return vec(0, 0, 0);
195 if (check_par(*this, dir, 0.0) != 0) {
196 // parallel vectors are not changed
197 return *this;
198 }
199 vfloat dirlen = dir.length();
200 check_econd11a(dirlen, == 0, "cannot turn around zero vector", mcerr);
201 vec u = dir / dirlen; // unit vector
202 vec constcomp = u * (*this) * u;
203 vec ort1 = unit_vec(u || (*this));
204 vec ort2 = ort1 || u;
205 vec perpcomp = ort2 * (*this) * ort2;
206 vfloat len = perpcomp.length();
207 // mcout<<" constcomp="<<constcomp<<" ort1="<<ort1<<" ort2="<<ort2;
208 ort1 = sin(angle) * len * ort1;
209 ort2 = cos(angle) * len * ort2;
210 // mcout<<" constcomp="<<constcomp<<" ort1="<<ort1<<" ort2="<<ort2
211 // <<" len="<<len<<" sin(angle)="<<sin(angle)<<" cos(angle)="<<cos(angle)
212 // <<" angle="<<angle<<'\n';
213 return constcomp + ort1 + ort2;
214}
215
216void vec::turn(const vec& dir, vfloat angle) {
217 *this = this->turn_new(dir, angle);
218}
219
220void vec::shift(const vec& /*dir*/) {
221 // Not defined for vectors
222}
223
224vec vec::down_new(const abssyscoor* fasc) { return down_new(fasc->Gabas()); }
225void vec::down(const abssyscoor* fasc) { down(fasc->Gabas()); }
226vec vec::up_new(const abssyscoor* fasc) { return up_new(fasc->Gabas()); }
227void vec::up(const abssyscoor* fasc) { up(fasc->Gabas()); }
228
230 const vfloat phi = M_PI * 2.0 * SRANLUX();
231 x = sin(phi);
232 y = cos(phi);
233 z = 0;
234}
235
236void vec::random_conic_vec(double theta) {
237 vfloat phi = M_PI * 2.0 * SRANLUX();
238 double stheta = sin(theta);
239 x = sin(phi) * stheta;
240 y = cos(phi) * stheta;
241 z = cos(theta);
242}
243
245 vfloat cteta = 2.0 * SRANLUX() - 1.0;
247 vfloat steta = sqrt(1.0 - cteta * cteta);
248 *this = (*this) * steta;
249 z = cteta;
250}
251
252std::ostream& operator<<(std::ostream& file, const vec& v) {
253 Ifile << "vector=" << std::setw(13) << v.x << std::setw(13) << v.y
254 << std::setw(13) << v.z;
255 file << '\n';
256 file.flush();
257 return file;
258}
259
260vec dex(1, 0, 0);
261vec dey(0, 1, 0);
262vec dez(0, 0, 1);
263vec dv0(0, 0, 0);
264
265// **** basis ****
266
267absref absref::* basis::aref[3] = {
268 reinterpret_cast<absref absref::*>(static_cast<vec absref::*>(&basis::ex)),
269 reinterpret_cast<absref absref::*>(static_cast<vec absref::*>(&basis::ey)),
270 reinterpret_cast<absref absref::*>(static_cast<vec absref::*>(&basis::ez))};
271
273 return absref_transmit(3, aref);
274}
275
277 pvecerror("basis basis::switch_xyz(void)");
278 return basis(ez, ex, ey, name);
279}
280
281basis::basis() : ex(1, 0, 0), ey(0, 1, 0), ez(0, 0, 1) {
282 name = "primary_bas";
283}
284
285basis::basis(const std::string& pname) : ex(1, 0, 0), ey(0, 1, 0), ez(0, 0, 1) {
286 name = pname;
287}
288
289basis::basis(const vec& p, const std::string& pname) {
290 pvecerror("basis::basis(vec &p)");
291 name = pname;
292 // vec dex(1, 0, 0);
293 // vec dey(0, 1, 0);
294 // vec dez(0, 0, 1);
295 if (p.length() == 0) {
296 vecerror = 1;
297 ex = dex;
298 ey = dey;
299 ez = dez;
300 }
301 vfloat ca = cos2vec(p, dez);
302 if (ca == 1) {
303 ex = dex;
304 ey = dey;
305 ez = dez;
306 } else if (ca == -1) {
307 ex = -dex;
308 ey = -dey;
309 ez = -dez;
310 } else {
311 ez = unit_vec(p);
312 ey = unit_vec(ez || dez);
313 ex = ey || ez;
314 }
315}
316
317basis::basis(const vec& p, const vec& c, const std::string& pname) {
318 pvecerror("basis::basis(vec &p, vec &c, char pname[12])");
319 name = pname;
320
321 if (p.length() == 0 || c.length() == 0) {
322 vecerror = 1;
323 ex = dex;
324 ey = dey;
325 ez = dez;
326 }
327 vfloat ca = cos2vec(p, c);
328 if (ca == 1) {
329 vecerror = 1;
330 ex = dex;
331 ey = dey;
332 ez = dez;
333 } else if (ca == -1) {
334 vecerror = 1;
335 ex = dex;
336 ey = dey;
337 ez = dez;
338 } else {
339 ez = unit_vec(p);
340 ey = unit_vec(ez || c);
341 ex = ey || ez;
342 }
343}
344
345// the same basis with other name, useful for later turning
346basis::basis(const basis& pb, const std::string& pname)
347 : ex(pb.ex), ey(pb.ey), ez(pb.ez) {
348 name = pname;
349}
350
351basis::basis(const vec& pex, const vec& pey, const vec& pez,
352 const std::string& pname) {
353 pvecerror("basis::basis(vec &pex, vec &pey, vec &pez, char pname[12])");
354 if (!check_perp(pex, pey, vprecision) || !check_perp(pex, pez, vprecision) ||
355 !check_perp(pey, pez, vprecision)) {
356 mcerr << "ERROR in basis::basis(vec &pex, vec &pey, vec &pez) : \n"
357 << "the vectors are not perpendicular\n";
358 mcerr << " pex,pey,pez:\n";
359 mcerr << pex << pey << pez;
360 mcerr << "name=" << pname << '\n';
361 spexit(mcerr);
362 }
363 if (!apeq(pex.length(), vfloat(1.0)) ||
364 !apeq(pey.length(), vfloat(1.0)) ||
365 !apeq(pez.length(), vfloat(1.0))) {
366 mcerr << "ERROR in basis::basis(vec &pex, vec &pey, vec &pez) : \n"
367 << "the vectors are not of unit length\n";
368 mcerr << " pex,pey,pez:\n";
369 mcerr << pex << pey << pez;
370 mcerr << "name=" << pname << '\n';
371 spexit(mcerr);
372 }
373 if (!apeq(pex || pey, pez, vprecision)) {
374 mcerr << "ERROR in basis::basis(vec &pex, vec &pey, vec &pez) : \n";
375 mcerr << "wrong direction of pez\n";
376 mcerr << " pex,pey,pez:\n";
377 mcerr << pex << pey << pez;
378 mcerr << "name=" << pname << '\n';
379 spexit(mcerr);
380 }
381 name = pname;
382 ex = pex;
383 ey = pey;
384 ez = pez;
385}
386
387void basis::print(std::ostream& file, int /*l*/) const { file << (*this); }
388
389std::ostream& operator<<(std::ostream& file, const basis& b) {
390 Ifile << "basis: name=" << b.name << '\n';
391 indn.n += 2;
392 int indnsave = indn.n;
393 Ifile << "ex: ";
394 indn.n = 0;
395 file << b.ex;
396 indn.n = indnsave;
397 Ifile << "ey: ";
398 indn.n = 0;
399 file << b.ey;
400 indn.n = indnsave;
401 Ifile << "ez: ";
402 indn.n = 0;
403 file << b.ez;
404 indn.n = indnsave;
405 indn.n -= 2;
406 return file;
407}
408
409// **** point ****
410
411absref absref::* point::aref =
412 reinterpret_cast<absref absref::*>(static_cast<vec absref::*>(&point::v));
413
414absref_transmit point::get_components() {
415 return absref_transmit(1, &aref);
416}
417
418void point::down(const abssyscoor* fasc) {
419 v.down(fasc);
420 shift(fasc->Gapiv()->v);
421}
422void point::up(const abssyscoor* fasc) {
423 shift(-fasc->Gapiv()->v);
424 v.up(fasc);
425}
426
427void point::print(std::ostream& file, int /*l*/) const { file << (*this); }
428
429std::ostream& operator<<(std::ostream& file, const point& p) {
430 Ifile << "point:\n";
431 indn.n += 2;
432 file << p.v;
433 indn.n -= 2;
434 return file;
435}
436
437// **** system of coordinates ****
438
439void abssyscoor::print(std::ostream& file, int l) const {
440 if (l > 0) {
441 Ifile << "abssyscoor::print(l=" << l << "): name=" << name << '\n';
442 if (l > 1) {
443 indn.n += 2;
444 const point* apiv = Gapiv();
445 if (apiv != NULL) {
446 Ifile << "piv=" << noindent << (*apiv);
447 } else {
448 Ifile << "apiv=NULL\n";
449 }
450 const basis* abas = Gabas();
451 if (abas != NULL) {
452 Ifile << "bas=" << noindent << (*abas);
453 } else {
454 Ifile << "abas=NULL\n";
455 }
456 indn.n -= 2;
457 }
458 file.flush();
459 }
460}
461
462std::ostream& operator<<(std::ostream& file, const abssyscoor& f) {
463 f.print(file, 2);
464 return file;
465}
466
467absref absref::* fixsyscoor::aref[2] = {
468 reinterpret_cast<absref absref::*>(
469 static_cast<point absref::*>(&fixsyscoor::piv)),
470 reinterpret_cast<absref absref::*>(
471 static_cast<basis absref::*>(&fixsyscoor::bas))};
472
474 return absref_transmit(2, aref);
475}
476
477void fixsyscoor::Ppiv(const point& fpiv) { piv = fpiv; }
478void fixsyscoor::Pbas(const basis& fbas) { bas = fbas; }
479
480void fixsyscoor::print(std::ostream& file, int l) const {
481 if (l > 0) {
482 Ifile << "fixsyscoor::print(l=" << l << ")\n";
483 if (l > 1) {
484 indn.n += 2;
485 abssyscoor::print(file, l);
486 }
487 }
488}
489
490std::ostream& operator<<(std::ostream& file, const fixsyscoor& f) {
491 Ifile << "fixsyscoor:\n";
492 f.abssyscoor::print(file, 2);
493 return file;
494}
495
496}
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:172
#define spexit(stream)
Definition: FunNameStack.h:256
int qaref_other
Number of objects available though virtual function GetOther.
Definition: vec.h:149
virtual void print(std::ostream &file, int l) const
Definition: vec.cpp:31
virtual absref * get_other(int n)
Definition: vec.cpp:39
int qaref
Number of vector objects which are the members of the class.
Definition: vec.h:129
virtual void up(const abssyscoor *fasc)
Convert numbering representation of objects to new system.
Definition: vec.cpp:48
virtual void shift(const vec &dir)
Definition: vec.cpp:57
virtual void down(const abssyscoor *fasc)
Convert numbering representation of object to basical system of fasc.
Definition: vec.cpp:43
virtual void turn(const vec &dir, vfloat angle)
Turn around axis doing via center of coordinate system along dir.
Definition: vec.cpp:53
virtual void print(std::ostream &file, int l) const
Definition: vec.cpp:439
virtual const point * Gapiv() const =0
virtual const basis * Gabas() const =0
std::string name
Definition: vec.h:424
Basis.
Definition: vec.h:313
virtual absref_transmit get_components() override
Definition: vec.cpp:272
vec ez
Definition: vec.h:317
basis()
Nominal basis.
Definition: vec.cpp:281
std::string name
Definition: vec.h:324
vec Gez() const
Definition: vec.h:329
basis switch_xyz() const
Change ex=ez; ey=ex; ez=ey.
Definition: vec.cpp:276
vec ex
Definition: vec.h:317
vec Gey() const
Definition: vec.h:328
static absref absref::* aref[3]
Definition: vec.h:321
vec ey
Definition: vec.h:317
vec Gex() const
Definition: vec.h:327
virtual void print(std::ostream &file, int l) const
Definition: vec.cpp:387
void Ppiv(const point &fpiv)
Definition: vec.cpp:477
static absref absref::* aref[2]
Definition: vec.h:463
absref_transmit get_components() override
Definition: vec.cpp:473
void Pbas(const basis &fbas)
Definition: vec.cpp:478
void print(std::ostream &file, int l) const override
Definition: vec.cpp:480
Point.
Definition: vec.h:368
void shift(const vec &dir) override
Definition: vec.h:379
void up(const abssyscoor *fasc) override
Convert numbering representation of objects to new system.
Definition: vec.cpp:422
void down(const abssyscoor *fasc) override
Convert numbering representation of object to basical system of fasc.
Definition: vec.cpp:418
vec v
Definition: vec.h:370
virtual void print(std::ostream &file, int l) const
Definition: vec.cpp:427
Definition: vec.h:179
void turn(const vec &dir, vfloat angle) override
Turn this vector.
Definition: vec.cpp:216
vec up_new(const basis *fabas_new)
Definition: vec.cpp:170
void shift(const vec &dir) override
Definition: vec.cpp:220
vec turn_new(const vec &dir, vfloat angle)
Make new turned vector and leave this one unchanged.
Definition: vec.cpp:192
vfloat x
Definition: vec.h:192
vfloat length() const
Definition: vec.h:196
vfloat z
Definition: vec.h:194
void up(const basis *fabas_new)
Definition: vec.cpp:190
void random_conic_vec(double theta)
Definition: vec.cpp:236
friend int check_par(const vec &r1, const vec &r2, vfloat prec)
friend vec unit_vec(const vec &v)
vec()=default
Default constructor.
vfloat length2() const
Definition: vec.h:197
void down(const basis *fabas)
Definition: vec.cpp:168
void random_sfer_vec()
Definition: vec.cpp:244
void random_round_vec()
Generate random unit vector in plane perpendicular to z-axis.
Definition: vec.cpp:229
vec down_new(const basis *fabas)
Definition: vec.cpp:156
vfloat y
Definition: vec.h:193
Definition: BGMesh.cpp:6
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:432
vfloat ang2projvec(const vec &r1, const vec &r2, const vec &normal)
Definition: vec.cpp:136
std::ostream & noindent(std::ostream &f)
Definition: prstream.cpp:17
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:37
vec project_to_plane(const vec &r, const vec &normal)
Definition: vec.cpp:124
vec dv0(0, 0, 0)
Definition: vec.h:308
int vecerror
Definition: vec.cpp:29
bool apeq(const circumf &f1, const circumf &f2, vfloat prec)
Definition: circumf.cpp:44
vfloat sin2vec(const vec &r1, const vec &r2)
Definition: vec.cpp:107
DoubleAc acos(const DoubleAc &f)
Definition: DoubleAc.cpp:490
vec dex(1, 0, 0)
Definition: vec.h:305
vfloat cos2vec(const vec &r1, const vec &r2)
Definition: vec.cpp:66
vfloat ang2vec(const vec &r1, const vec &r2)
Definition: vec.cpp:89
DoubleAc sin(const DoubleAc &f)
Definition: DoubleAc.cpp:384
vec dez(0, 0, 1)
Definition: vec.h:307
DoubleAc asin(const DoubleAc &f)
Definition: DoubleAc.cpp:470
indentation indn
Definition: prstream.cpp:15
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:314
const vfloat vprecision
Definition: vfloat.h:17
vec dey(0, 1, 0)
Definition: vec.h:306
double vfloat
Definition: vfloat.h:16
#define Ifile
Definition: prstream.h:195
#define mcerr
Definition: prstream.h:128
#define pvecerrorp(string)
Definition: vec.h:35
#define ApplyAnyFunctionToVecElements(func)
Definition: vec.h:157
#define pvecerror(string)
Definition: vec.h:28