triangleI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2018 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "IOstreams.H"
30 #include "pointHit.H"
31 #include "triPoints.H"
32 #include "mathematicalConstants.H"
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
36 template<class Point, class PointRef>
38 (
39  const Point& a,
40  const Point& b,
41  const Point& c
42 )
43 :
44  a_(a),
45  b_(b),
46  c_(c)
47 {}
48 
49 
50 template<class Point, class PointRef>
52 (
53  const FixedList<Point, 3>& tri
54 )
55 :
56  a_(tri[0]),
57  b_(tri[1]),
58  c_(tri[2])
59 {}
60 
61 
62 template<class Point, class PointRef>
64 (
65  const UList<Point>& points,
66  const FixedList<label, 3>& indices
67 )
68 :
69  a_(points[indices[0]]),
70  b_(points[indices[1]]),
71  c_(points[indices[2]])
72 {}
73 
74 
75 
76 template<class Point, class PointRef>
78 {
79  is >> *this;
80 }
81 
82 
83 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
84 
85 template<class Point, class PointRef>
87 {
88  return a_;
89 }
90 
91 template<class Point, class PointRef>
93 {
94  return b_;
95 }
96 
97 template<class Point, class PointRef>
99 {
100  return c_;
101 }
102 
103 
104 template<class Point, class PointRef>
106 {
107  return (1.0/3.0)*(a_ + b_ + c_);
108 }
109 
110 
111 template<class Point, class PointRef>
113 {
114  return 0.5*((b_ - a_)^(c_ - a_));
115 }
116 
117 
118 template<class Point, class PointRef>
120 {
121  const vector n(areaNormal());
122  const scalar s(Foam::mag(n));
123  return s < ROOTVSMALL ? Zero : n/s;
124 }
125 
126 
127 template<class Point, class PointRef>
128 inline Foam::scalar Foam::triangle<Point, PointRef>::mag() const
129 {
130  return ::Foam::mag(areaNormal());
131 }
132 
133 
134 template<class Point, class PointRef>
136 {
137  scalar d1 = (c_ - a_) & (b_ - a_);
138  scalar d2 = -(c_ - b_) & (b_ - a_);
139  scalar d3 = (c_ - a_) & (c_ - b_);
140 
141  scalar c1 = d2*d3;
142  scalar c2 = d3*d1;
143  scalar c3 = d1*d2;
144 
145  scalar c = c1 + c2 + c3;
146 
147  if (Foam::mag(c) < ROOTVSMALL)
148  {
149  // Degenerate triangle, returning centre instead of circumCentre.
150 
151  return centre();
152  }
153 
154  return
155  (
156  ((c2 + c3)*a_ + (c3 + c1)*b_ + (c1 + c2)*c_)/(2*c)
157  );
158 }
159 
160 
161 template<class Point, class PointRef>
163 {
164  const scalar d1 = (c_ - a_) & (b_ - a_);
165  const scalar d2 = -(c_ - b_) & (b_ - a_);
166  const scalar d3 = (c_ - a_) & (c_ - b_);
167 
168  const scalar denom = d2*d3 + d3*d1 + d1*d2;
169 
170  if (Foam::mag(denom) < VSMALL)
171  {
172  // Degenerate triangle, returning GREAT for circumRadius.
173 
174  return GREAT;
175  }
176 
177  const scalar a = (d1 + d2)*(d2 + d3)*(d3 + d1) / denom;
178  return 0.5*Foam::sqrt(min(GREAT, max(0, a)));
179 }
180 
181 
182 template<class Point, class PointRef>
183 inline Foam::scalar Foam::triangle<Point, PointRef>::quality() const
184 {
185  scalar c = circumRadius();
186 
187  if (c < ROOTVSMALL)
188  {
189  // zero circumRadius, something has gone wrong.
190  return SMALL;
191  }
192 
193  return mag()/(Foam::sqr(c)*3.0*sqrt(3.0)/4.0);
194 }
195 
196 
197 template<class Point, class PointRef>
199 (
200  const triangle& t
201 ) const
202 {
203  return (1.0/12.0)*
204  (
205  ((t.a_ - a_) & ((b_ - a_)^(c_ - a_)))
206  + ((t.b_ - b_) & ((c_ - b_)^(t.a_ - b_)))
207  + ((c_ - t.c_) & ((t.b_ - t.c_)^(t.a_ - t.c_)))
208 
209  + ((t.a_ - a_) & ((b_ - a_)^(c_ - a_)))
210  + ((b_ - t.b_) & ((t.a_ - t.b_)^(t.c_ - t.b_)))
211  + ((c_ - t.c_) & ((b_ - t.c_)^(t.a_ - t.c_)))
212  );
213 }
214 
215 
216 template<class Point, class PointRef>
218 (
219  PointRef refPt,
220  scalar density
221 ) const
222 {
223  Point aRel = a_ - refPt;
224  Point bRel = b_ - refPt;
225  Point cRel = c_ - refPt;
226 
227  tensor V
228  (
229  aRel.x(), aRel.y(), aRel.z(),
230  bRel.x(), bRel.y(), bRel.z(),
231  cRel.x(), cRel.y(), cRel.z()
232  );
233 
234  scalar a = Foam::mag((b_ - a_)^(c_ - a_));
235 
236  tensor S = 1/24.0*(tensor::one + I);
237 
238  return
239  (
240  a*I/24.0*
241  (
242  (aRel & aRel)
243  + (bRel & bRel)
244  + (cRel & cRel)
245  + ((aRel + bRel + cRel) & (aRel + bRel + cRel))
246  )
247  - a*(V.T() & S & V)
248  )
249  *density;
250 }
251 
252 
253 template<class Point, class PointRef>
255 {
256  return barycentricToPoint(barycentric2D01(rndGen));
257 }
258 
259 
260 template<class Point, class PointRef>
262 (
263  const barycentric2D& bary
264 ) const
265 {
266  return bary[0]*a_ + bary[1]*b_ + bary[2]*c_;
267 }
268 
269 
270 template<class Point, class PointRef>
272 (
273  const point& pt
274 ) const
275 {
276  barycentric2D bary;
277  pointToBarycentric(pt, bary);
278  return bary;
279 }
280 
281 
282 template<class Point, class PointRef>
284 (
285  const point& pt,
286  barycentric2D& bary
287 ) const
288 {
289  // Reference:
290  // Real-time collision detection, Christer Ericson, 2005, p47-48
291 
292  vector v0 = b_ - a_;
293  vector v1 = c_ - a_;
294  vector v2 = pt - a_;
295 
296  scalar d00 = v0 & v0;
297  scalar d01 = v0 & v1;
298  scalar d11 = v1 & v1;
299  scalar d20 = v2 & v0;
300  scalar d21 = v2 & v1;
301 
302  scalar denom = d00*d11 - d01*d01;
303 
304  if (Foam::mag(denom) < SMALL)
305  {
306  // Degenerate triangle, returning 1/3 barycentric coordinates.
307 
308  bary = barycentric2D(1.0/3.0, 1.0/3.0, 1.0/3.0);
309 
310  return denom;
311  }
312 
313  bary[1] = (d11*d20 - d01*d21)/denom;
314  bary[2] = (d00*d21 - d01*d20)/denom;
315  bary[0] = 1.0 - bary[1] - bary[2];
316 
317  return denom;
318 }
319 
320 
321 template<class Point, class PointRef>
323 (
324  const point& p,
325  const vector& q,
326  const intersection::algorithm alg,
327  const intersection::direction dir
328 ) const
329 {
330  // Express triangle in terms of baseVertex (point a_) and
331  // two edge vectors
332  vector E0 = b_ - a_;
333  vector E1 = c_ - a_;
334 
335  // Initialize intersection to miss.
336  pointHit inter(p);
337 
338  vector n(0.5*(E0 ^ E1));
339  scalar area = Foam::mag(n);
340 
341  if (area < VSMALL)
342  {
343  // Ineligible miss.
344  inter.setMiss(false);
345 
346  // The miss point is the nearest point on the triangle. Take any one.
347  inter.setPoint(a_);
348 
349  // The distance to the miss is the distance between the
350  // original point and plane of intersection. No normal so use
351  // distance from p to a_
352  inter.setDistance(Foam::mag(a_ - p));
353 
354  return inter;
355  }
356 
357  vector q1 = q/Foam::mag(q);
358 
359  if (dir == intersection::CONTACT_SPHERE)
360  {
361  n /= area;
362 
363  return ray(p, q1 - n, alg, intersection::VECTOR);
364  }
365 
366  // Intersection point with triangle plane
367  point pInter;
368  // Is intersection point inside triangle
369  bool hit;
370  {
371  // Reuse the fast ray intersection routine below in FULL_RAY
372  // mode since the original intersection routine has rounding problems.
373  pointHit fastInter = intersection(p, q1, intersection::FULL_RAY);
374  hit = fastInter.hit();
375 
376  if (hit)
377  {
378  pInter = fastInter.rawPoint();
379  }
380  else
381  {
382  // Calculate intersection of ray with triangle plane
383  vector v = a_ - p;
384  pInter = p + (q1&v)*q1;
385  }
386  }
387 
388  // Distance to intersection point
389  scalar dist = q1 & (pInter - p);
390 
391  const scalar planarPointTol =
392  Foam::min
393  (
394  Foam::min
395  (
396  Foam::mag(E0),
397  Foam::mag(E1)
398  ),
399  Foam::mag(c_ - b_)
400  )*intersection::planarTol();
401 
402  bool eligible =
403  alg == intersection::FULL_RAY
404  || (alg == intersection::HALF_RAY && dist > -planarPointTol)
405  || (
406  alg == intersection::VISIBLE
407  && ((q1 & areaNormal()) < -VSMALL)
408  );
409 
410  if (hit && eligible)
411  {
412  // Hit. Set distance to intersection.
413  inter.setHit();
414  inter.setPoint(pInter);
415  inter.setDistance(dist);
416  }
417  else
418  {
419  // Miss or ineligible hit.
420  inter.setMiss(eligible);
421 
422  // The miss point is the nearest point on the triangle
423  inter.setPoint(nearestPoint(p).rawPoint());
424 
425  // The distance to the miss is the distance between the
426  // original point and plane of intersection
427  inter.setDistance(Foam::mag(pInter - p));
428  }
429 
430 
431  return inter;
432 }
433 
434 
435 // From "Fast, Minimum Storage Ray/Triangle Intersection"
436 // Moeller/Trumbore.
437 template<class Point, class PointRef>
439 (
440  const point& orig,
441  const vector& dir,
442  const intersection::algorithm alg,
443  const scalar tol
444 ) const
445 {
446  const vector edge1 = b_ - a_;
447  const vector edge2 = c_ - a_;
448 
449  // begin calculating determinant - also used to calculate U parameter
450  const vector pVec = dir ^ edge2;
451 
452  // if determinant is near zero, ray lies in plane of triangle
453  const scalar det = edge1 & pVec;
454 
455  // Initialise to miss
456  pointHit intersection(false, Zero, GREAT, false);
457 
458  if (alg == intersection::VISIBLE)
459  {
460  // Culling branch
461  if (det < ROOTVSMALL)
462  {
463  // Ray on wrong side of triangle. Return miss
464  return intersection;
465  }
466  }
467  else if (alg == intersection::HALF_RAY || alg == intersection::FULL_RAY)
468  {
469  // Non-culling branch
470  if (det > -ROOTVSMALL && det < ROOTVSMALL)
471  {
472  // Ray parallel to triangle. Return miss
473  return intersection;
474  }
475  }
476 
477  const scalar inv_det = 1.0 / det;
478 
479  /* calculate distance from a_ to ray origin */
480  const vector tVec = orig-a_;
481 
482  /* calculate U parameter and test bounds */
483  const scalar u = (tVec & pVec)*inv_det;
484 
485  if (u < -tol || u > 1.0+tol)
486  {
487  // return miss
488  return intersection;
489  }
490 
491  /* prepare to test V parameter */
492  const vector qVec = tVec ^ edge1;
493 
494  /* calculate V parameter and test bounds */
495  const scalar v = (dir & qVec) * inv_det;
496 
497  if (v < -tol || u + v > 1.0+tol)
498  {
499  // return miss
500  return intersection;
501  }
502 
503  /* calculate t, scale parameters, ray intersects triangle */
504  const scalar t = (edge2 & qVec) * inv_det;
505 
506  if (alg == intersection::HALF_RAY && t < -tol)
507  {
508  // Wrong side of orig. Return miss
509  return intersection;
510  }
511 
512  intersection.setHit();
513  intersection.setPoint(a_ + u*edge1 + v*edge2);
514  intersection.setDistance(t);
515 
516  return intersection;
517 }
518 
519 
520 template<class Point, class PointRef>
522 (
523  const point& p,
524  label& nearType,
525  label& nearLabel
526 ) const
527 {
528  // Adapted from:
529  // Real-time collision detection, Christer Ericson, 2005, p136-142
530 
531  // Check if P in vertex region outside A
532  vector ab = b_ - a_;
533  vector ac = c_ - a_;
534  vector ap = p - a_;
535 
536  scalar d1 = ab & ap;
537  scalar d2 = ac & ap;
538 
539  if (d1 <= 0.0 && d2 <= 0.0)
540  {
541  // barycentric coordinates (1, 0, 0)
542 
543  nearType = POINT;
544  nearLabel = 0;
545  return pointHit(false, a_, Foam::mag(a_ - p), true);
546  }
547 
548  // Check if P in vertex region outside B
549  vector bp = p - b_;
550  scalar d3 = ab & bp;
551  scalar d4 = ac & bp;
552 
553  if (d3 >= 0.0 && d4 <= d3)
554  {
555  // barycentric coordinates (0, 1, 0)
556 
557  nearType = POINT;
558  nearLabel = 1;
559  return pointHit(false, b_, Foam::mag(b_ - p), true);
560  }
561 
562  // Check if P in edge region of AB, if so return projection of P onto AB
563  scalar vc = d1*d4 - d3*d2;
564 
565  if (vc <= 0.0 && d1 >= 0.0 && d3 <= 0.0)
566  {
567  if ((d1 - d3) < ROOTVSMALL)
568  {
569  // Degenerate triangle, for d1 = d3, a_ and b_ are likely coincident
570  nearType = POINT;
571  nearLabel = 0;
572  return pointHit(false, a_, Foam::mag(a_ - p), true);
573  }
574 
575  // barycentric coordinates (1-v, v, 0)
576  scalar v = d1/(d1 - d3);
577 
578  point nearPt = a_ + v*ab;
579  nearType = EDGE;
580  nearLabel = 0;
581  return pointHit(false, nearPt, Foam::mag(nearPt - p), true);
582  }
583 
584  // Check if P in vertex region outside C
585  vector cp = p - c_;
586  scalar d5 = ab & cp;
587  scalar d6 = ac & cp;
588 
589  if (d6 >= 0.0 && d5 <= d6)
590  {
591  // barycentric coordinates (0, 0, 1)
592 
593  nearType = POINT;
594  nearLabel = 2;
595  return pointHit(false, c_, Foam::mag(c_ - p), true);
596  }
597 
598  // Check if P in edge region of AC, if so return projection of P onto AC
599  scalar vb = d5*d2 - d1*d6;
600 
601  if (vb <= 0.0 && d2 >= 0.0 && d6 <= 0.0)
602  {
603  if ((d2 - d6) < ROOTVSMALL)
604  {
605  // Degenerate triangle, for d2 = d6, a_ and c_ are likely coincident
606  nearType = POINT;
607  nearLabel = 0;
608  return pointHit(false, a_, Foam::mag(a_ - p), true);
609  }
610 
611  // barycentric coordinates (1-w, 0, w)
612  scalar w = d2/(d2 - d6);
613 
614  point nearPt = a_ + w*ac;
615  nearType = EDGE;
616  nearLabel = 2;
617  return pointHit(false, nearPt, Foam::mag(nearPt - p), true);
618  }
619 
620  // Check if P in edge region of BC, if so return projection of P onto BC
621  scalar va = d3*d6 - d5*d4;
622 
623  if (va <= 0.0 && (d4 - d3) >= 0.0 && (d5 - d6) >= 0.0)
624  {
625  if (((d4 - d3) + (d5 - d6)) < ROOTVSMALL)
626  {
627  // Degenerate triangle, for (d4 - d3) = (d6 - d5), b_ and c_ are
628  // likely coincident
629  nearType = POINT;
630  nearLabel = 1;
631  return pointHit(false, b_, Foam::mag(b_ - p), true);
632  }
633 
634  // barycentric coordinates (0, 1-w, w)
635  scalar w = (d4 - d3)/((d4 - d3) + (d5 - d6));
636 
637  point nearPt = b_ + w*(c_ - b_);
638  nearType = EDGE;
639  nearLabel = 1;
640  return pointHit(false, nearPt, Foam::mag(nearPt - p), true);
641  }
642 
643  // P inside face region. Compute Q through its barycentric
644  // coordinates (u, v, w)
645 
646  if ((va + vb + vc) < ROOTVSMALL)
647  {
648  // Degenerate triangle, return the centre because no edge or points are
649  // closest
650  point nearPt = centre();
651  nearType = NONE,
652  nearLabel = -1;
653  return pointHit(true, nearPt, Foam::mag(nearPt - p), false);
654  }
655 
656  scalar denom = 1.0/(va + vb + vc);
657  scalar v = vb * denom;
658  scalar w = vc * denom;
659 
660  // = u*a + v*b + w*c, u = va*denom = 1.0 - v - w
661 
662  point nearPt = a_ + ab*v + ac*w;
663  nearType = NONE,
664  nearLabel = -1;
665  return pointHit(true, nearPt, Foam::mag(nearPt - p), false);
666 }
667 
668 
669 template<class Point, class PointRef>
671 (
672  const point& p
673 ) const
674 {
675  // Dummy labels
676  label nearType = -1;
677  label nearLabel = -1;
678 
679  return nearestPointClassify(p, nearType, nearLabel);
680 }
681 
682 
683 template<class Point, class PointRef>
685 (
686  const point& p,
687  label& nearType,
688  label& nearLabel
689 ) const
690 {
691  return nearestPointClassify(p, nearType, nearLabel).hit();
692 }
693 
694 
695 template<class Point, class PointRef>
697 (
698  const linePointRef& ln,
699  pointHit& lnInfo
700 ) const
701 {
702  vector q = ln.vec();
703  pointHit triInfo
704  (
706  (
707  ln.start(),
708  q,
709  intersection::FULL_RAY
710  )
711  );
712 
713  if (triInfo.hit())
714  {
715  // Line hits triangle. Find point on line.
716  if (triInfo.distance() > 1)
717  {
718  // Hit beyond endpoint
719  lnInfo.setMiss(true);
720  lnInfo.setPoint(ln.end());
721  scalar dist = Foam::mag(triInfo.hitPoint()-lnInfo.missPoint());
722  lnInfo.setDistance(dist);
723  triInfo.setMiss(true);
724  triInfo.setDistance(dist);
725  }
726  else if (triInfo.distance() < 0)
727  {
728  // Hit beyond startpoint
729  lnInfo.setMiss(true);
730  lnInfo.setPoint(ln.start());
731  scalar dist = Foam::mag(triInfo.hitPoint()-lnInfo.missPoint());
732  lnInfo.setDistance(dist);
733  triInfo.setMiss(true);
734  triInfo.setDistance(dist);
735  }
736  else
737  {
738  // Hit on line
739  lnInfo.setHit();
740  lnInfo.setPoint(triInfo.hitPoint());
741  lnInfo.setDistance(0.0);
742  triInfo.setDistance(0.0);
743  }
744  }
745  else
746  {
747  // Line skips triangle. See which triangle edge it gets closest to
748 
749  point nearestEdgePoint;
750  point nearestLinePoint;
751  //label minEdgeIndex = 0;
752  scalar minDist = ln.nearestDist
753  (
754  linePointRef(a_, b_),
755  nearestLinePoint,
756  nearestEdgePoint
757  );
758 
759  {
760  point linePoint;
761  point triEdgePoint;
762  scalar dist = ln.nearestDist
763  (
764  linePointRef(b_, c_),
765  linePoint,
766  triEdgePoint
767  );
768  if (dist < minDist)
769  {
770  minDist = dist;
771  nearestEdgePoint = triEdgePoint;
772  nearestLinePoint = linePoint;
773  //minEdgeIndex = 1;
774  }
775  }
776 
777  {
778  point linePoint;
779  point triEdgePoint;
780  scalar dist = ln.nearestDist
781  (
782  linePointRef(c_, a_),
783  linePoint,
784  triEdgePoint
785  );
786  if (dist < minDist)
787  {
788  minDist = dist;
789  nearestEdgePoint = triEdgePoint;
790  nearestLinePoint = linePoint;
791  //minEdgeIndex = 2;
792  }
793  }
794 
795  lnInfo.setDistance(minDist);
796  triInfo.setDistance(minDist);
797  triInfo.setMiss(false);
798  triInfo.setPoint(nearestEdgePoint);
799 
800  // Convert point on line to pointHit
801  if (Foam::mag(nearestLinePoint-ln.start()) < SMALL)
802  {
803  lnInfo.setMiss(true);
804  lnInfo.setPoint(ln.start());
805  }
806  else if (Foam::mag(nearestLinePoint-ln.end()) < SMALL)
807  {
808  lnInfo.setMiss(true);
809  lnInfo.setPoint(ln.end());
810  }
811  else
812  {
813  lnInfo.setHit();
814  lnInfo.setPoint(nearestLinePoint);
815  }
816  }
817  return triInfo;
818 }
819 
820 
821 template<class Point, class PointRef>
823 (
824  const point& p,
825  const scalar tol
826 ) const
827 {
828  const scalar dist = ((p - a_) & unitNormal());
829 
830  return ((dist < -tol) ? -1 : (dist > tol) ? +1 : 0);
831 }
832 
833 
834 template<class Point, class PointRef>
836 (
837  const triPoints&
838 )
839 {}
840 
841 
842 template<class Point, class PointRef>
844 :
845  area_(0.0)
846 {}
847 
848 
849 template<class Point, class PointRef>
851 (
852  const triPoints& tri
853 )
854 {
855  area_ += triangle<Point, const Point&>(tri).mag();
856 }
857 
858 
859 template<class Point, class PointRef>
861 (
862  triIntersectionList& tris,
863  label& nTris
864 )
865 :
866  tris_(tris),
867  nTris_(nTris)
868 {}
869 
870 
871 template<class Point, class PointRef>
873 (
874  const triPoints& tri
875 )
876 {
877  tris_[nTris_++] = tri;
878 }
879 
880 
881 template<class Point, class PointRef>
883 (
884  const FixedList<scalar, 3>& d,
885  const triPoints& t,
886  const label negI,
887  const label posI
888 )
889 {
890  return (d[posI]*t[negI] - d[negI]*t[posI])/(-d[negI] + d[posI]);
891 }
892 
893 
894 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
895 
896 template<class Point, class PointRef>
897 inline Foam::Istream& Foam::operator>>
898 (
899  Istream& is,
901 )
902 {
903  is.readBegin("triangle");
904  is >> t.a_ >> t.b_ >> t.c_;
905  is.readEnd("triangle");
906 
907  is.check(FUNCTION_NAME);
908  return is;
909 }
910 
911 
912 template<class Point, class PointRef>
913 inline Foam::Ostream& Foam::operator<<
914 (
915  Ostream& os,
916  const triangle<Point, PointRef>& t
917 )
918 {
919  os << nl
921  << t.a_ << token::SPACE
922  << t.b_ << token::SPACE
923  << t.c_
924  << token::END_LIST;
925 
926  return os;
927 }
928 
929 
930 // ************************************************************************* //
Foam::intersection::direction
direction
Definition: intersection.H:66
Foam::Random
Random number generator.
Definition: Random.H:59
Foam::Tensor< scalar >
Foam::PointHit::setHit
void setHit() noexcept
Set the hit status on.
Definition: PointHit.H:181
mathematicalConstants.H
Foam::PointHit::setMiss
void setMiss(const bool eligible) noexcept
Set the hit status off and set the eligible miss status.
Definition: PointHit.H:188
p
volScalarField & p
Definition: createFieldRefs.H:8
IOstreams.H
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Foam::PointHit::setDistance
void setDistance(const scalar d) noexcept
Set the distance.
Definition: PointHit.H:201
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::triangle::randomPoint
Point randomPoint(Random &rndGen) const
Return a random point on the triangle from a uniform.
Definition: triangleI.H:254
cp
const volScalarField & cp
Definition: setRegionSolidFields.H:8
Foam::PointHit
Describes the interaction of a face and a point. It carries the info of a successful hit and (if succ...
Definition: PointHit.H:53
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::triangle::sumAreaOp::sumAreaOp
sumAreaOp()
Definition: triangleI.H:843
Foam::triangle::sign
int sign(const point &p, const scalar tol=SMALL) const
The sign for which side of the face plane the point is on.
Definition: triangleI.H:823
Foam::triangle::classify
bool classify(const point &p, label &nearType, label &nearLabel) const
Classify nearest point to p in triangle plane.
Definition: triangleI.H:685
Foam::triangle::inertia
tensor inertia(PointRef refPt=Zero, scalar density=1.0) const
Return the inertia tensor, with optional reference.
Definition: triangleI.H:218
Foam::Barycentric2D
Templated 2D Barycentric derived from VectorSpace. Has 3 components, one of which is redundant.
Definition: Barycentric2D.H:54
Foam::PointHit::distance
scalar distance() const noexcept
Return distance to hit.
Definition: PointHit.H:139
Foam::barycentric2D
Barycentric2D< scalar > barycentric2D
A scalar version of the templated Barycentric2D.
Definition: barycentric2D.H:47
triPoints.H
Foam::PointHit::hitPoint
const point_type & hitPoint() const
Return the hit point. Fatal if not hit.
Definition: PointHit.H:145
pointHit.H
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::Istream::readBegin
bool readBegin(const char *funcName)
Begin read of data chunk, starts with '('.
Definition: Istream.C:111
Foam::triangle::centre
Point centre() const
Return centre (centroid)
Definition: triangleI.H:105
Foam::triangle::unitNormal
vector unitNormal() const
Return unit normal.
Definition: triangleI.H:119
Foam::triangle
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:59
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::triPoints
Triangle storage. Null constructable (unfortunately triangle<point, point> is not)
Definition: triPoints.H:52
Foam::constant::physicoChemical::c1
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
Foam::triangle::c
const Point & c() const
Return third vertex.
Definition: triangleI.H:98
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::PointHit::missPoint
const point_type & missPoint() const
Return the miss point. Fatal if hit.
Definition: PointHit.H:158
Foam::PointHit::rawPoint
const point_type & rawPoint() const noexcept
The point, no checks.
Definition: PointHit.H:172
Foam::triangle::a
const Point & a() const
Return first vertex.
Definition: triangleI.H:86
Foam::intersection::algorithm
algorithm
Definition: intersection.H:72
Foam::triangle::ray
pointHit ray(const point &p, const vector &q, const intersection::algorithm=intersection::FULL_RAY, const intersection::direction dir=intersection::VECTOR) const
Return point intersection with a ray.
Definition: triangleI.H:323
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::triangle::b
const Point & b() const
Return second vertex.
Definition: triangleI.H:92
Foam::triangle::circumRadius
scalar circumRadius() const
Return circum-radius.
Definition: triangleI.H:162
Foam::pointHit
PointHit< point > pointHit
A PointIndexHit for 3D points.
Definition: pointHit.H:44
os
OBJstream os(runTime.globalPath()/outputName)
Foam::constant::physicoChemical::c2
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].
Foam::PointHit::setPoint
void setPoint(const point_type &p)
Set the point.
Definition: PointHit.H:195
Foam::triangle::mag
scalar mag() const
Return scalar magnitude.
Definition: triangleI.H:128
Foam::triangle::nearestPointClassify
pointHit nearestPointClassify(const point &p, label &nearType, label &nearLabel) const
Find the nearest point to p on the triangle and classify it:
Definition: triangleI.H:522
Foam::linePointRef
line< point, const point & > linePointRef
A line using referred points.
Definition: linePointRef.H:47
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::barycentric2D01
barycentric2D barycentric2D01(Random &rndGen)
Generate a random barycentric coordinate within the unit triangle.
Definition: barycentric2D.C:55
Foam::Vector< scalar >
Foam::triangle::quality
scalar quality() const
Return quality: Ratio of triangle and circum-circle.
Definition: triangleI.H:183
Foam::triangle::circumCentre
Point circumCentre() const
Return circum-centre.
Definition: triangleI.H:135
Foam::sqrt
dimensionedScalar sqrt(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:144
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::FixedList
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:104
Foam::token::SPACE
Space [isspace].
Definition: token.H:125
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::intersection
Foam::intersection.
Definition: intersection.H:52
Foam::triangle::intersection
pointHit intersection(const point &p, const vector &q, const intersection::algorithm alg, const scalar tol=0.0) const
Fast intersection with a ray.
Definition: triangleI.H:439
Foam::line
A line primitive.
Definition: line.H:53
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::fieldTypes::area
const wordList area
Standard area field types (scalar, vector, tensor, etc)
Foam::triangle::triangle
triangle(const Point &a, const Point &b, const Point &c)
Construct from three points.
Definition: triangleI.H:38
Foam::token::END_LIST
End list [isseparator].
Definition: token.H:156
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Point
CGAL::Point_3< K > Point
Definition: CGALIndexedPolyhedron.H:53
rndGen
Random rndGen
Definition: createFields.H:23
Foam::ln
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
Definition: MSwindows.C:925
Foam::triangle::nearestPoint
pointHit nearestPoint(const point &p) const
Return nearest point to p on triangle.
Definition: triangleI.H:671
Foam::det
dimensionedScalar det(const dimensionedSphericalTensor &dt)
Definition: dimensionedSphericalTensor.C:62
Foam::triangle::pointToBarycentric
barycentric2D pointToBarycentric(const point &pt) const
Calculate the barycentric coordinates from the given point.
Definition: triangleI.H:272
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::triangle::barycentricToPoint
Point barycentricToPoint(const barycentric2D &bary) const
Calculate the point from the given barycentric coordinates.
Definition: triangleI.H:262
Foam::triangle::areaNormal
vector areaNormal() const
The area normal - with magnitude equal to area of triangle.
Definition: triangleI.H:112
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
Foam::PointHit::hit
bool hit() const noexcept
Is there a hit.
Definition: PointHit.H:121
Foam::triangle::sweptVol
scalar sweptVol(const triangle &t) const
Return swept-volume.
Definition: triangleI.H:199
Foam::I
static const Identity< scalar > I
Definition: Identity.H:95
Foam::triangle::storeOp::storeOp
storeOp(triIntersectionList &, label &)
Definition: triangleI.H:861