Garfield++ 4.0
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 line ****
19
20absref absref::* straight::aref[2] = {(absref absref::*)&straight::piv,
21 (absref absref::*)&straight::dir};
22
24 return 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("bool apeq(const straight &sl1, const straight &sl2, vfloat prec)");
42 if (check_par(sl1.dir, sl2.dir, prec) == 0) return false;
43 if (apeq(sl1.piv, sl2.piv, prec)) return true;
44 return (sl1.check_point_in(sl2.piv, prec) == 1);
45}
46
47int straight::check_point_in(const point& fp, vfloat prec) const {
48 pvecerror("int straight::check_point_in(point fp, vfloat prec)");
49 vfloat f = distance(fp);
50 if (f <= prec) return 1;
51 return 0;
52}
53point straight::cross(const straight& sl, vfloat prec) const {
54 pvecerror("point straight::cross(straight& sl, vfloat prec)");
55 point pt[2];
56 int type_of_cross;
57 vfloat f = vecdistance(sl, type_of_cross, &pt[0]);
58 point ptt(dv0);
59 if (type_of_cross == 2 || type_of_cross == 3) {
60 vecerror = type_of_cross;
61 return ptt;
62 }
63 if (fabs(f) <= prec) {
64 vecerror = 0;
65 return pt[0];
66 } else {
67 vecerror = 1;
68 return ptt;
69 }
70}
71
72vfloat straight::vecdistance(const straight& sl, int& type_of_cross,
73 point pt[2]) const {
75 "vfloat straight::vecdistance(const straight& sl, int& type_of_cross, "
76 "point pt[2])");
77 pt[0] = point();
78 pt[1] = point();
79 type_of_cross = 0;
80 straight s1, s2;
81 s1 = *this;
82 s2 = sl; // s2 may be changed
83 if (s1.piv == s2.piv) {
84 // the same origin point
85 if (check_par(s1.dir, s2.dir, 0.0) != 0) {
86 // parallel or anti-parallel
87 type_of_cross = 3;
88 return 0.0; // coincidence
89 } else { // crossed in piv;
90 return 0.0;
91 }
92 }
93 if (check_par(s1.dir, s2.dir, 0.0) != 0) {
94 // parallel or anti-parallel
95 if (s1.check_point_in(s2.piv, 0.0) == 1) {
96 // point in => the same line
97 type_of_cross = 3;
98 return 0.0;
99 } else {
100 // not crossed
101 type_of_cross = 2; // different parallel lines
102 return s1.distance(s2.piv);
103 }
104 } // now we know that the lines are not parallel
105
106 basis bs(s1.dir, s2.dir, "local");
107 // ez is parallel to s1.dir, ez=unit_vec(s1.dir)
108 // ey is perpendicular to plane which have s1.dir and s2.dir,
109 // ey=unit_vec(ez||s2.dir)
110 // ex is vector product of ey and ez, ex=ey||ez
111 // mcout<<bs;
112 fixsyscoor scl(&s1.piv, &bs, "local");
113 // mcout<<scl;
114 plane pn(point(0, 0, 0), vec(1, 0, 0)); // assumed to be in scl
115 // This plane is defined by
116 // mcout<<pn;
117 s2.up(&scl);
118 // mcout<<s2;
119 pt[1] = pn.cross(s2);
120 // mcout<<pt;
121 if (pt[1].v.y == 0) {
122 pt[1].down(&scl);
123 pt[0] = pt[1];
124 return 0.0;
125 } else {
126 type_of_cross = 1;
127 vfloat d = pt[1].v.y;
128 pt[0] = pt[1];
129 pt[0].v.y = 0;
130 pt[0].down(&scl);
131 pt[1].down(&scl);
132 return d;
133 }
134}
135
136vfloat straight::distance(const straight& sl, int& type_of_cross,
137 point pt[2]) const {
138 return fabs(vecdistance(sl, type_of_cross, pt));
139}
140
141straight::straight(straight* sl, int qsl, const straight& sl_start, int anum,
142 vfloat precision, vfloat* dist, // may be negative
143 point (*pt)[2], vfloat& mean2dist) {
144 pvecerror("void straight::straight(straight* sl, int qsl,...");
145 check_econd11(qsl, < 4, mcerr);
146 straight sl_finish = sl_start;
147 int n;
148 mean2dist = max_vfloat;
149 vfloat mean2dist_prev = max_vfloat;
150 int type_of_cross;
151 point* ptf = new point[qsl];
152 // mcout<<"straight::straight: starting, qsl="<<qsl
153 // <<"\nsl_start="<<sl_start<<'\n';
154 do {
155 mean2dist_prev = mean2dist;
156 mean2dist = 0;
157 *this = sl_finish;
158 for (n = 0; n < qsl; n++) {
159 dist[n] = vecdistance(sl[n], type_of_cross, pt[n]);
160 mean2dist += pow(dist[n], 2);
161 check_econd11(type_of_cross, > 1, mcerr);
162 ptf[n] = pt[n][1];
163 }
164 mean2dist /= qsl;
165 if (mean2dist > 0) mean2dist = sqrt(mean2dist);
166 sl_finish = straight(ptf, qsl, anum);
167 // mcout<<"straight::straight: mean2dist_prev="<<mean2dist_prev
168 // <<" mean2dist="<<mean2dist<<'\n';
169 // for( n=0; n<qsl; n++)
170 //{
171 // mcout<<"pt[n][0]="<<pt[n][0]<<'\n';
172 // mcout<<"pt[n][1]="<<pt[n][1]<<'\n';
173 //}
174 } while (mean2dist_prev < mean2dist ||
175 (mean2dist != 0 && mean2dist_prev - mean2dist > precision));
176 delete[] ptf;
177}
178
179vfloat straight::distance(const point& fpt) const {
180 pvecerror("vfloat straight::distance(point& fpt)");
181 if (fpt == piv) return 0.0;
182 vec v = fpt - piv;
183 return v.length() * sin2vec(dir, v); // should be positive
184}
185
186vfloat straight::distance(const point& fpt, point& fcpt) const {
187 pvecerror("vfloat straight::distance(point& fpt, point& fcpt)");
188 if (fpt == piv) {
189 fcpt = piv;
190 return 0.0;
191 }
192 vec v = fpt - piv;
193 vfloat len = v.length();
194 fcpt = piv + len * cos2vec(dir, v) * dir;
195 return v.length() * sin2vec(dir, v);
196}
197
198point straight::vecdistance(const vec normal, const straight& slt) {
199 pvecerror(
200 "vfloat straight::vecdistance(const vec normal, const straight& slt)");
201 if (check_perp(normal, slt.Gdir(), 0.0) == 1) {
202 // if it is perp.
203 mcout << "straight::vecdistance: normal=" << normal
204 << " slt.Gdir()=" << slt.Gdir();
205 vecerror = 1;
206 return point(0, 0, 0);
207 }
208 basis bash(dir, normal, "temprorary");
209 fixsyscoor sc(&piv, &bash, "temprorary");
210 straight slh = slt;
211 slh.up(&sc);
212 plane pn = plane(point(0, 0, 0), vec(1, 0, 0));
213 return pn.cross(slh);
214}
215
216straight::straight(const point* pt, int qpt, int anum) {
217 // interpolates by xi2
218 pvecerror("straight::straight(const point* pt, int qpt, int anum) ");
219 check_econd11(qpt, < 2, mcerr);
220 check_econd21(anum, < 0 ||, >= 3, mcerr);
221
222 if (qpt == 2) {
223 *this = straight(pt[0], pt[1]);
224 return;
225 }
226 double* x = new double[qpt];
227 double* y = new double[qpt];
228 double* z = new double[qpt];
229 for (int n = 0; n < qpt; n++) {
230 x[n] = pt[n].v.x;
231 y[n] = pt[n].v.y;
232 z[n] = pt[n].v.z;
233 }
234 point piv1;
235 if (anum == 0) {
236 linexi2 lcy(qpt, x, y);
237 linexi2 lcz(qpt, x, z);
238 piv = point(lcy.x_mean, lcy.line(lcy.x_mean), lcz.line(lcy.x_mean));
239 piv1 = point(lcy.x_mean + 1, lcy.line(lcy.x_mean + 1),
240 lcz.line(lcy.x_mean + 1));
241 } else if (anum == 1) {
242 linexi2 lcx(qpt, y, x);
243 linexi2 lcz(qpt, y, z);
244 piv = point(lcx.line(lcx.x_mean), lcx.x_mean, lcz.line(lcx.x_mean));
245 // lcx.x_mean = lcz.x_mean
246 piv1 = point(lcx.line(lcx.x_mean + 1), lcx.x_mean + 1,
247 lcz.line(lcx.x_mean + 1));
248 } else {
249 linexi2 lcx(qpt, z, x);
250 linexi2 lcy(qpt, z, y);
251 piv = point(lcx.line(lcx.x_mean), lcy.line(lcx.x_mean), lcx.x_mean);
252 piv1 = point(lcx.line(lcx.x_mean + 1), lcy.line(lcx.x_mean + 1),
253 lcx.x_mean + 1);
254 }
255 dir = unit_vec(piv1 - piv);
256
257 delete[] x;
258 delete[] y;
259 delete[] z;
260}
261
262straight::straight(const straight sl[4], point pt[2], vfloat precision) {
263 pvecerror(
264 "straight::straight(const straight sl[4], point pt[2], vfloat prec");
265 int i;
266 vfloat meandist;
267 point ptprev[2];
268 point ptcurr[2];
269 ptprev[0] = pt[0];
270 ptprev[1] = pt[1];
271 ptcurr[0] = pt[0];
272 ptcurr[1] = pt[1];
273 do {
274 meandist = 0;
275 for (i = 0; i < 2; i++) {
276 int is; // index of line to make plane
277 int ip; // index of point to make plane
278 int isc; // index of line to find point
279 if (i == 0) {
280 is = 0;
281 ip = 1;
282 isc = 1;
283 } else {
284 is = 3;
285 ip = 0;
286 isc = 2;
287 }
288 plane pn(sl[is], ptcurr[ip]);
289 ptcurr[i] = pn.cross(sl[isc]);
290 meandist += (ptcurr[i] - ptprev[i]).length2();
291 mcout << " i=" << i << " ptprev[i]=" << ptprev[i]
292 << " ptcurr[i]=" << ptcurr[i] << '\n';
293 ptprev[i] = ptcurr[i];
294 }
295 meandist /= 2.0;
296 meandist = sqrt(meandist);
297 mcout << "meandist=" << meandist << '\n';
298 } while (meandist >= precision);
299 *this = straight(ptcurr[0], ptcurr[1]);
300}
301
302std::ostream& operator<<(std::ostream& file, const straight& s) {
303 Ifile << "straight (line):\n";
304 indn.n += 2;
305 file << s.piv << s.dir;
306 indn.n -= 2;
307 return file;
308}
309}
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
Definition: FunNameStack.h:191
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
virtual void up(const abssyscoor *fasc)
Convert numbering representation of objects to new system.
Definition: vec.cpp:48
Basis.
Definition: vec.h:313
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:75
Point.
Definition: vec.h:368
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
Straight line, as combination of vector and point.
Definition: straight.h:24
point cross(const straight &sl, vfloat prec) const
Definition: straight.cpp:53
point piv
Origin point, pivot.
Definition: straight.h:27
vfloat vecdistance(const straight &sl, int &type_of_cross, point pt[2]) const
Shortest distance between two lines, may be negative.
Definition: straight.cpp:72
vec Gdir() const
Definition: straight.h:33
vfloat distance(const straight &sl, int &type_of_cross, point pt[2]) const
Definition: straight.cpp:136
int check_point_in(const point &fp, vfloat prec) const
Definition: straight.cpp:47
virtual absref_transmit get_components() override
Definition: straight.cpp:23
vec dir
Direction, unit vector.
Definition: straight.h:29
static absref absref::* aref[2]
Definition: straight.h:37
Definition: vec.h:179
vfloat x
Definition: vec.h:192
vfloat length() const
Definition: vec.h:196
vfloat z
Definition: vec.h:194
vfloat y
Definition: vec.h:193
Definition: BGMesh.cpp:6
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:37
DoubleAc pow(const DoubleAc &f, double p)
Definition: DoubleAc.cpp:337
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
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:195
#define mcerr
Definition: prstream.h:128
#define pvecerror(string)
Definition: vec.h:28