Garfield++ v1r0
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
22
23void straight::get_components(ActivePtr<absref_transmit>& aref_tran) {
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
40int apeq(const straight& sl1, const straight& sl2, vfloat prec) {
41 pvecerror("int apeq(const straight &sl1, const straight &sl2, vfloat "
42 "prec=vprecision)");
43 int i = check_par(sl1.dir, sl2.dir, prec);
44 if (i == 0) return 0;
45 if (apeq(sl1.piv, sl2.piv, prec)) return 1;
46 if (sl1.check_point_in(sl2.piv, prec) == 1) return 1;
47 return 0;
48}
49
50int straight::check_point_in(const point& fp, vfloat prec) const {
51 pvecerror("int straight::check_point_in(point fp, vfloat prec)");
52 vfloat f = distance(fp);
53 if (f <= prec) return 1;
54 return 0;
55}
56point straight::cross(const straight& sl, vfloat prec) const {
57 pvecerror("point straight::cross(straight& sl, vfloat prec)");
58 point pt[2];
59 int type_of_cross;
60 vfloat f = vecdistance(sl, type_of_cross, &pt[0]);
61 point ptt(dv0);
62 if (type_of_cross == 2 || type_of_cross == 3) {
63 vecerror = type_of_cross;
64 return ptt;
65 }
66 if (fabs(f) <= prec) {
67 vecerror = 0;
68 return pt[0];
69 } else {
70 vecerror = 1;
71 return ptt;
72 }
73}
74
75vfloat straight::vecdistance(const straight& sl, int& type_of_cross,
76 point pt[2]) const {
77 pvecerror("vfloat straight::distance(const straight& sl, int type_of_cross, "
78 "point pt[2])");
79 pt[0] = point();
80 pt[1] = point();
81 type_of_cross = 0;
82 straight s1, s2;
83 s1 = *this;
84 s2 = sl; // s2 may be changed
85 //mcout<<s1<<s2;
86 if (s1.piv == s2.piv) { // the same origin point
87 if (check_par(s1.dir, s2.dir, 0.0) != 0) // parallel or anti-parallel
88 {
89 type_of_cross = 3;
90 return 0.0; // coincidence
91 } else { // crossed in piv;
92 return 0.0;
93 }
94 }
95 if (check_par(s1.dir, s2.dir, 0.0) != 0) // parallel or anti-parallel
96 {
97 if (s1.check_point_in(s2.piv, 0.0) == 1) { // point in => the same line
98 type_of_cross = 3;
99 return 0.0;
100 } else // not crossed
101 {
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 // xi2
146 {
147 pvecerror("void straight::straight(straight* sl, int qsl,...");
148 check_econd11(qsl, < 4, mcerr);
149 straight sl_finish = sl_start;
150 int n;
151 mean2dist = max_vfloat;
152 vfloat mean2dist_prev = max_vfloat;
153 int type_of_cross;
154 point* ptf = new point[qsl];
155 //mcout<<"straight::straight: starting, qsl="<<qsl
156 // <<"\nsl_start="<<sl_start<<'\n';
157 do {
158 mean2dist_prev = mean2dist;
159 mean2dist = 0;
160 *this = sl_finish;
161 for (n = 0; n < qsl; n++) {
162 dist[n] = vecdistance(sl[n], type_of_cross, pt[n]);
163 mean2dist += pow(dist[n], 2);
164 check_econd11(type_of_cross, > 1, mcerr);
165 ptf[n] = pt[n][1];
166 }
167 mean2dist /= qsl;
168 if (mean2dist > 0) mean2dist = sqrt(mean2dist);
169 sl_finish = straight(ptf, qsl, anum);
170 //mcout<<"straight::straight: mean2dist_prev="<<mean2dist_prev
171 // <<" mean2dist="<<mean2dist<<'\n';
172 //for( n=0; n<qsl; n++)
173 //{
174 // mcout<<"pt[n][0]="<<pt[n][0]<<'\n';
175 // mcout<<"pt[n][1]="<<pt[n][1]<<'\n';
176 //}
177 } while (mean2dist_prev < mean2dist ||
178 (mean2dist != 0 && mean2dist_prev - mean2dist > precision));
179 //mcout<<"straight::straight: finishinging, *this="<<(*this)<<'\n';
180 delete ptf;
181}
182
183vfloat straight::distance(const point& fpt) const {
184 pvecerror("vfloat straight::distance(point& fpt)");
185 if (fpt == piv) return 0.0;
186 vec v = fpt - piv;
187 return length(v) * sin2vec(dir, v); // should be positive
188}
189vfloat straight::distance(const point& fpt, point& fcpt) const {
190 pvecerror("vfloat straight::distance(point& fpt, point& fcpt)");
191 if (fpt == piv) {
192 fcpt = piv;
193 return 0.0;
194 }
195 vec v = fpt - piv;
196 vfloat len = length(v);
197 fcpt = piv + len * cos2vec(dir, v) * dir;
198 return length(v) * sin2vec(dir, v);
199}
200
201point straight::vecdistance(const vec normal, const straight& slt) {
202 pvecerror(
203 "vfloat straight::vecdistance(const vec normal, const straight& slt)");
204 if (check_perp(normal, slt.Gdir(), 0.0) == 1) // if it is perp.
205 {
206 mcout << "straight::vecdistance: normal=" << normal
207 << " slt.Gdir()=" << slt.Gdir();
208 vecerror = 1;
209 return point(0, 0, 0);
210 }
211 basis bash(dir, normal, "temprorary");
212 fixsyscoor sc(&piv, &bash, "temprorary");
213 straight slh = slt;
214 slh.up(&sc);
215 plane pn = plane(point(0, 0, 0), vec(1, 0, 0));
216 return pn.cross(slh);
217}
218
219straight::straight(const point* pt, int qpt, int anum) // interpolates by xi2
220 {
221 pvecerror("straight::straight(const point* pt, int qpt, int anum) ");
222 check_econd11(qpt, < 2, mcerr);
223 check_econd21(anum, < 0 ||, >= 3, mcerr);
224
225 if (qpt == 2) {
226 *this = straight(pt[0], pt[1]);
227 return;
228 }
229 double* x = new double[qpt];
230 double* y = new double[qpt];
231 double* z = new double[qpt];
232 int n;
233 for (n = 0; n < qpt; n++) {
234 x[n] = pt[n].v.x;
235 y[n] = pt[n].v.y;
236 z[n] = pt[n].v.z;
237 }
238 point piv1;
239 if (anum == 0) {
240 linexi2 lcy(qpt, x, y);
241 linexi2 lcz(qpt, x, z);
242 piv = point(lcy.x_mean, lcy.line(lcy.x_mean), lcz.line(lcy.x_mean));
243 piv1 = point(lcy.x_mean + 1, lcy.line(lcy.x_mean + 1),
244 lcz.line(lcy.x_mean + 1));
245 } else if (anum == 1) {
246 linexi2 lcx(qpt, y, x);
247 linexi2 lcz(qpt, y, z);
248 piv = point(lcx.line(lcx.x_mean), lcx.x_mean, lcz.line(lcx.x_mean));
249 // lcx.x_mean = lcz.x_mean
250 piv1 = point(lcx.line(lcx.x_mean + 1), lcx.x_mean + 1,
251 lcz.line(lcx.x_mean + 1));
252 } else {
253 linexi2 lcx(qpt, z, x);
254 linexi2 lcy(qpt, z, y);
255 piv = point(lcx.line(lcx.x_mean), lcy.line(lcx.x_mean), lcx.x_mean);
256 piv1 = point(lcx.line(lcx.x_mean + 1), lcy.line(lcx.x_mean + 1),
257 lcx.x_mean + 1);
258 }
259 dir = unit_vec(piv1 - piv);
260
261 delete x;
262 delete y;
263 delete z;
264}
265
266straight::straight(const straight sl[4], point pt[2], vfloat precision) {
267 pvecerror("straight::straight(const straight sl[4], point pt[2], vfloat "
268 "precision)");
269 int i;
270 vfloat meandist;
271 point ptprev[2];
272 point ptcurr[2];
273 ptprev[0] = pt[0];
274 ptprev[1] = pt[1];
275 ptcurr[0] = pt[0];
276 ptcurr[1] = pt[1];
277 do {
278 meandist = 0;
279 for (i = 0; i < 2; i++) {
280 int is; // index of line to make plane
281 int ip; // index of point to make plane
282 int isc; // index of line to find point
283 if (i == 0) {
284 is = 0;
285 ip = 1;
286 isc = 1;
287 } else {
288 is = 3;
289 ip = 0;
290 isc = 2;
291 }
292 plane pn(sl[is], ptcurr[ip]);
293 ptcurr[i] = pn.cross(sl[isc]);
294 meandist += length2(ptcurr[i] - ptprev[i]);
295 mcout << " i=" << i << " ptprev[i]=" << ptprev[i]
296 << " ptcurr[i]=" << ptcurr[i] << '\n';
297 ptprev[i] = ptcurr[i];
298 }
299 meandist /= 2.0;
300 meandist = sqrt(meandist);
301 mcout << "meandist=" << meandist << '\n';
302 } while (meandist >= precision);
303 *this = straight(ptcurr[0], ptcurr[1]);
304}
305
306std::ostream& operator<<(std::ostream& file, const straight& s) {
307 Ifile << "straight (line):\n";
308 indn.n += 2;
309 file << s.piv << s.dir;
310 indn.n -= 2;
311 return file;
312}
313
314}
DoubleAc pow(const DoubleAc &f, double p)
Definition: DoubleAc.cpp:336
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:313
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:616
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
Definition: FunNameStack.h:428
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:366
point cross(const straight &sl) const
Definition: plane.cpp:77
point cross(const straight &sl, vfloat prec) const
Definition: straight.cpp:56
vfloat vecdistance(const straight &sl, int &type_of_cross, point pt[2]) const
Definition: straight.cpp:75
vec Gdir(void) const
Definition: straight.h:31
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:50
static absrefabsref::*[2] aref
Definition: straight.h:37
virtual void get_components(ActivePtr< absref_transmit > &aref_tran)
Definition: straight.cpp:23
Definition: vec.h:134
virtual void up(const abssyscoor *fasc)
Definition: vec.cpp:55
Definition: vec.h:397
double x_mean
Definition: linexi2.h:22
double line(double x)
Definition: linexi2.h:64
Definition: vec.h:477
vec v
Definition: vec.h:479
virtual void down(const abssyscoor *fasc)
Definition: vec.cpp:546
Definition: vec.h:248
vfloat y
Definition: vec.h:250
vfloat x
Definition: vec.h:250
vfloat z
Definition: vec.h:250
Definition: BGMesh.cpp:3
int apeq(const circumf &f1, const circumf &f2, vfloat prec)
Definition: circumf.cpp:45
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:22
int operator==(const circumf &f1, const circumf &f2)
Definition: circumf.cpp:36
indentation indn
Definition: prstream.cpp:13
#define mcout
Definition: prstream.h:133
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
vec dv0(0, 0, 0)
vfloat cos2vec(const vec &r1, const vec &r2)
Definition: vec.cpp:142
vfloat sin2vec(const vec &r1, const vec &r2)
Definition: vec.cpp:183
int vecerror
Definition: vec.cpp:31
#define pvecerror(string)
Definition: vec.h:52
double vfloat
Definition: vfloat.h:15
#define max_vfloat
Definition: vfloat.h:14