Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/geom3d.cpp
3206 views
1
#include <algorithm>
2
#include <mystdlib.h>
3
4
#include <myadt.hpp>
5
#include <gprim.hpp>
6
7
namespace netgen
8
{
9
ostream & operator<<(ostream & s, const Point3d & p)
10
{
11
return s << "(" << p.x[0] << ", " << p.x[1] << ", " << p.x[2] << ")";
12
}
13
14
ostream & operator<<(ostream & s, const Vec3d & v)
15
{
16
return s << "(" << v.x[0] << ", " << v.x[1] << ", " << v.x[2] << ")";
17
}
18
19
double Angle (const Vec3d & v1, const Vec3d & v2)
20
{
21
double co = (v1 * v2) / (v1.Length() * v2.Length());
22
if (co > 1) co = 1;
23
if (co < -1) co = -1;
24
return acos ( co );
25
}
26
27
28
void Vec3d :: GetNormal (Vec3d & n) const
29
{
30
if (fabs (X()) > fabs (Z()))
31
{
32
n.X() = -Y();
33
n.Y() = X();
34
n.Z() = 0;
35
}
36
else
37
{
38
n.X() = 0;
39
n.Y() = Z();
40
n.Z() = -Y();
41
}
42
double len = n.Length();
43
if (len == 0)
44
{
45
n.X() = 1;
46
n.Y() = n.Z() = 0;
47
}
48
else
49
n /= len;
50
}
51
52
/*
53
ostream & operator<<(ostream & s, const ROTDenseMatrix3D & r)
54
{
55
return s << "{ (" << r.txx << ", " << r.txy << ", " << r.txz << ") , ("
56
<< r.tyx << ", " << r.tyy << ", " << r.tyz << ") , ("
57
<< r.tzx << ", " << r.tzy << ", " << r.tzz << ") }";
58
}
59
*/
60
61
/*
62
Vec3d operator- (const Point3d & p1, const Point3d & p2)
63
{
64
return Vec3d (p1.X() - p2.X(), p1.Y() - p2.Y(),p1.Z() - p2.Z());
65
}
66
67
Point3d operator- (const Point3d & p1, const Vec3d & v)
68
{
69
return Point3d (p1.X() - v.X(), p1.Y() - v.Y(),p1.Z() - v.Z());
70
}
71
72
Point3d operator+ (const Point3d & p1, const Vec3d & v)
73
{
74
return Point3d (p1.X() + v.X(), p1.Y() + v.Y(),p1.Z() + v.Z());
75
}
76
77
Vec3d operator- (const Vec3d & v1, const Vec3d & v2)
78
{
79
return Vec3d (v1.X() - v2.X(), v1.Y() - v2.Y(),v1.Z() - v2.Z());
80
}
81
82
Vec3d operator+ (const Vec3d & v1, const Vec3d & v2)
83
{
84
return Vec3d (v1.X() + v2.X(), v1.Y() + v2.Y(),v1.Z() + v2.Z());
85
}
86
87
Vec3d operator* (double scal, const Vec3d & v)
88
{
89
return Vec3d (scal * v.X(), scal * v.Y(), scal * v.Z());
90
}
91
*/
92
/*
93
double operator* (const Vec3d & v1, const Vec3d & v2)
94
{
95
return v1.X() * v2.X() + v1.Y() * v2.Y() + v1.Z() * v2.Z();
96
}
97
98
double Cross (const Vec3d & v1, const Vec3d & v2)
99
{
100
return v1.X() * v2.Y() - v1.Y() * v2.X();
101
}
102
*/
103
104
/*
105
void ROTDenseMatrix3D :: CalcRotMat(double ag, double bg, double lg, double size2, Vec3d r)
106
{
107
size = size2;
108
txx=size * ( cos(bg) * cos(lg) );
109
txy=size * ( cos(bg) * sin(lg) );
110
txz=size * (-sin(bg) );
111
112
tyx=size * ( sin(ag) * sin(bg) * cos(lg) - cos(ag) * sin(lg) );
113
tyy=size * ( sin(ag) * sin(bg) * sin(lg) + cos(ag) * cos(lg) );
114
tyz=size * ( sin(ag) * cos(bg) );
115
116
tzx=size * ( cos(ag) * sin(bg) * cos(lg) + sin(ag) * sin(lg) );
117
tzy=size * ( cos(ag) * sin(bg) * sin(lg) - sin(ag) * cos(lg) );
118
tzz=size * ( cos(ag) * cos(bg) );
119
120
deltaR=r;
121
}
122
ROTDenseMatrix3D :: ROTDenseMatrix3D(double ag, double bg, double lg, double size2, Vec3d r)
123
{CalcRotMat(ag, bg, lg, size2, r); }
124
125
ROTDenseMatrix3D :: ROTDenseMatrix3D(Vec3d rot2)
126
{
127
Vec3d r2(0,0,0);
128
CalcRotMat(rot2.X(), rot2.Y(), rot2.Z(), 1, r2);
129
}
130
131
ROTDenseMatrix3D ROTDenseMatrix3D :: INV()
132
{
133
ROTDenseMatrix3D rinv(txx/sqr(size),tyx/sqr(size),tzx/sqr(size),
134
txy/sqr(size),tyy/sqr(size),tzy/sqr(size),
135
txz/sqr(size),tyz/sqr(size),tzz/sqr(size),
136
1/size,deltaR);
137
return rinv;
138
}
139
140
Vec3d operator* (const ROTDenseMatrix3D & r, const Vec3d & v)
141
{
142
return Vec3d (r.XX() * v.X() + r.XY() * v.Y() + r.XZ() * v.Z(),
143
r.YX() * v.X() + r.YY() * v.Y() + r.YZ() * v.Z(),
144
r.ZX() * v.X() + r.ZY() * v.Y() + r.ZZ() * v.Z() );
145
}
146
147
Point3d operator* (const ROTDenseMatrix3D & r, const Point3d & p)
148
{
149
return Point3d (r.XX() * p.X() + r.XY() * p.Y() + r.XZ() * p.Z(),
150
r.YX() * p.X() + r.YY() * p.Y() + r.YZ() * p.Z(),
151
r.ZX() * p.X() + r.ZY() * p.Y() + r.ZZ() * p.Z() );
152
}
153
*/
154
155
156
157
158
159
160
161
Box3d :: Box3d ( double aminx, double amaxx,
162
double aminy, double amaxy,
163
double aminz, double amaxz )
164
{
165
minx[0] = aminx; maxx[0] = amaxx;
166
minx[1] = aminy; maxx[1] = amaxy;
167
minx[2] = aminz; maxx[2] = amaxz;
168
}
169
170
Box3d :: Box3d ( const Box3d & b2 )
171
{
172
for (int i = 0; i < 3; i++)
173
{
174
minx[i] = b2.minx[i];
175
maxx[i] = b2.maxx[i];
176
}
177
}
178
179
Box3d :: Box3d ( const Box<3> & b2 )
180
{
181
for (int i = 0; i < 3; i++)
182
{
183
minx[i] = b2.PMin()(i);
184
maxx[i] = b2.PMax()(i);
185
}
186
}
187
188
189
/*
190
int Box3d :: Intersect (const Box3d & box2) const
191
{
192
int i;
193
for (i = 0; i <= 2; i++)
194
if (minx[i] > box2.maxx[i] || maxx[i] < box2.minx[i])
195
return 0;
196
return 1;
197
}
198
*/
199
200
/*
201
void Box3d :: SetPoint (const Point3d & p)
202
{
203
minx[0] = maxx[0] = p.X();
204
minx[1] = maxx[1] = p.Y();
205
minx[2] = maxx[2] = p.Z();
206
}
207
208
void Box3d :: AddPoint (const Point3d & p)
209
{
210
if (p.X() < minx[0]) minx[0] = p.X();
211
if (p.X() > maxx[0]) maxx[0] = p.X();
212
if (p.Y() < minx[1]) minx[1] = p.Y();
213
if (p.Y() > maxx[1]) maxx[1] = p.Y();
214
if (p.Z() < minx[2]) minx[2] = p.Z();
215
if (p.Z() > maxx[2]) maxx[2] = p.Z();
216
}
217
*/
218
219
void Box3d :: GetPointNr (int i, Point3d & point) const
220
{
221
i--;
222
point.X() = (i & 1) ? maxx[0] : minx[0];
223
point.Y() = (i & 2) ? maxx[1] : minx[1];
224
point.Z() = (i & 4) ? maxx[2] : minx[2];
225
}
226
227
228
void Box3d :: Increase (double d)
229
{
230
for (int i = 0; i <= 2; i++)
231
{
232
minx[i] -= d;
233
maxx[i] += d;
234
}
235
}
236
237
void Box3d :: IncreaseRel (double /* rel */)
238
{
239
for (int i = 0; i <= 2; i++)
240
{
241
double d = 0.5 * (maxx[i] - minx[i]);
242
minx[i] -= d;
243
maxx[i] += d;
244
}
245
}
246
247
248
Box3d :: Box3d (const Point3d& p1, const Point3d& p2)
249
{
250
minx[0] = min2 (p1.X(), p2.X());
251
minx[1] = min2 (p1.Y(), p2.Y());
252
minx[2] = min2 (p1.Z(), p2.Z());
253
maxx[0] = max2 (p1.X(), p2.X());
254
maxx[1] = max2 (p1.Y(), p2.Y());
255
maxx[2] = max2 (p1.Z(), p2.Z());
256
}
257
258
const Box3d& Box3d :: operator+=(const Box3d& b)
259
{
260
minx[0] = min2 (minx[0], b.minx[0]);
261
minx[1] = min2 (minx[1], b.minx[1]);
262
minx[2] = min2 (minx[2], b.minx[2]);
263
maxx[0] = max2 (maxx[0], b.maxx[0]);
264
maxx[1] = max2 (maxx[1], b.maxx[1]);
265
maxx[2] = max2 (maxx[2], b.maxx[2]);
266
267
return *this;
268
}
269
270
Point3d Box3d :: MaxCoords() const
271
{
272
return Point3d(maxx[0], maxx[1], maxx[2]);
273
}
274
275
Point3d Box3d :: MinCoords() const
276
{
277
return Point3d(minx[0], minx[1], minx[2]);
278
}
279
280
/*
281
void Box3d :: CreateNegMinMaxBox()
282
{
283
minx[0] = MAXDOUBLE;
284
minx[1] = MAXDOUBLE;
285
minx[2] = MAXDOUBLE;
286
maxx[0] = MINDOUBLE;
287
maxx[1] = MINDOUBLE;
288
maxx[2] = MINDOUBLE;
289
290
}
291
*/
292
293
void Box3d :: WriteData(ofstream& fout) const
294
{
295
for(int i = 0; i < 3; i++)
296
{
297
fout << minx[i] << " " << maxx[i] << " ";
298
}
299
fout << "\n";
300
}
301
302
void Box3d :: ReadData(ifstream& fin)
303
{
304
for(int i = 0; i < 3; i++)
305
{
306
fin >> minx[i];
307
fin >> maxx[i];
308
}
309
}
310
311
312
313
314
Box3dSphere :: Box3dSphere ( double aminx, double amaxx,
315
double aminy, double amaxy,
316
double aminz, double amaxz )
317
: Box3d (aminx, amaxx, aminy, amaxy, aminz, amaxz)
318
{
319
CalcDiamCenter ();
320
}
321
322
323
void Box3dSphere :: CalcDiamCenter ()
324
{
325
diam = sqrt( sqr (maxx[0] - minx[0]) +
326
sqr (maxx[1] - minx[1]) +
327
sqr (maxx[2] - minx[2]));
328
329
c.X() = 0.5 * (minx[0] + maxx[0]);
330
c.Y() = 0.5 * (minx[1] + maxx[1]);
331
c.Z() = 0.5 * (minx[2] + maxx[2]);
332
333
inner = min2 ( min2 (maxx[0] - minx[0], maxx[1] - minx[1]), maxx[2] - minx[2]) / 2;
334
}
335
336
337
void Box3dSphere :: GetSubBox (int i, Box3dSphere & sbox) const
338
{
339
i--;
340
if (i & 1)
341
{
342
sbox.minx[0] = c.X();
343
sbox.maxx[0] = maxx[0];
344
}
345
else
346
{
347
sbox.minx[0] = minx[0];
348
sbox.maxx[0] = c.X();
349
}
350
if (i & 2)
351
{
352
sbox.minx[1] = c.Y();
353
sbox.maxx[1] = maxx[1];
354
}
355
else
356
{
357
sbox.minx[1] = minx[1];
358
sbox.maxx[1] = c.Y();
359
}
360
if (i & 4)
361
{
362
sbox.minx[2] = c.Z();
363
sbox.maxx[2] = maxx[2];
364
}
365
else
366
{
367
sbox.minx[2] = minx[2];
368
sbox.maxx[2] = c.Z();
369
}
370
371
// sbox.CalcDiamCenter ();
372
373
sbox.c.X() = 0.5 * (sbox.minx[0] + sbox.maxx[0]);
374
sbox.c.Y() = 0.5 * (sbox.minx[1] + sbox.maxx[1]);
375
sbox.c.Z() = 0.5 * (sbox.minx[2] + sbox.maxx[2]);
376
sbox.diam = 0.5 * diam;
377
sbox.inner = 0.5 * inner;
378
}
379
380
381
382
383
/*
384
double Determinant (const Vec3d & col1,
385
const Vec3d & col2,
386
const Vec3d & col3)
387
{
388
return
389
col1.x[0] * ( col2.x[1] * col3.x[2] - col2.x[2] * col3.x[1]) +
390
col1.x[1] * ( col2.x[2] * col3.x[0] - col2.x[0] * col3.x[2]) +
391
col1.x[2] * ( col2.x[0] * col3.x[1] - col2.x[1] * col3.x[0]);
392
}
393
*/
394
395
void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3)
396
{
397
Swap (v1.Y(), v2.X());
398
Swap (v1.Z(), v3.X());
399
Swap (v2.Z(), v3.Y());
400
}
401
402
403
int SolveLinearSystem (const Vec3d & col1, const Vec3d & col2,
404
const Vec3d & col3, const Vec3d & rhs,
405
Vec3d & sol)
406
{
407
// changed by MW
408
double matrix[3][3];
409
double locrhs[3];
410
int retval = 0;
411
412
for(int i=0; i<3; i++)
413
{
414
matrix[i][0] = col1.X(i+1);
415
matrix[i][1] = col2.X(i+1);
416
matrix[i][2] = col3.X(i+1);
417
locrhs[i] = rhs.X(i+1);
418
}
419
420
for(int i=0; i<2; i++)
421
{
422
int pivot = i;
423
double maxv = fabs(matrix[i][i]);
424
for(int j=i+1; j<3; j++)
425
if(fabs(matrix[j][i]) > maxv)
426
{
427
maxv = fabs(matrix[j][i]);
428
pivot = j;
429
}
430
431
if(fabs(maxv) > 1e-40)
432
{
433
if(pivot != i)
434
{
435
swap(matrix[i][0],matrix[pivot][0]);
436
swap(matrix[i][1],matrix[pivot][1]);
437
swap(matrix[i][2],matrix[pivot][2]);
438
swap(locrhs[i],locrhs[pivot]);
439
}
440
for(int j=i+1; j<3; j++)
441
{
442
double fac = matrix[j][i] / matrix[i][i];
443
444
for(int k=i+1; k<3; k++)
445
matrix[j][k] -= fac*matrix[i][k];
446
locrhs[j] -= fac*locrhs[i];
447
}
448
}
449
else
450
retval = 1;
451
}
452
453
if(fabs(matrix[2][2]) < 1e-40)
454
retval = 1;
455
456
if(retval != 0)
457
return retval;
458
459
460
for(int i=2; i>=0; i--)
461
{
462
double sum = locrhs[i];
463
for(int j=2; j>i; j--)
464
sum -= matrix[i][j]*sol.X(j+1);
465
466
sol.X(i+1) = sum/matrix[i][i];
467
}
468
469
return 0;
470
471
472
473
474
475
/*
476
double det = Determinant (col1, col2, col3);
477
if (fabs (det) < 1e-40)
478
return 1;
479
480
sol.X() = Determinant (rhs, col2, col3) / det;
481
sol.Y() = Determinant (col1, rhs, col3) / det;
482
sol.Z() = Determinant (col1, col2, rhs) / det;
483
484
return 0;
485
*/
486
/*
487
Vec3d cr;
488
Cross (col1, col2, cr);
489
double det = cr * col3;
490
491
if (fabs (det) < 1e-40)
492
return 1;
493
494
if (fabs(cr.Z()) > 1e-12)
495
{
496
// solve for 3. component
497
sol.Z() = (cr * rhs) / det;
498
499
// 2x2 system for 1. and 2. component
500
double res1 = rhs.X() - sol.Z() * col3.X();
501
double res2 = rhs.Y() - sol.Z() * col3.Y();
502
503
sol.X() = (col2.Y() * res1 - col2.X() * res2) / cr.Z();
504
sol.Y() = (col1.X() * res2 - col1.Y() * res1) / cr.Z();
505
506
}
507
else
508
{
509
det = Determinant (col1, col2, col3);
510
if (fabs (det) < 1e-40)
511
return 1;
512
513
sol.X() = Determinant (rhs, col2, col3) / det;
514
sol.Y() = Determinant (col1, rhs, col3) / det;
515
sol.Z() = Determinant (col1, col2, rhs) / det;
516
}
517
518
return 0;
519
*/
520
}
521
522
523
int SolveLinearSystemLS (const Vec3d & col1,
524
const Vec3d & col2,
525
const Vec2d & rhs,
526
Vec3d & sol)
527
{
528
double a11 = col1 * col1;
529
double a12 = col1 * col2;
530
double a22 = col2 * col2;
531
532
double det = a11 * a22 - a12 * a12;
533
534
if (det*det <= 1e-24 * a11 * a22)
535
{
536
sol = Vec3d (0, 0, 0);
537
return 1;
538
}
539
540
Vec2d invrhs;
541
invrhs.X() = ( a22 * rhs.X() - a12 * rhs.Y()) / det;
542
invrhs.Y() = (-a12 * rhs.X() + a11 * rhs.Y()) / det;
543
544
sol.X() = invrhs.X() * col1.X() + invrhs.Y() * col2.X();
545
sol.Y() = invrhs.X() * col1.Y() + invrhs.Y() * col2.Y();
546
sol.Z() = invrhs.X() * col1.Z() + invrhs.Y() * col2.Z();
547
548
return 0;
549
550
/*
551
Vec3d inv1, inv2;
552
int err =
553
PseudoInverse (col1, col2, inv1, inv2);
554
555
sol = rhs.X() * inv1 + rhs.Y() * inv2;
556
return err;
557
*/
558
}
559
560
int SolveLinearSystemLS2 (const Vec3d & col1,
561
const Vec3d & col2,
562
const Vec2d & rhs,
563
Vec3d & sol, double & x, double & y)
564
{
565
double a11 = col1 * col1;
566
double a12 = col1 * col2;
567
double a22 = col2 * col2;
568
569
double det = a11 * a22 - a12 * a12;
570
571
if (fabs (det) <= 1e-12 * col1.Length() * col2.Length() ||
572
col1.Length2() == 0 || col2.Length2() == 0)
573
{
574
sol = Vec3d (0, 0, 0);
575
x = 0; y = 0;
576
return 1;
577
}
578
579
Vec2d invrhs;
580
invrhs.X() = ( a22 * rhs.X() - a12 * rhs.Y()) / det;
581
invrhs.Y() = (-a12 * rhs.X() + a11 * rhs.Y()) / det;
582
583
sol.X() = invrhs.X() * col1.X() + invrhs.Y() * col2.X();
584
sol.Y() = invrhs.X() * col1.Y() + invrhs.Y() * col2.Y();
585
sol.Z() = invrhs.X() * col1.Z() + invrhs.Y() * col2.Z();
586
587
x = invrhs.X();
588
y = invrhs.Y();
589
590
return 0;
591
592
/*
593
Vec3d inv1, inv2;
594
int err =
595
PseudoInverse (col1, col2, inv1, inv2);
596
597
sol = rhs.X() * inv1 + rhs.Y() * inv2;
598
return err;
599
*/
600
}
601
602
int PseudoInverse (const Vec3d & col1,
603
const Vec3d & col2,
604
Vec3d & inv1,
605
Vec3d & inv2)
606
{
607
double a11 = col1 * col1;
608
double a12 = col1 * col2;
609
double a22 = col2 * col2;
610
611
double det = a11 * a22 - a12 * a12;
612
613
if (fabs (det) < 1e-12 * col1.Length() * col2.Length())
614
{
615
inv1 = Vec3d (0, 0, 0);
616
inv2 = Vec3d (0, 0, 0);
617
return 1;
618
}
619
620
double ia11 = a22 / det;
621
double ia12 = -a12 / det;
622
double ia22 = a11 / det;
623
624
inv1 = ia11 * col1 + ia12 * col2;
625
inv2 = ia12 * col1 + ia22 * col2;
626
627
return 0;
628
}
629
630
631
632
633
QuadraticFunction3d ::
634
QuadraticFunction3d (const Point3d & p, const Vec3d & v)
635
{
636
Vec3d hv(v);
637
hv /= (hv.Length() + 1e-12);
638
Vec3d t1, t2;
639
hv.GetNormal (t1);
640
Cross (hv, t1, t2);
641
642
double t1p = t1.X() * p.X() + t1.Y() * p.Y() + t1.Z() * p.Z();
643
double t2p = t2.X() * p.X() + t2.Y() * p.Y() + t2.Z() * p.Z();
644
c0 = sqr (t1p) + sqr (t2p);
645
cx = -2 * (t1p * t1.X() + t2p * t2.X());
646
cy = -2 * (t1p * t1.Y() + t2p * t2.Y());
647
cz = -2 * (t1p * t1.Z() + t2p * t2.Z());
648
649
cxx = t1.X() * t1.X() + t2.X() * t2.X();
650
cyy = t1.Y() * t1.Y() + t2.Y() * t2.Y();
651
czz = t1.Z() * t1.Z() + t2.Z() * t2.Z();
652
653
cxy = 2 * t1.X() * t1.Y() + 2 * t2.X() * t2.Y();
654
cxz = 2 * t1.X() * t1.Z() + 2 * t2.X() * t2.Z();
655
cyz = 2 * t1.Y() * t1.Z() + 2 * t2.Y() * t2.Z();
656
657
/*
658
(*testout) << "c0 = " << c0
659
<< " clin = " << cx << " " << cy << " " << cz
660
<< " cq = " << cxx << " " << cyy << " " << czz
661
<< cxy << " " << cyz << " " << cyz << endl;
662
*/
663
}
664
665
// QuadraticFunction3d gqf (Point3d (0,0,0), Vec3d (1, 0, 0));
666
667
668
669
670
671
void referencetransform :: Set (const Point3d & p1, const Point3d & p2,
672
const Point3d & p3, double ah)
673
{
674
ex = p2 - p1;
675
ex /= ex.Length();
676
ey = p3 - p1;
677
ey -= (ex * ey) * ex;
678
ey /= ey.Length();
679
ez = Cross (ex, ey);
680
rp = p1;
681
h = ah;
682
683
exh = ah * ex;
684
eyh = ah * ey;
685
ezh = ah * ez;
686
ah = 1 / ah;
687
ex_h = ah * ex;
688
ey_h = ah * ey;
689
ez_h = ah * ez;
690
}
691
692
void referencetransform :: ToPlain (const Point3d & p, Point3d & pp) const
693
{
694
Vec3d v;
695
v = p - rp;
696
pp.X() = (ex_h * v);
697
pp.Y() = (ey_h * v);
698
pp.Z() = (ez_h * v);
699
}
700
701
void referencetransform :: ToPlain (const ARRAY<Point3d> & p,
702
ARRAY<Point3d> & pp) const
703
{
704
Vec3d v;
705
int i;
706
707
pp.SetSize (p.Size());
708
for (i = 1; i <= p.Size(); i++)
709
{
710
v = p.Get(i) - rp;
711
pp.Elem(i).X() = (ex_h * v);
712
pp.Elem(i).Y() = (ey_h * v);
713
pp.Elem(i).Z() = (ez_h * v);
714
}
715
}
716
717
void referencetransform :: FromPlain (const Point3d & pp, Point3d & p) const
718
{
719
Vec3d v;
720
// v = (h * pp.X()) * ex + (h * pp.Y()) * ey + (h * pp.Z()) * ez;
721
// p = rp + v;
722
v.X() = pp.X() * exh.X() + pp.Y() * eyh.X() + pp.Z() * ezh.X();
723
v.Y() = pp.X() * exh.Y() + pp.Y() * eyh.Y() + pp.Z() * ezh.Y();
724
v.Z() = pp.X() * exh.Z() + pp.Y() * eyh.Z() + pp.Z() * ezh.Z();
725
p.X() = rp.X() + v.X();
726
p.Y() = rp.Y() + v.Y();
727
p.Z() = rp.Z() + v.Z();
728
}
729
730
731
}
732
733