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-------------------------------------------------------------------------------
11License
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"
33
34// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35
36template<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
50template<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
62template<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
76template<class Point, class PointRef>
78{
79 is >> *this;
80}
81
82
83// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
84
85template<class Point, class PointRef>
87{
88 return a_;
89}
90
91template<class Point, class PointRef>
93{
94 return b_;
95}
96
97template<class Point, class PointRef>
99{
100 return c_;
101}
102
103
104template<class Point, class PointRef>
106{
107 return (1.0/3.0)*(a_ + b_ + c_);
108}
109
110
111template<class Point, class PointRef>
113{
114 return 0.5*((b_ - a_)^(c_ - a_));
115}
116
117
118template<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
127template<class Point, class PointRef>
128inline Foam::scalar Foam::triangle<Point, PointRef>::mag() const
129{
130 return ::Foam::mag(areaNormal());
131}
132
133
134template<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
161template<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
182template<class Point, class PointRef>
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
197template<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
216template<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
253template<class Point, class PointRef>
255{
256 return barycentricToPoint(barycentric2D01(rndGen));
257}
258
259
260template<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
270template<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
282template<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
321template<class Point, class PointRef>
323(
324 const point& p,
325 const vector& q,
326 const intersection::algorithm alg,
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
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.
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 =
393 (
395 (
396 Foam::mag(E0),
397 Foam::mag(E1)
398 ),
399 Foam::mag(c_ - b_)
401
402 bool eligible =
404 || (alg == intersection::HALF_RAY && dist > -planarPointTol)
405 || (
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.
437template<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
520template<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
669template<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
683template<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
695template<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,
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
821template<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
834template<class Point, class PointRef>
836(
837 const triPoints&
838)
839{}
840
841
842template<class Point, class PointRef>
844:
845 area_(0.0)
846{}
847
848
849template<class Point, class PointRef>
851(
852 const triPoints& tri
853)
854{
855 area_ += triangle<Point, const Point&>(tri).mag();
856}
857
858
859template<class Point, class PointRef>
861(
863 label& nTris
864)
865:
866 tris_(tris),
867 nTris_(nTris)
868{}
869
870
871template<class Point, class PointRef>
873(
874 const triPoints& tri
875)
876{
877 tris_[nTris_++] = tri;
878}
879
880
881template<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
896template<class Point, class PointRef>
897inline 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
912template<class Point, class PointRef>
913inline 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_
925
926 return os;
927}
928
929
930// ************************************************************************* //
CGAL::Point_3< K > Point
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:57
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: FixedList.H:81
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
bool readBegin(const char *funcName)
Begin read of data chunk, starts with '('.
Definition: Istream.C:111
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
Describes the interaction of a face and a point. It carries the info of a successful hit and (if succ...
Definition: PointHit.H:54
void setHit() noexcept
Set the hit status on.
Definition: PointHit.H:181
const point_type & rawPoint() const noexcept
The point, no checks.
Definition: PointHit.H:172
scalar distance() const noexcept
Return distance to hit.
Definition: PointHit.H:139
void setPoint(const point_type &p)
Set the point.
Definition: PointHit.H:195
void setDistance(const scalar d) noexcept
Set the distance.
Definition: PointHit.H:201
const point_type & missPoint() const
Return the miss point. Fatal if hit.
Definition: PointHit.H:158
bool hit() const noexcept
Is there a hit.
Definition: PointHit.H:121
void setMiss(const bool eligible) noexcept
Set the hit status off and set the eligible miss status.
Definition: PointHit.H:188
const point_type & hitPoint() const
Return the hit point. Fatal if not hit.
Definition: PointHit.H:145
Random number generator.
Definition: Random.H:60
Tensor< Cmpt > T() const
Return non-Hermitian transpose.
Definition: TensorI.H:526
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:94
friend complex sign(const complex &c)
sgn() https://en.wikipedia.org/wiki/Sign_function#Complex_signum
Definition: complexI.H:228
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
Foam::intersection.
Definition: intersection.H:53
static scalar planarTol()
Return planar tolerance.
Definition: intersection.H:88
A line primitive.
Definition: line.H:68
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:62
A reference point and direction.
Definition: plane.H:110
Store resulting tets.
Definition: tetrahedron.H:120
@ BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
@ END_LIST
End list [isseparator].
Definition: token.H:156
@ SPACE
Space [isspace].
Definition: token.H:125
Triangle storage. Null constructable (unfortunately triangle<point, point> is not)
Definition: triPoints.H:55
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:80
Point circumCentre() const
Return circum-centre.
Definition: triangleI.H:135
barycentric2D pointToBarycentric(const point &pt) const
Calculate the barycentric coordinates from the given point.
Definition: triangleI.H:272
scalar circumRadius() const
Return circum-radius.
Definition: triangleI.H:162
Point barycentricToPoint(const barycentric2D &bary) const
Calculate the point from the given barycentric coordinates.
Definition: triangleI.H:262
scalar sweptVol(const triangle &t) const
Return swept-volume.
Definition: triangleI.H:199
vector areaNormal() const
The area normal - with magnitude equal to area of triangle.
Definition: triangleI.H:112
const Point & a() const
Return first vertex.
Definition: triangleI.H:86
Point centre() const
Return centre (centroid)
Definition: triangleI.H:105
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
vector unitNormal() const
Return unit normal.
Definition: triangleI.H:119
const Point & c() const
Return third vertex.
Definition: triangleI.H:98
tensor inertia(PointRef refPt=Zero, scalar density=1.0) const
Return the inertia tensor, with optional reference.
Definition: triangleI.H:218
scalar mag() const
Return scalar magnitude.
Definition: triangleI.H:128
pointHit nearestPoint(const point &p) const
Return nearest point to p on triangle.
Definition: triangleI.H:671
Point randomPoint(Random &rndGen) const
Return a random point on the triangle from a uniform.
Definition: triangleI.H:254
bool classify(const point &p, label &nearType, label &nearLabel) const
Classify nearest point to p in triangle plane.
Definition: triangleI.H:685
const Point & b() const
Return second vertex.
Definition: triangleI.H:92
scalar quality() const
Return quality: Ratio of triangle and circum-circle.
Definition: triangleI.H:183
volScalarField & p
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
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))
#define FUNCTION_NAME
dimensionedScalar det(const dimensionedSphericalTensor &dt)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
barycentric2D barycentric2D01(Random &rndGen)
Generate a random barycentric coordinate within the unit triangle.
Definition: barycentric2D.C:55
dimensionedSymmTensor sqr(const dimensionedVector &dv)
line< point, const point & > linePointRef
A line using referred points.
Definition: linePointRef.H:47
static const Identity< scalar > I
Definition: Identity.H:94
Barycentric2D< scalar > barycentric2D
A scalar version of the templated Barycentric2D.
Definition: barycentric2D.H:52
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
PointHit< point > pointHit
A PointIndexHit for 3D points.
Definition: pointHit.H:44
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
Definition: MSwindows.C:933
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
const volScalarField & cp
volScalarField & b
Definition: createFields.H:27
Random rndGen
Definition: createFields.H:23