Garfield++ v2r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
straight.cpp
Go to the documentation of this file.
4/*
5Copyright (c) 2000 Igor B. Smirnov
6
7The file can be used, copied, modified, and distributed
8according to the terms of GNU Lesser General Public License version 2.1
9as published by the Free Software Foundation,
10and provided that the above copyright notice, this permission notice,
11and notices about any modifications of the original text
12appear in all copies and in supporting documentation.
13The file is provided "as is" without express or implied warranty.
14*/
15
16namespace Heed {
17
18// **** straight ****
19
20absref absref::*(straight::aref[2]) = {(absref absref::*)&straight::piv,
21 (absref absref::*)&straight::dir};
22
24 aref_tran.pass(new absref_transmit(2, aref));
25}
26
27straight::straight(const plane pl1, const plane pl2) {
28 pvecerror("straight::straight(const plane pl1, const plane pl2)");
29 *this = pl1.cross(pl2);
30}
31int operator==(const straight& sl1, const straight& sl2) {
32 pvecerror("int operator==(const straight &sl1, const straight &sl2)");
33
34 if (!(sl1.dir == sl2.dir || sl1.dir == -sl2.dir)) return 0;
35 if (sl1.piv == sl2.piv) return 1;
36 if (sl1.check_point_in(sl2.piv, 0.0) == 1) return 1;
37 return 0;
38}
39
40bool apeq(const straight& sl1, const straight& sl2, vfloat prec) {
41 pvecerror("int apeq(const straight &sl1, const straight &sl2, vfloat prec)");
42 int i = check_par(sl1.dir, sl2.dir, prec);
43 if (i == 0) return false;
44 if (apeq(sl1.piv, sl2.piv, prec)) return true;
45 return (sl1.check_point_in(sl2.piv, prec) == 1);
46}
47
48int straight::check_point_in(const point& fp, vfloat prec) const {
49 pvecerror("int straight::check_point_in(point fp, vfloat prec)");
50 vfloat f = distance(fp);
51 if (f <= prec) return 1;
52 return 0;
53}
54point straight::cross(const straight& sl, vfloat prec) const {
55 pvecerror("point straight::cross(straight& sl, vfloat prec)");
56 point pt[2];
57 int type_of_cross;
58 vfloat f = vecdistance(sl, type_of_cross, &pt[0]);
59 point ptt(dv0);
60 if (type_of_cross == 2 || type_of_cross == 3) {
61 vecerror = type_of_cross;
62 return ptt;
63 }
64 if (fabs(f) <= prec) {
65 vecerror = 0;
66 return pt[0];
67 } else {
68 vecerror = 1;
69 return ptt;
70 }
71}
72
73vfloat straight::vecdistance(const straight& sl, int& type_of_cross,
74 point pt[2]) const {
76 "vfloat straight::distance(const straight& sl, int type_of_cross, "
77 "point pt[2])");
78 pt[0] = point();
79 pt[1] = point();
80 type_of_cross = 0;
81 straight s1, s2;
82 s1 = *this;
83 s2 = sl; // s2 may be changed
84 if (s1.piv == s2.piv) {
85 // the same origin point
86 if (check_par(s1.dir, s2.dir, 0.0) != 0) {
87 // parallel or anti-parallel
88 type_of_cross = 3;
89 return 0.0; // coincidence
90 } else { // crossed in piv;
91 return 0.0;
92 }
93 }
94 if (check_par(s1.dir, s2.dir, 0.0) != 0) {
95 // parallel or anti-parallel
96 if (s1.check_point_in(s2.piv, 0.0) == 1) {
97 // point in => the same line
98 type_of_cross = 3;
99 return 0.0;
100 } else {
101 // not crossed
102 type_of_cross = 2; // different parallel lines
103 return s1.distance(s2.piv);
104 }
105 } // now we know that the lines are not parallel
106
107 basis bs(s1.dir, s2.dir, "local");
108 // ez is parallel to s1.dir, ez=unit_vec(s1.dir)
109 // ey is perpendicular to plane which have s1.dir and s2.dir,
110 // ey=unit_vec(ez||s2.dir)
111 // ex is vector product of ey and ez, ex=ey||ez
112 // mcout<<bs;
113 fixsyscoor scl(&s1.piv, &bs, "local");
114 // mcout<<scl;
115 plane pn(point(0, 0, 0), vec(1, 0, 0)); // assumed to be in scl
116 // This plane is defined by
117 // mcout<<pn;
118 s2.up(&scl);
119 // mcout<<s2;
120 pt[1] = pn.cross(s2);
121 // mcout<<pt;
122 if (pt[1].v.y == 0) {
123 pt[1].down(&scl);
124 pt[0] = pt[1];
125 return 0.0;
126 } else {
127 type_of_cross = 1;
128 vfloat d = pt[1].v.y;
129 pt[0] = pt[1];
130 pt[0].v.y = 0;
131 pt[0].down(&scl);
132 pt[1].down(&scl);
133 return d;
134 }
135}
136
137vfloat straight::distance(const straight& sl, int& type_of_cross,
138 point pt[2]) const {
139 return fabs(vecdistance(sl, type_of_cross, pt));
140}
141
142straight::straight(straight* sl, int qsl, const straight& sl_start, int anum,
143 vfloat precision, vfloat* dist, // may be negative
144 point (*pt)[2], vfloat& mean2dist) {
145 pvecerror("void straight::straight(straight* sl, int qsl,...");
146 check_econd11(qsl, < 4, mcerr);
147 straight sl_finish = sl_start;
148 int n;
149 mean2dist = max_vfloat;
150 vfloat mean2dist_prev = max_vfloat;
151 int type_of_cross;
152 point* ptf = new point[qsl];
153 // mcout<<"straight::straight: starting, qsl="<<qsl
154 // <<"\nsl_start="<<sl_start<<'\n';
155 do {
156 mean2dist_prev = mean2dist;
157 mean2dist = 0;
158 *this = sl_finish;
159 for (n = 0; n < qsl; n++) {
160 dist[n] = vecdistance(sl[n], type_of_cross, pt[n]);
161 mean2dist += pow(dist[n], 2);
162 check_econd11(type_of_cross, > 1, mcerr);
163 ptf[n] = pt[n][1];
164 }
165 mean2dist /= qsl;
166 if (mean2dist > 0) mean2dist = sqrt(mean2dist);
167 sl_finish = straight(ptf, qsl, anum);
168 // mcout<<"straight::straight: mean2dist_prev="<<mean2dist_prev
169 // <<" mean2dist="<<mean2dist<<'\n';
170 // for( n=0; n<qsl; n++)
171 //{
172 // mcout<<"pt[n][0]="<<pt[n][0]<<'\n';
173 // mcout<<"pt[n][1]="<<pt[n][1]<<'\n';
174 //}
175 } while (mean2dist_prev < mean2dist ||
176 (mean2dist != 0 && mean2dist_prev - mean2dist > precision));
177 delete[] ptf;
178}
179
180vfloat straight::distance(const point& fpt) const {
181 pvecerror("vfloat straight::distance(point& fpt)");
182 if (fpt == piv) return 0.0;
183 vec v = fpt - piv;
184 return v.length() * sin2vec(dir, v); // should be positive
185}
186
187vfloat straight::distance(const point& fpt, point& fcpt) const {
188 pvecerror("vfloat straight::distance(point& fpt, point& fcpt)");
189 if (fpt == piv) {
190 fcpt = piv;
191 return 0.0;
192 }
193 vec v = fpt - piv;
194 vfloat len = v.length();
195 fcpt = piv + len * cos2vec(dir, v) * dir;
196 return v.length() * sin2vec(dir, v);
197}
198
199point straight::vecdistance(const vec normal, const straight& slt) {
200 pvecerror(
201 "vfloat straight::vecdistance(const vec normal, const straight& slt)");
202 if (check_perp(normal, slt.Gdir(), 0.0) == 1) {
203 // if it is perp.
204 mcout << "straight::vecdistance: normal=" << normal
205 << " slt.Gdir()=" << slt.Gdir();
206 vecerror = 1;
207 return point(0, 0, 0);
208 }
209 basis bash(dir, normal, "temprorary");
210 fixsyscoor sc(&piv, &bash, "temprorary");
211 straight slh = slt;
212 slh.up(&sc);
213 plane pn = plane(point(0, 0, 0), vec(1, 0, 0));
214 return pn.cross(slh);
215}
216
217straight::straight(const point* pt, int qpt, int anum) {
218 // interpolates by xi2
219 pvecerror("straight::straight(const point* pt, int qpt, int anum) ");
220 check_econd11(qpt, < 2, mcerr);
221 check_econd21(anum, < 0 ||, >= 3, mcerr);
222
223 if (qpt == 2) {
224 *this = straight(pt[0], pt[1]);
225 return;
226 }
227 double* x = new double[qpt];
228 double* y = new double[qpt];
229 double* z = new double[qpt];
230 for (int n = 0; n < qpt; n++) {
231 x[n] = pt[n].v.x;
232 y[n] = pt[n].v.y;
233 z[n] = pt[n].v.z;
234 }
235 point piv1;
236 if (anum == 0) {
237 linexi2 lcy(qpt, x, y);
238 linexi2 lcz(qpt, x, z);
239 piv = point(lcy.x_mean, lcy.line(lcy.x_mean), lcz.line(lcy.x_mean));
240 piv1 = point(lcy.x_mean + 1, lcy.line(lcy.x_mean + 1),
241 lcz.line(lcy.x_mean + 1));
242 } else if (anum == 1) {
243 linexi2 lcx(qpt, y, x);
244 linexi2 lcz(qpt, y, z);
245 piv = point(lcx.line(lcx.x_mean), lcx.x_mean, lcz.line(lcx.x_mean));
246 // lcx.x_mean = lcz.x_mean
247 piv1 = point(lcx.line(lcx.x_mean + 1), lcx.x_mean + 1,
248 lcz.line(lcx.x_mean + 1));
249 } else {
250 linexi2 lcx(qpt, z, x);
251 linexi2 lcy(qpt, z, y);
252 piv = point(lcx.line(lcx.x_mean), lcy.line(lcx.x_mean), lcx.x_mean);
253 piv1 = point(lcx.line(lcx.x_mean + 1), lcy.line(lcx.x_mean + 1),
254 lcx.x_mean + 1);
255 }
256 dir = unit_vec(piv1 - piv);
257
258 delete[] x;
259 delete[] y;
260 delete[] z;
261}
262
263straight::straight(const straight sl[4], point pt[2], vfloat precision) {
264 pvecerror(
265 "straight::straight(const straight sl[4], point pt[2], vfloat prec");
266 int i;
267 vfloat meandist;
268 point ptprev[2];
269 point ptcurr[2];
270 ptprev[0] = pt[0];
271 ptprev[1] = pt[1];
272 ptcurr[0] = pt[0];
273 ptcurr[1] = pt[1];
274 do {
275 meandist = 0;
276 for (i = 0; i < 2; i++) {
277 int is; // index of line to make plane
278 int ip; // index of point to make plane
279 int isc; // index of line to find point
280 if (i == 0) {
281 is = 0;
282 ip = 1;
283 isc = 1;
284 } else {
285 is = 3;
286 ip = 0;
287 isc = 2;
288 }
289 plane pn(sl[is], ptcurr[ip]);
290 ptcurr[i] = pn.cross(sl[isc]);
291 meandist += (ptcurr[i] - ptprev[i]).length2();
292 mcout << " i=" << i << " ptprev[i]=" << ptprev[i]
293 << " ptcurr[i]=" << ptcurr[i] << '\n';
294 ptprev[i] = ptcurr[i];
295 }
296 meandist /= 2.0;
297 meandist = sqrt(meandist);
298 mcout << "meandist=" << meandist << '\n';
299 } while (meandist >= precision);
300 *this = straight(ptcurr[0], ptcurr[1]);
301}
302
303std::ostream& operator<<(std::ostream& file, const straight& s) {
304 Ifile << "straight (line):\n";
305 indn.n += 2;
306 file << s.piv << s.dir;
307 indn.n -= 2;
308 return file;
309}
310}
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
Definition: FunNameStack.h:191
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
Active pointer or automatic container or controlling pointer.
Definition: AbsPtr.h:199
void pass(X *fptr)
Definition: AbsPtr.h:247
virtual void up(const abssyscoor *fasc)
Convert numbering representation of objects to new system.
Definition: vec.cpp:48
Basis.
Definition: vec.h:319
double line(const double x)
Definition: linexi2.h:66
Plane, defined by defined by a point and a vector normal to the plane.
Definition: plane.h:24
point cross(const straight &sl) const
Definition: plane.cpp:74
Point.
Definition: vec.h:374
virtual void down(const abssyscoor *fasc)
Convert numbering representation of object to basical system of fasc.
Definition: vec.cpp:418
vec v
Definition: vec.h:376
Definition of straight line, as combination of vector and point.
Definition: straight.h:24
point cross(const straight &sl, vfloat prec) const
Definition: straight.cpp:54
point piv
Origin point, pivot.
Definition: straight.h:27
vfloat vecdistance(const straight &sl, int &type_of_cross, point pt[2]) const
Definition: straight.cpp:73
vec Gdir(void) const
Definition: straight.h:33
vfloat distance(const straight &sl, int &type_of_cross, point pt[2]) const
Definition: straight.cpp:137
int check_point_in(const point &fp, vfloat prec) const
Definition: straight.cpp:48
static absrefabsref::*[2] aref
Definition: straight.h:37
virtual void get_components(ActivePtr< absref_transmit > &aref_tran)
Definition: straight.cpp:23
vec dir
Direction, unit vector.
Definition: straight.h:29
Definition: vec.h:186
vfloat x
Definition: vec.h:203
vfloat length() const
Definition: vec.h:205
vfloat z
Definition: vec.h:203
vfloat y
Definition: vec.h:203
Definition: BGMesh.cpp:5
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:36
DoubleAc pow(const DoubleAc &f, double p)
Definition: DoubleAc.cpp:337
vec dv0(0, 0, 0)
Definition: vec.h:314
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
int operator==(const circumf &f1, const circumf &f2)
Definition: circumf.cpp:34
vfloat cos2vec(const vec &r1, const vec &r2)
Definition: vec.cpp:66
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:615
indentation indn
Definition: prstream.cpp:15
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:314
double vfloat
Definition: vfloat.h:16
#define mcout
Definition: prstream.h:126
#define Ifile
Definition: prstream.h:196
#define mcerr
Definition: prstream.h:128
#define pvecerror(string)
Definition: vec.h:29