Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
polyline.cpp
Go to the documentation of this file.
2
3/*
4Copyright (c) 2000 Igor B. Smirnov
5
6The file can be used, copied, modified, and distributed
7according to the terms of GNU Lesser General Public License version 2.1
8as published by the Free Software Foundation,
9and provided that the above copyright notice, this permission notice,
10and notices about any modifications of the original text
11appear in all copies and in supporting documentation.
12The file is provided "as is" without express or implied warranty.
13*/
14
15namespace Heed {
16
17// **** polyline ****
18void polyline::get_components(ActivePtr<absref_transmit>& aref_tran) {
19 aref_tran.pass(new absref_transmit(qpt + qsl, aref));
20}
21
23 mfunname("polyline::polyline( polyline &pl)");
24 polyline_init(pl.pt, pl.qpt);
25}
27 mfunname("polyline::polyline(const polyline &pl)");
28 polyline_init(pl.pt, pl.qpt);
29}
30polyline::polyline(const point* fpt, int fqpt) {
31 mfunname("polyline::polyline(const point* fpt, int fqpt)");
32 polyline_init(fpt, fqpt);
33}
34polyline::polyline(const point& fpt1, const point& fpt2) {
35 // interval
36 mfunname("polyline::polyline(const point& fpt1, const point& fpt2)");
37 point fpt[2];
38 fpt[0] = fpt1;
39 fpt[1] = fpt2;
40 polyline_init(fpt, 2);
41}
42
44 mfunname("polyline& polyline::operator=(const polyline& fpl)");
46 polyline_init(fpl.pt, fpl.qpt);
47 return *this;
48}
49
50void polyline::polyline_init(const point* fpt, int fqpt) {
51 pvecerror("void polyline::polyline_init(const point* fpt, int fqpt)");
52 check_econd11(fqpt, < 0, mcerr)
53 if (fqpt >= 1) {
54 pt = new point[fqpt];
55 for (qpt = 0; qpt < fqpt; ++qpt)
56 pt[qpt] = fpt[qpt];
57 if (fqpt >= 2) {
58 sl = new straight[qpt - 1];
59 for (qsl = 0; qsl < qpt - 1; ++qsl) {
60 sl[qsl] = straight(pt[qsl], pt[qsl + 1]);
61 }
62 } else {
63 sl = NULL;
64 }
65 aref = new absref* [qpt + qsl];
66 for (int n = 0; n < qpt; ++n)
67 aref[n] = &pt[n];
68 for (int n = 0; n < qsl; ++n)
69 aref[n + qpt] = &sl[n];
70 } else {
71 qpt = 0;
72 qsl = 0;
73 pt = NULL;
74 sl = NULL;
75 aref = NULL;
76 }
77}
78
79int polyline::check_point_in(const point& fpt, vfloat prec) const {
80 pvecerror("int polyline::check_point_in(point& fpt, vfloat prec)");
81 for (int n = 0; n < qpt; ++n) {
82 if (apeq(pt[n], fpt, prec)) return 1;
83 }
84 for (int n = 0; n < qsl; ++n) {
85 if (sl[n].check_point_in(fpt, prec) == 1) {
86 vec v1 = fpt - pt[n];
87 vec v2 = fpt - pt[n + 1];
88 if (check_par(v1, v2, prec) == -1) {
89 // anti-parallel vectors, point inside borders
90 return 2;
91 }
92 }
93 }
94 return 0;
95}
96
97int polyline::cross(const straight& fsl, point* pc, int& qpc, polyline* pl,
98 int& qpl, vfloat prec) const {
99 pvecerror("void polyline::cross(const straight& fsl, ...)");
100 qpc = 0;
101 qpl = 0;
102 for (int n = 0; n < qsl; ++n) {
103 pc[qpc] = sl[n].cross(fsl, prec);
104 if (vecerror == 1 || vecerror == 2) {
105 // lines do not cross
106 vecerror = 0;
107 } else if (vecerror == 3) {
108 // the same straight line
109 pl[qpl++] = polyline(&(pt[n]), 2);
110 } else {
111 vec v1 = pc[qpc] - pt[n];
112 if (length(v1) < prec) {
113 qpc++;
114 } else {
115 vec v2 = pc[qpc] - pt[n + 1];
116 if (length(v2) < prec) {
117 qpc++;
118 } else if (check_par(v1, v2, prec) == -1) {
119 // anti-parallel vectors, point inside borders
120 qpc++;
121 }
122 }
123 }
124 }
125 if (qpc > 0 || qpl > 0) return 1;
126 return 0;
127}
128
130 pvecerror("vfloat polyline::dist_two_inter(polyline& pl)");
131 const polyline& pl1 = *this;
132 check_econd11(pl1.Gqpt(), != 2, mcerr);
133 check_econd11(pl2.Gqpt(), != 2, mcerr);
134 point cpt[2];
135 int type_of_cross;
136 vfloat sldist = pl1.Gsl(0).distance(pl2.Gsl(0), type_of_cross, cpt);
137 if (type_of_cross == 2 || type_of_cross == 3) return sldist;
138 if (pl1.check_point_in(cpt[0], prec) > 0 &&
139 pl2.check_point_in(cpt[1], prec) > 0)
140 return sldist;
141 vfloat mx = max_vfloat;
142 vfloat r;
143 if ((r = pl1.distance(pl2.Gpt(0))) < mx) mx = r;
144 if ((r = pl1.distance(pl2.Gpt(1))) < mx) mx = r;
145 if ((r = pl2.distance(pl1.Gpt(0))) < mx) mx = r;
146 if ((r = pl2.distance(pl1.Gpt(1))) < mx) mx = r;
147 return mx;
148}
149
150vfloat polyline::distance(const point& fpt) const {
151 pvecerror("vfloat polyline::distance(const point& fpt) const");
152 check_econd11(qsl, <= 0, mcerr);
153 vfloat sldist;
154 point cpt;
155 vfloat mx = max_vfloat;
156 int n;
157 for (n = 0; n < qsl; n++) {
158 sldist = sl[n].distance(fpt, cpt);
159 vec v1 = cpt - pt[n];
160 vec v2 = cpt - pt[n + 1];
161 if (check_par(v1, v2, 0.01) ==
162 -1) { // anti-parallel vectors, point inside borders
163 if (sldist < mx) mx = sldist;
164 } else {
165 if ((sldist = length(fpt - pt[n])) < mx) mx = sldist;
166 if ((sldist = length(fpt - pt[n + 1])) < mx) mx = sldist;
167 }
168 }
169 return mx;
170}
171
172vfloat polyline::distance(const point& fpt, point& fcpt) const {
173 pvecerror("vfloat polyline::distance(const point& fpt) const");
174 check_econd11(qsl, <= 0, mcerr);
175 vfloat sldist;
176 point cpt;
177 vfloat mx = max_vfloat;
178 int n;
179 for (n = 0; n < qsl; n++) {
180 sldist = sl[n].distance(fpt, cpt);
181 vec v1 = cpt - pt[n];
182 vec v2 = cpt - pt[n + 1];
183 if (check_par(v1, v2, 0.01) ==
184 -1) { // anti-parallel vectors, point inside borders
185 if (sldist < mx) {
186 mx = sldist;
187 fcpt = cpt;
188 }
189 } else {
190 if ((sldist = length(fpt - pt[n])) < mx) {
191 mx = sldist;
192 fcpt = pt[n];
193 }
194 if ((sldist = length(fpt - pt[n + 1])) < mx) {
195 mx = sldist;
196 fcpt = pt[n + 1];
197 }
198 }
199 }
200 return mx;
201}
202
203int cross4pllines(const polyline pl[4], vfloat precision, straight& sl,
204 point ptc[4][2]) {
205 pvecerror(
206 "int cross4pllines(const polyline pl[4], straight& sl, point ptc[4][2])");
207 int n;
208 straight slpl[4];
209 for (n = 0; n < 4; n++)
210 slpl[n] = pl[n].Gsl(0);
211 point pt[2];
212 pt[0] = (pl[1].Gpt(0).v + pl[1].Gpt(1).v) * 0.5;
213 pt[1] = (pl[2].Gpt(0).v + pl[2].Gpt(1).v) * 0.5;
214 sl = straight(slpl, pt, precision);
215 int type_of_cross;
216 for (n = 0; n < 4; n++) {
217 sl.distance(pl[n].Gsl(0), type_of_cross, ptc[n]);
218 // distance should be little, it need to find points
219 if (pl[n].check_point_in(ptc[n][1], precision) == 0) // check sides
220 return 0;
221 }
222 return 1;
223}
224
225std::ostream& operator<<(std::ostream& file, const polyline& p) {
226 int n;
227 Ifile << "polyline:\n";
228 indn.n += 2;
229 Ifile << "qpt=" << p.qpt << '\n';
230 for (n = 0; n < p.qpt; n++)
231 file << p.pt[n];
232 Ifile << "qsl=" << p.qsl << '\n';
233 for (n = 0; n < p.qsl; n++)
234 file << p.sl[n];
235 indn.n -= 2;
236 return file;
237}
238// **** polyline in plane ****
239
241
242void polyline_pl::get_components(ActivePtr<absref_transmit>& aref_tran) {
243 aref_tran.pass(new absref_transmit(1, &aref_pl, qpt + qsl, aref));
244}
245
247 mfunname("polyline_pl::polyline_pl( polyline& pl)");
248 if (pl.Gqsl() < 2) {
249 mcerr << "error in polyline_pl(polyline& pl): qsl=" << Gqsl();
250 spexit(mcerr);
251 }
253 pn = plane(pl.Gsl(0).Gpiv(), pl.Gsl(0).Gdir() || pl.Gsl(1).Gdir());
254}
255
257 mfunname("polyline_pl::polyline_pl(const polyline& pl");
258 if (pl.Gqsl() < 2) {
259 mcerr << "error in polyline_pl(polyline& pl): qsl=" << Gqsl();
260 spexit(mcerr);
261 }
263 pn = plane(pl.Gsl(0).Gpiv(), pl.Gsl(0).Gdir() || pl.Gsl(1).Gdir());
264}
265
267 mfunname("polyline_pl& polyline_pl::operator=(const polyline_pl& fpl)");
268 polyline_del();
269 polyline_init(fpl.pt, fpl.qpt);
270 pn = fpl.pn;
271 return *this;
272}
273
274std::ostream& operator<<(std::ostream& file, const polyline_pl& p) {
275 Ifile << "polyline_pl:\n";
276 indn.n += 2;
277 file << p.pn;
278 file << statcast(const polyline&, p);
279 indn.n -= 2;
280 return file;
281}
282
283// **** polygon (in plane) ****
284
285polygon::polygon(const straight* fsl, int fqsl, vfloat prec)
286 : polyline_pl(), s_convex(1) {
287 pvecerror("polygon::polygon(const straight* fsl, int fqsl)");
288 check_econd11a(fqsl, < 3, "fqsl cannot be less 3\n", mcerr);
289 int n, m;
290 // now check that either the piv's of lines are not equal to each other,
291 // or the dir's are not parallel.
292 // It does not prove that input data are corrent, but more
293 // explicit prove might take too much time.
294 for (n = 0; n < fqsl - 1; n++)
295 for (m = n + 1; m < fqsl; m++) {
296 if (fsl[n].Gpiv() == fsl[m].Gpiv())
297 if (check_par(fsl[n].Gdir(), fsl[m].Gdir(), 0) !=
298 0) //1 par, -1 antipar
299 {
300 mcerr << "error in polyline_init(straight* fsl, int fqsl):\n"
301 << "Parallel lines with the same pivot cannot form polygin\n";
302 for (int k = 0; k < fqsl; k++)
303 mcout << "n=" << k << " fsl[n]=" << fsl[k];
304 spexit(mcerr);
305 }
306 }
307 int qptl = fqsl + 1;
308 point* ptl = new point[qptl];
309 for (n = 1; n < fqsl; n++) {
310 ptl[n] = fsl[n - 1].cross(fsl[n], prec);
311 if (vecerror != 0) {
312 mcerr << "error in polygon::polygon(straight* fsl, int fqsl):\n"
313 << " straight lines are not crossed properly\n"
314 << "fsl[n-1]=" << fsl[n - 1] << "fsl[n]=" << fsl[n]
315 << "vecerror=" << vecerror << '\n';
316 spexit(mcerr);
317 }
318 }
319 ptl[0] = fsl[fqsl - 1].cross(fsl[0], prec);
320 if (vecerror != 0) {
321 mcerr << "error in polygon::polygon(straight* fsl, int fqsl):\n"
322 << " straight lines are not crossed properly\n"
323 << "fsl[fqsl-1]=" << fsl[fqsl - 1] << "fsl[0]=" << fsl[0]
324 << "vecerror=" << vecerror << '\n';
325 spexit(mcerr);
326 }
327 ptl[fqsl] = ptl[0];
328 plane pnl = plane(fsl[0].Gpiv(), fsl[0].Gdir() || fsl[1].Gdir());
329 polyline_pl pll(pnl, ptl, qptl);
330 *this = polygon(pll, 1);
331
332 delete ptl;
333
334}
335
337 mfunname("polygon& polygon::operator=(const polygon& fpl)");
338 polyline_del();
339 polyline_init(fpl.pt, fpl.qpt);
340 pn = fpl.pn;
341 s_convex = fpl.s_convex;
342 return *this;
343}
344
345int polygon::check_point_in(const point& fpt, vfloat prec) const {
346 pvecerror("int polygon::check_point_in(point& fpt)");
347 int i;
348 if ((i = polyline::check_point_in(fpt, prec)) > 0) {
349 return i;
350 }
351 if ((i = pn.check_point_in(fpt, prec)) == 0) {
352 return i;
353 }
354 /* The idea of the following algorithm is circulating around the polygon
355 and finding of two points, one gives the minimum angle relatively
356 some(any) direction, another gives the maximal angle.
357 The point resides inside polygon if they are the same at the end of
358 circulation.
359 */
360 point endpt[2];
361 endpt[0] = pt[0]; // which is really first or last, depends on pn.Gdir()
362 endpt[1] = pt[0];
363 double totang = 0;
364 double ang, ang2;
365 //int s_start[2];
366 //s_start[0]=0;
367 //s_start[1]=0;
368 int n;
369 for (n = 0; n < qpt - 1; n++) {
370 ang2 = 0.0;
371 ang = ang2projvec((pt[n] - fpt), (pt[n + 1] - fpt), pn.Gdir());
372 if (ang <= M_PI) {
373 // go to opposite direction of clock
374 totang += ang;
375 } else {
376 ang2 = 2 * M_PI - ang;
377 totang -= ang2;
378 }
379 }
380
381 if (fabs(totang) > 6.0) return 3;
382 return 0;
383}
384
385point polygon::cross(const straight& fsl, vfloat prec) const {
386 pvecerror("point polygon::cross(straight& fsl)");
387 point cpt = pn.cross(fsl); // does it cross the plane
388 //mcout<<"polygon::cross: cpt="<<cpt;
389 //mcout<<"vecerror="<<vecerror<<'\n';
390 if (vecerror != 0) return cpt;
391 int s = check_point_in(cpt, prec);
392 if (s > 0)
393 return cpt;
394 else {
395 vecerror = 1;
396 return cpt;
397 }
398}
399int polygon::range(const point& fpt, const vec& dir, vfloat& rng, point& fptenr,
400 vfloat prec) const {
401 pvecerror("int polygon::range(const point& fpt, const vec& dir, vfloat& rng, "
402 " point &fptenr)");
403 straight stl(fpt, dir);
404 point pnt = cross(stl, prec);
405 if (vecerror != 0) {
406 vecerror = 0;
407 return 0;
408 }
409 vec dif = pnt - fpt;
410 const int i = check_par(dif, dir, prec);
411 if (i == 1) {
412 rng = length(dif);
413 fptenr = pnt;
414 return 1;
415 } else
416 return 0;
417}
418
419std::ostream& operator<<(std::ostream& file, const polygon& p) {
420 Ifile << "polygon:\n";
421 indn.n += 2;
422 Ifile << "s_convex=" << p.s_convex << '\n';
423 file << statcast(const polyline_pl&, p);
424 indn.n -= 2;
425 return file;
426}
427// *** rectangle ***
431};
432
433void rectangle::get_components(ActivePtr<absref_transmit>& aref_tran) {
434 aref_tran.pass(new absref_transmit(4, aref_rct, qpt + qsl, aref));
435}
436
437rectangle::rectangle(const point& fpiv, vec fdir[2], vfloat fdim[2],
438 vfloat prec) {
439 pvecerror("rectangle::rectangle(point fpiv, vec fdir[2], vfloat fdim[2], "
440 "vfloat prec)");
441 if (check_perp(fdir[0], fdir[1], prec) != 1) {
442 mcerr << "rectangle::rectangle(point fpiv, vec fdir[2], vfloat fdim[2]):\n"
443 << " error: sides are not perpendicular\n";
444 // There is stil no reason found in applications for sides to be
445 // necessary perpendicular. The only reason in name of this class
446 // choosen occasionly. To my knowledge it denotes a figure with
447 // perpendicular sides.
448 mcerr << "fdir[2](directions of sides):\n" << fdir[0] << fdir[1];
449 spexit(mcerr);
450 }
451 if (fdim[0] <= 0 || fdim[1] <= 0) {
452 mcerr << "rectangle::rectangle(point fpiv, vec fdir[2], vfloat fdim[2]):\n"
453 << " error: fdim[0] <=0 || fdim[1] <=0\n";
454 mcerr << "fdim (dimensions):" << fdim[0] << ' ' << fdim[1] << '\n';
455 mcerr << "fdir[2](directions of sides):\n" << fdir[0] << fdir[1];
456 spexit(mcerr);
457 }
458 piv = fpiv;
459 dir1 = unit_vec(fdir[0]);
460 dir2 = unit_vec(fdir[1]);
461 dim[0] = fdim[0];
462 dim[1] = fdim[1];
463 //mcout<<"piv:\n"<<piv;
464 //mcout<<"dir[2](directions of sides):\n"<<dir[0]<<dir[1];
465 //mcout<<"dim (dimensions):"<<dim[0]<<' '<<dim[1]<<'\n';
466 straight slh[4];
467 slh[0] = straight(piv + dir1 * dim[0] / 2.0, dir2);
468 slh[1] = straight(piv + dir2 * dim[1] / 2.0, -dir1);
469 slh[2] = straight(piv - dir1 * dim[0] / 2.0, -dir2);
470 slh[3] = straight(piv - dir2 * dim[1] / 2.0, dir1);
471 polygon::operator=(polygon(slh, 4, prec));
472}
473
474std::ostream& operator<<(std::ostream& file, const rectangle& f) {
475 Ifile << "rectangle:\n";
476 indn.n += 2;
477 Ifile << "piv:\n" << f.piv;
478 Ifile << "dir1,2(directions of sides):\n" << f.dir1 << f.dir2;
479 Ifile << "dim (dimensions):" << f.dim[0] << ' ' << f.dim[1] << '\n';
480 file << statcast(const polygon&, f);
481 indn.n -= 2;
482 return file;
483}
484
485// **** special quadrangle **** for cathode strip shamber
486
491
492void spquadr::get_components(ActivePtr<absref_transmit>& aref_tran) {
493 aref_tran.pass(new absref_transmit(4, aref_sp, qpt + qsl, aref));
494}
495
497 vec axis = unit_vec(dir1 || dir2);
498 vec rv = dir1;
499 rv.turn(axis, angle);
500 rv = rv * rad;
501 point rpt = piv + rv;
502 return rpt;
503}
504
506 : polygon(sq),
507 piv(sq.piv),
508 dir1(sq.dir1),
509 dir2(sq.dir2),
510 awidth(sq.awidth) {
511 ;
512}
514 : polygon(sq),
515 piv(sq.piv),
516 dir1(sq.dir1),
517 dir2(sq.dir2),
518 awidth(sq.awidth) {
519 ;
520}
521
522spquadr::spquadr(const point& fpiv, const straight& sl1, const straight& sl2,
523 const vec& fdir1, const vec& fdir2, vfloat prec)
524 : polygon(), piv(fpiv), dir1(unit_vec(fdir1)), dir2(unit_vec(fdir2)) {
525 straight slh[4];
526 slh[0] = sl1;
527 slh[1] = straight(piv, dir1);
528 slh[2] = sl2;
529 slh[3] = straight(piv, dir2);
530 polygon plgn = polygon(slh, 4, prec);
531 *this = spquadr(fpiv, sl1, sl2, fdir1, fdir2, plgn);
532}
533
534std::ostream& operator<<(std::ostream& file, const spquadr& p) {
535 Ifile << "spquadr:\n";
536 indn.n += 2;
537 Ifile << "piv:";
538 file << p.piv;
539 Ifile << "dir1:\n";
540 file << p.dir1;
541 Ifile << "dir2:\n";
542 file << p.dir2;
543 Ifile << " awidth=" << p.awidth << '\n';
544 file << statcast(const polygon&, p);
545 indn.n -= 2;
546 return file;
547}
548
549}
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:616
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:366
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:395
#define spexit(stream)
Definition: FunNameStack.h:536
#define mfunname(string)
Definition: FunNameStack.h:67
point cross(const straight &sl) const
Definition: plane.cpp:77
vec Gdir(void) const
Definition: plane.h:34
int check_point_in(const point &fp, vfloat prec) const
Definition: plane.cpp:70
int range(const point &fpt, const vec &dir, vfloat &rng, point &fptenr, vfloat prec) const
Definition: polyline.cpp:399
polygon(void)
Definition: polyline.h:169
int check_point_in(const point &fpt, vfloat prec) const
Definition: polyline.cpp:345
polygon & operator=(const polygon &fpl)
Definition: polyline.cpp:336
virtual void get_components(ActivePtr< absref_transmit > &aref_tran)
Definition: polyline.cpp:242
polyline_pl & operator=(const polyline_pl &fpl)
Definition: polyline.cpp:266
static absrefabsref::* aref_pl
Definition: polyline.h:134
polyline & operator=(const polyline &fpl)
Definition: polyline.cpp:43
int Gqsl(void) const
Definition: polyline.h:44
point * pt
Definition: polyline.h:29
straight * sl
Definition: polyline.h:31
point Gpt(int n) const
Definition: polyline.h:35
void polyline_init(const point *fpt, int fqpt)
Definition: polyline.cpp:50
straight Gsl(int n) const
Definition: polyline.h:45
vfloat dist_two_inter(polyline &pl, vfloat prec) const
Definition: polyline.cpp:129
virtual void get_components(ActivePtr< absref_transmit > &aref_tran)
Definition: polyline.cpp:18
absref ** aref
Definition: polyline.h:55
int Gqpt(void) const
Definition: polyline.h:34
friend int plane::cross(const polyline &pll, point *crpt, int &qcrpt, polyline *crpll, int &qcrpll, vfloat prec) const
int check_point_in(const point &fpt, vfloat prec) const
Definition: polyline.cpp:79
vfloat distance(const point &fpt) const
Definition: polyline.cpp:150
void polyline_del(void)
Definition: polyline.h:81
polyline(void)
Definition: polyline.h:97
rectangle(void)
Definition: polyline.h:198
static absrefabsref::*[4] aref_rct
Definition: polyline.h:203
vfloat dim[2]
Definition: polyline.h:197
virtual void get_components(ActivePtr< absref_transmit > &aref_tran)
Definition: polyline.cpp:433
virtual void get_components(ActivePtr< absref_transmit > &aref_tran)
Definition: polyline.cpp:492
vfloat awidth
Definition: polyline.h:215
point pt_angle_rad(vfloat rad, vfloat angle)
Definition: polyline.cpp:496
static absrefabsref::*[4] aref_sp
Definition: polyline.h:223
spquadr(void)
Definition: polyline.h:251
point cross(const straight &sl, vfloat prec) const
Definition: straight.cpp:56
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
point Gpiv(void) const
Definition: straight.h:30
Definition: vec.h:134
Definition: vec.h:477
vec v
Definition: vec.h:479
Definition: vec.h:248
void turn(const vec &dir, vfloat angle)
Definition: vec.cpp:298
#define statcast(type, name)
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 cross4pllines(const polyline pl[4], vfloat precision, straight &sl, point ptc[4][2])
Definition: polyline.cpp:203
indentation indn
Definition: prstream.cpp:13
#define mcout
Definition: prstream.h:133
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
vfloat ang2projvec(const vec &r1, const vec &r2, const vec &normal)
Definition: vec.cpp:212
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