triangleI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "IOstreams.H"
27 #include "pointHit.H"
28 #include "mathematicalConstants.H"
29 
30 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31 
32 template<class Point, class PointRef>
34 (
35  const Point& a,
36  const Point& b,
37  const Point& c
38 )
39 :
40  a_(a),
41  b_(b),
42  c_(c)
43 {}
44 
45 
46 template<class Point, class PointRef>
48 (
49  const UList<Point>& points,
50  const FixedList<label, 3>& indices
51 )
52 :
53  a_(points[indices[0]]),
54  b_(points[indices[1]]),
55  c_(points[indices[2]])
56 {}
57 
58 
59 
60 template<class Point, class PointRef>
62 {
63  is >> *this;
64 }
65 
66 
67 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
68 
69 template<class Point, class PointRef>
70 inline const Point& Foam::triangle<Point, PointRef>::a() const
71 {
72  return a_;
73 }
74 
75 template<class Point, class PointRef>
76 inline const Point& Foam::triangle<Point, PointRef>::b() const
77 {
78  return b_;
79 }
80 
81 template<class Point, class PointRef>
82 inline const Point& Foam::triangle<Point, PointRef>::c() const
83 {
84  return c_;
85 }
86 
87 
88 template<class Point, class PointRef>
90 {
91  return (1.0/3.0)*(a_ + b_ + c_);
92 }
93 
94 
95 template<class Point, class PointRef>
97 {
98  return 0.5*((b_ - a_)^(c_ - a_));
99 }
100 
101 
102 template<class Point, class PointRef>
103 inline Foam::scalar Foam::triangle<Point, PointRef>::mag() const
104 {
105  return Foam::mag(area());
106 }
107 
108 
109 template<class Point, class PointRef>
111 {
112  const vector a = area();
113  const scalar maga = Foam::mag(a);
114  return maga > 0 ? a/maga : Zero;
115 }
116 
117 
118 template<class Point, class PointRef>
121 {
122  const scalar d1 = (c_ - a_) & (b_ - a_);
123  const scalar d2 = -(c_ - b_) & (b_ - a_);
124  const scalar d3 = (c_ - a_) & (c_ - b_);
125 
126  const scalar c1 = d2*d3;
127  const scalar c2 = d3*d1;
128  const scalar c3 = d1*d2;
129 
130  const scalar denom = c1 + c2 + c3;
131 
132  if (Foam::mag(denom) < rootVSmall)
133  {
134  // Degenerate. Return an invalid circle.
135  return Tuple2<Point, scalar>(point::uniform(NaN), -vGreat);
136  }
137  else
138  {
139  return
141  (
142  ((c2 + c3)*a_ + (c3 + c1)*b_ + (c1 + c2)*c_)/(2*denom),
143  max(0, (d1 + d2)*(d2 + d3)*(d3 + d1)/(4*denom))
144  );
145  }
146 }
147 
148 
149 template<class Point, class PointRef>
152 {
153  const Tuple2<Point, scalar> crSqr = circumCircleSqr();
154 
155  // Invalid. Return without conversion.
156  if (crSqr.second() < 0) return crSqr;
157 
158  return Tuple2<Point, scalar>(crSqr.first(), sqrt(crSqr.second()));
159 }
160 
161 
162 template<class Point, class PointRef>
163 inline Foam::scalar Foam::triangle<Point, PointRef>::quality() const
164 {
165  const scalar r = circumCircle().second();
166 
167  // Invalid. Return zero.
168  if (r < 0) return 0;
169 
170  static const scalar sqrt3 = sqrt(scalar(3));
171 
172  return mag()/(0.75*sqrt3*sqr(min(r, great)) + rootVSmall);
173 }
174 
175 
176 template<class Point, class PointRef>
178 (
179  const triangle& t
180 ) const
181 {
182  return (1.0/12.0)*
183  (
184  ((t.a_ - a_) & ((b_ - a_)^(c_ - a_)))
185  + ((t.b_ - b_) & ((c_ - b_)^(t.a_ - b_)))
186  + ((c_ - t.c_) & ((t.b_ - t.c_)^(t.a_ - t.c_)))
187 
188  + ((t.a_ - a_) & ((b_ - a_)^(c_ - a_)))
189  + ((b_ - t.b_) & ((t.a_ - t.b_)^(t.c_ - t.b_)))
190  + ((c_ - t.c_) & ((b_ - t.c_)^(t.a_ - t.c_)))
191  );
192 }
193 
194 
195 template<class Point, class PointRef>
197 (
198  PointRef refPt,
199  scalar density
200 ) const
201 {
202  const Point aRel = a_ - refPt;
203  const Point bRel = b_ - refPt;
204  const Point cRel = c_ - refPt;
205 
206  const tensor V
207  (
208  aRel.x(), aRel.y(), aRel.z(),
209  bRel.x(), bRel.y(), bRel.z(),
210  cRel.x(), cRel.y(), cRel.z()
211  );
212 
213  const scalar a = Foam::mag((b_ - a_)^(c_ - a_));
214  const symmTensor S = 1/24.0*(symmTensor::one + I);
215 
216  return
217  (
218  a*I/24.0*
219  (
220  (aRel & aRel)
221  + (bRel & bRel)
222  + (cRel & cRel)
223  + ((aRel + bRel + cRel) & (aRel + bRel + cRel))
224  )
225  - a*symm(V.T() & S & V)
226  )*density;
227 }
228 
229 
230 template<class Point, class PointRef>
232 (
234 ) const
235 {
236  return barycentricToPoint(barycentric2D01(rndGen));
237 }
238 
239 
240 template<class Point, class PointRef>
242 (
243  const barycentric2D& bary
244 ) const
245 {
246  return bary[0]*a_ + bary[1]*b_ + bary[2]*c_;
247 }
248 
249 
250 template<class Point, class PointRef>
252 (
253  const point& pt
254 ) const
255 {
256  barycentric2D bary;
257  pointToBarycentric(pt, bary);
258  return bary;
259 }
260 
261 
262 template<class Point, class PointRef>
264 (
265  const point& pt,
266  barycentric2D& bary
267 ) const
268 {
269  // Reference:
270  // Real-time collision detection, Christer Ericson, 2005, p47-48
271 
272  vector v0 = b_ - a_;
273  vector v1 = c_ - a_;
274  vector v2 = pt - a_;
275 
276  scalar d00 = v0 & v0;
277  scalar d01 = v0 & v1;
278  scalar d11 = v1 & v1;
279  scalar d20 = v2 & v0;
280  scalar d21 = v2 & v1;
281 
282  scalar denom = d00*d11 - d01*d01;
283 
284  if (Foam::mag(denom) < small)
285  {
286  // Degenerate triangle, returning 1/3 barycentric coordinates.
287 
288  bary = barycentric2D(1.0/3.0, 1.0/3.0, 1.0/3.0);
289 
290  return denom;
291  }
292 
293  bary[1] = (d11*d20 - d01*d21)/denom;
294  bary[2] = (d00*d21 - d01*d20)/denom;
295  bary[0] = 1.0 - bary[1] - bary[2];
296 
297  return denom;
298 }
299 
300 
301 template<class Point, class PointRef>
303 (
304  const point& p,
305  const vector& q,
306  const intersection::algorithm alg,
307  const intersection::direction dir
308 ) const
309 {
310  // Express triangle in terms of baseVertex (point a_) and
311  // two edge vectors
312  const vector E0 = b_ - a_;
313  const vector E1 = c_ - a_;
314 
315  // Initialise intersection to miss.
316  pointHit inter(p);
317 
318  vector n(0.5*(E0 ^ E1));
319  const scalar magArea = Foam::mag(n);
320 
321  if (magArea < vSmall)
322  {
323  // Ineligible miss.
324  inter.setMiss(false);
325 
326  // The miss point is the nearest point on the triangle. Take any one.
327  inter.setPoint(a_);
328 
329  // The distance to the miss is the distance between the
330  // original point and plane of intersection. No normal so use
331  // distance from p to a_
332  inter.setDistance(Foam::mag(a_ - p));
333 
334  return inter;
335  }
336 
337  const vector q1 = q/Foam::mag(q);
338 
340  {
341  n /= magArea;
342 
343  return ray(p, q1 - n, alg, intersection::direction::vector);
344  }
345 
346  // Intersection point with triangle plane
347  point pInter;
348 
349  // Is intersection point inside triangle
350  bool hit;
351  {
352  // Reuse the fast ray intersection routine below in algorithm::fullRay
353  // mode since the original intersection routine has rounding problems.
354  pointHit fastInter = intersection
355  (
356  p,
357  q1,
359  );
360  hit = fastInter.hit();
361 
362  if (hit)
363  {
364  pInter = fastInter.rawPoint();
365  }
366  else
367  {
368  // Calculate intersection of ray with triangle plane
369  vector v = a_ - p;
370  pInter = p + (q1&v)*q1;
371  }
372  }
373 
374  // Distance to intersection point
375  const scalar dist = q1 & (pInter - p);
376 
377  const scalar planarPointTol =
378  Foam::min
379  (
380  Foam::min
381  (
382  Foam::mag(E0),
383  Foam::mag(E1)
384  ),
385  Foam::mag(c_ - b_)
387 
388  bool eligible =
390  || (alg == intersection::algorithm::halfRay && dist > -planarPointTol)
391  || (
393  && ((q1 & area()) < -vSmall)
394  );
395 
396  if (hit && eligible)
397  {
398  // Hit. Set distance to intersection.
399  inter.setHit();
400  inter.setPoint(pInter);
401  inter.setDistance(dist);
402  }
403  else
404  {
405  // Miss or ineligible hit.
406  inter.setMiss(eligible);
407 
408  // The miss point is the nearest point on the triangle
409  inter.setPoint(nearestPoint(p).rawPoint());
410 
411  // The distance to the miss is the distance between the
412  // original point and plane of intersection
413  inter.setDistance(Foam::mag(pInter - p));
414  }
415 
416  return inter;
417 }
418 
419 
420 // From "Fast, Minimum Storage Ray/Triangle Intersection"
421 // Moeller/Trumbore.
422 template<class Point, class PointRef>
424 (
425  const point& orig,
426  const vector& dir,
427  const intersection::algorithm alg,
428  const scalar tol
429 ) const
430 {
431  const vector edge1 = b_ - a_;
432  const vector edge2 = c_ - a_;
433 
434  // Begin calculating determinant - also used to calculate U parameter
435  const vector pVec = dir ^ edge2;
436 
437  // Ff determinant is near zero, ray lies in plane of triangle
438  const scalar det = edge1 & pVec;
439 
440  // Initialise to miss
441  pointHit intersection(false, Zero, great, false);
442 
444  {
445  // Culling branch
446  if (det < rootVSmall)
447  {
448  // Ray on wrong side of triangle. Return miss
449  return intersection;
450  }
451  }
452  else if
453  (
456  )
457  {
458  // Non-culling branch
459  if (det > -rootVSmall && det < rootVSmall)
460  {
461  // Ray parallel to triangle. Return miss
462  return intersection;
463  }
464  }
465 
466  const scalar inv_det = 1.0 / det;
467 
468  // Calculate distance from a_ to ray origin
469  const vector tVec = orig-a_;
470 
471  // Calculate U parameter and test bounds
472  const scalar u = (tVec & pVec)*inv_det;
473 
474  if (u < -tol || u > 1.0+tol)
475  {
476  // return miss
477  return intersection;
478  }
479 
480  // Prepare to test V parameter
481  const vector qVec = tVec ^ edge1;
482 
483  // Calculate V parameter and test bounds
484  const scalar v = (dir & qVec) * inv_det;
485 
486  if (v < -tol || u + v > 1.0+tol)
487  {
488  // return miss
489  return intersection;
490  }
491 
492  // Calculate t, scale parameters, ray intersects triangle
493  const scalar t = (edge2 & qVec) * inv_det;
494 
495  if (alg == intersection::algorithm::halfRay && t < -tol)
496  {
497  // Wrong side of orig. Return miss
498  return intersection;
499  }
500 
501  intersection.setHit();
502  intersection.setPoint(a_ + u*edge1 + v*edge2);
503  intersection.setDistance(t);
504 
505  return intersection;
506 }
507 
508 
509 template<class Point, class PointRef>
511 (
512  const point& p,
513  label& nearType,
514  label& nearLabel
515 ) const
516 {
517  // Adapted from:
518  // Real-time collision detection, Christer Ericson, 2005, p136-142
519 
520  // Check if P in vertex region outside A
521  vector ab = b_ - a_;
522  vector ac = c_ - a_;
523  vector ap = p - a_;
524 
525  scalar d1 = ab & ap;
526  scalar d2 = ac & ap;
527 
528  if (d1 <= 0.0 && d2 <= 0.0)
529  {
530  // barycentric coordinates (1, 0, 0)
531 
532  nearType = POINT;
533  nearLabel = 0;
534  return pointHit(false, a_, Foam::mag(a_ - p), true);
535  }
536 
537  // Check if P in vertex region outside B
538  vector bp = p - b_;
539  scalar d3 = ab & bp;
540  scalar d4 = ac & bp;
541 
542  if (d3 >= 0.0 && d4 <= d3)
543  {
544  // barycentric coordinates (0, 1, 0)
545 
546  nearType = POINT;
547  nearLabel = 1;
548  return pointHit(false, b_, Foam::mag(b_ - p), true);
549  }
550 
551  // Check if P in edge region of AB, if so return projection of P onto AB
552  scalar vc = d1*d4 - d3*d2;
553 
554  if (vc <= 0.0 && d1 >= 0.0 && d3 <= 0.0)
555  {
556  if ((d1 - d3) < rootVSmall)
557  {
558  // Degenerate triangle, for d1 = d3, a_ and b_ are likely coincident
559  nearType = POINT;
560  nearLabel = 0;
561  return pointHit(false, a_, Foam::mag(a_ - p), true);
562  }
563 
564  // barycentric coordinates (1-v, v, 0)
565  scalar v = d1/(d1 - d3);
566 
567  point nearPt = a_ + v*ab;
568  nearType = EDGE;
569  nearLabel = 0;
570  return pointHit(false, nearPt, Foam::mag(nearPt - p), true);
571  }
572 
573  // Check if P in vertex region outside C
574  vector cp = p - c_;
575  scalar d5 = ab & cp;
576  scalar d6 = ac & cp;
577 
578  if (d6 >= 0.0 && d5 <= d6)
579  {
580  // barycentric coordinates (0, 0, 1)
581 
582  nearType = POINT;
583  nearLabel = 2;
584  return pointHit(false, c_, Foam::mag(c_ - p), true);
585  }
586 
587  // Check if P in edge region of AC, if so return projection of P onto AC
588  scalar vb = d5*d2 - d1*d6;
589 
590  if (vb <= 0.0 && d2 >= 0.0 && d6 <= 0.0)
591  {
592  if ((d2 - d6) < rootVSmall)
593  {
594  // Degenerate triangle, for d2 = d6, a_ and c_ are likely coincident
595  nearType = POINT;
596  nearLabel = 0;
597  return pointHit(false, a_, Foam::mag(a_ - p), true);
598  }
599 
600  // barycentric coordinates (1-w, 0, w)
601  scalar w = d2/(d2 - d6);
602 
603  point nearPt = a_ + w*ac;
604  nearType = EDGE;
605  nearLabel = 2;
606  return pointHit(false, nearPt, Foam::mag(nearPt - p), true);
607  }
608 
609  // Check if P in edge region of BC, if so return projection of P onto BC
610  scalar va = d3*d6 - d5*d4;
611 
612  if (va <= 0.0 && (d4 - d3) >= 0.0 && (d5 - d6) >= 0.0)
613  {
614  if (((d4 - d3) + (d5 - d6)) < rootVSmall)
615  {
616  // Degenerate triangle, for (d4 - d3) = (d6 - d5), b_ and c_ are
617  // likely coincident
618  nearType = POINT;
619  nearLabel = 1;
620  return pointHit(false, b_, Foam::mag(b_ - p), true);
621  }
622 
623  // barycentric coordinates (0, 1-w, w)
624  scalar w = (d4 - d3)/((d4 - d3) + (d5 - d6));
625 
626  point nearPt = b_ + w*(c_ - b_);
627  nearType = EDGE;
628  nearLabel = 1;
629  return pointHit(false, nearPt, Foam::mag(nearPt - p), true);
630  }
631 
632  // P inside face region. Compute Q through its barycentric
633  // coordinates (u, v, w)
634 
635  if ((va + vb + vc) < rootVSmall)
636  {
637  // Degenerate triangle, return the centre because no edge or points are
638  // closest
639  point nearPt = centre();
640  nearType = NONE,
641  nearLabel = -1;
642  return pointHit(true, nearPt, Foam::mag(nearPt - p), false);
643  }
644 
645  scalar denom = 1.0/(va + vb + vc);
646  scalar v = vb * denom;
647  scalar w = vc * denom;
648 
649  // = u*a + v*b + w*c, u = va*denom = 1.0 - v - w
650 
651  point nearPt = a_ + ab*v + ac*w;
652  nearType = NONE,
653  nearLabel = -1;
654  return pointHit(true, nearPt, Foam::mag(nearPt - p), false);
655 }
656 
657 
658 template<class Point, class PointRef>
660 (
661  const point& p
662 ) const
663 {
664  // Dummy labels
665  label nearType = -1;
666  label nearLabel = -1;
667 
668  return nearestPointClassify(p, nearType, nearLabel);
669 }
670 
671 
672 template<class Point, class PointRef>
674 (
675  const point& p,
676  label& nearType,
677  label& nearLabel
678 ) const
679 {
680  return nearestPointClassify(p, nearType, nearLabel).hit();
681 }
682 
683 
684 template<class Point, class PointRef>
686 (
687  const linePointRef& ln,
688  pointHit& lnInfo
689 ) const
690 {
691  vector q = ln.vec();
692  pointHit triInfo
693  (
695  (
696  ln.start(),
697  q,
699  )
700  );
701 
702  if (triInfo.hit())
703  {
704  // Line hits triangle. Find point on line.
705  if (triInfo.distance() > 1)
706  {
707  // Hit beyond endpoint
708  lnInfo.setMiss(true);
709  lnInfo.setPoint(ln.end());
710  scalar dist = Foam::mag(triInfo.hitPoint()-lnInfo.missPoint());
711  lnInfo.setDistance(dist);
712  triInfo.setMiss(true);
713  triInfo.setDistance(dist);
714  }
715  else if (triInfo.distance() < 0)
716  {
717  // Hit beyond startpoint
718  lnInfo.setMiss(true);
719  lnInfo.setPoint(ln.start());
720  scalar dist = Foam::mag(triInfo.hitPoint()-lnInfo.missPoint());
721  lnInfo.setDistance(dist);
722  triInfo.setMiss(true);
723  triInfo.setDistance(dist);
724  }
725  else
726  {
727  // Hit on line
728  lnInfo.setHit();
729  lnInfo.setPoint(triInfo.hitPoint());
730  lnInfo.setDistance(0.0);
731  triInfo.setDistance(0.0);
732  }
733  }
734  else
735  {
736  // Line skips triangle. See which triangle edge it gets closest to
737 
738  point nearestEdgePoint;
739  point nearestLinePoint;
740  // label minEdgeIndex = 0;
741  scalar minDist = ln.nearestDist
742  (
743  linePointRef(a_, b_),
744  nearestLinePoint,
745  nearestEdgePoint
746  );
747 
748  {
749  point linePoint;
750  point triEdgePoint;
751  scalar dist = ln.nearestDist
752  (
753  linePointRef(b_, c_),
754  linePoint,
755  triEdgePoint
756  );
757  if (dist < minDist)
758  {
759  minDist = dist;
760  nearestEdgePoint = triEdgePoint;
761  nearestLinePoint = linePoint;
762  // minEdgeIndex = 1;
763  }
764  }
765 
766  {
767  point linePoint;
768  point triEdgePoint;
769  scalar dist = ln.nearestDist
770  (
771  linePointRef(c_, a_),
772  linePoint,
773  triEdgePoint
774  );
775  if (dist < minDist)
776  {
777  minDist = dist;
778  nearestEdgePoint = triEdgePoint;
779  nearestLinePoint = linePoint;
780  // minEdgeIndex = 2;
781  }
782  }
783 
784  lnInfo.setDistance(minDist);
785  triInfo.setDistance(minDist);
786  triInfo.setMiss(false);
787  triInfo.setPoint(nearestEdgePoint);
788 
789  // Convert point on line to pointHit
790  if (Foam::mag(nearestLinePoint-ln.start()) < small)
791  {
792  lnInfo.setMiss(true);
793  lnInfo.setPoint(ln.start());
794  }
795  else if (Foam::mag(nearestLinePoint-ln.end()) < small)
796  {
797  lnInfo.setMiss(true);
798  lnInfo.setPoint(ln.end());
799  }
800  else
801  {
802  lnInfo.setHit();
803  lnInfo.setPoint(nearestLinePoint);
804  }
805  }
806  return triInfo;
807 }
808 
809 
810 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
811 
812 template<class Point, class PointRef>
813 inline Foam::Istream& Foam::operator>>
814 (
815  Istream& is,
817 )
818 {
819  is.readBegin("triangle");
820  is >> t.a_ >> t.b_ >> t.c_;
821  is.readEnd("triangle");
822 
823  is.check("Istream& operator>>(Istream&, triangle&)");
824  return is;
825 }
826 
827 
828 template<class Point, class PointRef>
829 inline Foam::Ostream& Foam::operator<<
830 (
831  Ostream& os,
832  const triangle<Point, PointRef>& t
833 )
834 {
835  os << nl
837  << t.a_ << token::SPACE
838  << t.b_ << token::SPACE
839  << t.c_
840  << token::END_LIST;
841 
842  return os;
843 }
844 
845 
846 // ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
label n
Templated 2D Barycentric derived from VectorSpace. Has 3 components, one of which is redundant.
Definition: Barycentric2D.H:53
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:108
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
Istream & readEnd(const char *funcName)
Definition: Istream.C:123
Istream & readBegin(const char *funcName)
Definition: Istream.C:106
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
const Point & hitPoint() const
Return hit point.
Definition: PointHit.H:126
void setPoint(const Point &p)
Definition: PointHit.H:181
void setDistance(const scalar d)
Definition: PointHit.H:186
scalar distance() const
Return distance to hit.
Definition: PointHit.H:139
const Point & rawPoint() const
Return point with no checking.
Definition: PointHit.H:158
const Point & missPoint() const
Return miss point.
Definition: PointHit.H:145
void setMiss(const bool eligible)
Definition: PointHit.H:175
bool hit() const
Is there a hit.
Definition: PointHit.H:120
void setHit()
Definition: PointHit.H:169
Tensor< Cmpt > T() const
Return transpose.
Definition: TensorI.H:331
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:66
const Type2 & second() const
Return second.
Definition: Tuple2.H:131
const Type1 & first() const
Return first.
Definition: Tuple2.H:119
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:74
static const Form one
Definition: VectorSpace.H:119
static Form uniform(const Cmpt &s)
Return a VectorSpace with all elements = s.
Definition: VectorSpaceI.H:168
Foam::intersection.
Definition: intersection.H:50
static scalar planarTol()
Return planar tolerance.
Definition: intersection.H:83
A line primitive.
Definition: line.H:71
Random number generator.
@ BEGIN_LIST
Definition: token.H:110
@ END_LIST
Definition: token.H:111
A triangle primitive used to calculate face areas and swept volumes.
Definition: triangle.H:80
barycentric2D pointToBarycentric(const point &pt) const
Calculate the barycentric coordinates from the given point.
Definition: triangleI.H:252
triangle(const Point &a, const Point &b, const Point &c)
Construct from three points.
Definition: triangleI.H:34
vector area() const
Return vector area.
Definition: triangleI.H:96
Point barycentricToPoint(const barycentric2D &bary) const
Calculate the point from the given barycentric coordinates.
Definition: triangleI.H:242
scalar sweptVol(const triangle &t) const
Return swept-volume.
Definition: triangleI.H:178
const Point & a() const
Return first vertex.
Definition: triangleI.H:70
Point centre() const
Return centre (centroid)
Definition: triangleI.H:89
Tuple2< Point, scalar > circumCircleSqr() const
Return the circum-centre and radius-squared.
Definition: triangleI.H:120
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:511
pointHit ray(const point &p, const vector &q, const intersection::algorithm=intersection::algorithm::fullRay, const intersection::direction dir=intersection::direction::vector) const
Return point intersection with a ray.
Definition: triangleI.H:303
const Point & c() const
Return third vertex.
Definition: triangleI.H:82
scalar mag() const
Return scalar magnitude.
Definition: triangleI.H:103
symmTensor inertia(PointRef refPt=vector::zero, scalar density=1.0) const
Return the inertia tensor, with optional reference.
Definition: triangleI.H:197
pointHit nearestPoint(const point &p) const
Return nearest point to p on triangle.
Definition: triangleI.H:660
Tuple2< Point, scalar > circumCircle() const
Return the circum-centre and radius.
Definition: triangleI.H:151
Point randomPoint(randomGenerator &rndGen) const
Return a random point on the triangle from a uniform.
Definition: triangleI.H:232
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:424
bool classify(const point &p, label &nearType, label &nearLabel) const
Classify nearest point to p in triangle plane.
Definition: triangleI.H:674
vector normal() const
Return unit normal.
Definition: triangleI.H:110
const Point & b() const
Return second vertex.
Definition: triangleI.H:76
scalar quality() const
Return quality: Ratio of triangle and circum-circle.
Definition: triangleI.H:163
const pointField & points
volScalarField & b
Definition: createFields.H:27
const dimensionedScalar c1
First radiation constant: default SI units: [W/m^2].
const dimensionedScalar c2
Second radiation constant: default SI units: [m K].
const dimensionedScalar c
Speed of light in a vacuum.
const dimensionSet density
const dimensionSet area
tmp< fvMatrix< Type > > S(const Pair< tmp< volScalarField::Internal >> &, const VolField< Type > &)
static const zero Zero
Definition: zero.H:97
scalar minDist(const List< pointIndexHit > &hitList)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
line< point, const point & > linePointRef
Line using referred points.
Definition: linePointRef.H:45
static const Identity< scalar > I
Definition: Identity.H:93
Barycentric2D< scalar > barycentric2D
A scalar version of the templated Barycentric2D.
Definition: barycentric2D.H:45
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
void symm(pointPatchField< tensor > &, const pointPatchField< tensor > &)
PointHit< point > pointHit
Definition: pointHit.H:41
void det(pointPatchField< scalar > &, const pointPatchField< tensor > &)
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
bool cp(const fileName &src, const fileName &dst, const bool followLink=true)
Copy, recursively if necessary, the source to the destination.
Definition: POSIX.C:753
void sqrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
static const char nl
Definition: Ostream.H:297
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
Definition: POSIX.C:908
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
barycentric2D barycentric2D01(randomGenerator &rndGen)
Generate a random barycentric coordinate within the unit triangle.
Definition: barycentric2D.C:31
randomGenerator rndGen(653213)
volScalarField & p