void Foam::momentOfInertia::massPropertiesShell ( const pointField& pts, const triFaceList& triFaces, scalar density, scalar& mass, vector& cM, tensor& J ) { // Reset properties for accumulation mass = 0.0; cM = vector::zero; J = tensor::zero; // Find centre of mass forAll(triFaces, i) { const triFace& tri(triFaces[i]); triPointRef t ( pts[tri[0]], pts[tri[1]], pts[tri[2]] ); scalar triMag = t.mag(); cM += triMag*t.centre(); mass += triMag; } cM /= mass; mass *= density; // Find inertia around centre of mass forAll(triFaces, i) { const triFace& tri(triFaces[i]); J += triPointRef ( pts[tri[0]], pts[tri[1]], pts[tri[2]] ).inertia(cM, density); } }
Foam::pointHit Foam::face::fastIntersection ( const point& p, const vector& q, const point& ctr, const pointField& meshPoints, const intersection::algorithm alg, const scalar tol ) const { scalar nearestHitDist = VGREAT; // Initialize to miss, distance = GREAT pointHit nearest(p); const labelList& f = *this; forAll(f, pI) { // Note: for best accuracy, centre point always comes last pointHit curHit = triPointRef ( meshPoints[f[pI]], meshPoints[f[fcIndex(pI)]], ctr ).fastIntersection(p, q, alg, tol); if (curHit.hit()) { if (Foam::mag(curHit.distance()) < nearestHitDist) { nearestHitDist = Foam::mag(curHit.distance()); nearest.setHit(); nearest.setPoint(curHit.hitPoint()); } } }
Foam::pointHit Foam::tetrahedron<Point, PointRef>::containmentSphere ( const scalar tol ) const { // (Probably very inefficient) minimum containment sphere calculation. // From http://www.imr.sandia.gov/papers/imr11/shewchuk2.pdf: // Sphere ctr is smallest one of // - tet circumcentre // - triangle circumcentre // - edge mids const scalar fac = 1 + tol; // Halve order of tolerance for comparisons of sqr. const scalar facSqr = Foam::sqrt(fac); // 1. Circumcentre itself. pointHit pHit(circumCentre()); pHit.setHit(); scalar minRadiusSqr = magSqr(pHit.rawPoint() - a_); // 2. Try circumcentre of tet triangles. Create circumcircle for triFace and // check if 4th point is inside. { point ctr = triPointRef(a_, b_, c_).circumCentre(); scalar radiusSqr = magSqr(ctr - a_); if ( radiusSqr < minRadiusSqr && Foam::magSqr(d_-ctr) <= facSqr*radiusSqr ) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } { point ctr = triPointRef(a_, b_, d_).circumCentre(); scalar radiusSqr = magSqr(ctr - a_); if ( radiusSqr < minRadiusSqr && Foam::magSqr(c_-ctr) <= facSqr*radiusSqr ) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } { point ctr = triPointRef(a_, c_, d_).circumCentre(); scalar radiusSqr = magSqr(ctr - a_); if ( radiusSqr < minRadiusSqr && Foam::magSqr(b_-ctr) <= facSqr*radiusSqr ) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } { point ctr = triPointRef(b_, c_, d_).circumCentre(); scalar radiusSqr = magSqr(ctr - b_); if ( radiusSqr < minRadiusSqr && Foam::magSqr(a_-ctr) <= facSqr*radiusSqr ) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } // 3. Try midpoints of edges // mid of edge A-B { point ctr = 0.5*(a_ + b_); scalar radiusSqr = magSqr(a_ - ctr); scalar testRadSrq = facSqr*radiusSqr; if ( radiusSqr < minRadiusSqr && magSqr(c_-ctr) <= testRadSrq && magSqr(d_-ctr) <= testRadSrq) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } // mid of edge A-C { point ctr = 0.5*(a_ + c_); scalar radiusSqr = magSqr(a_ - ctr); scalar testRadSrq = facSqr*radiusSqr; if ( radiusSqr < minRadiusSqr && magSqr(b_-ctr) <= testRadSrq && magSqr(d_-ctr) <= testRadSrq ) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } // mid of edge A-D { point ctr = 0.5*(a_ + d_); scalar radiusSqr = magSqr(a_ - ctr); scalar testRadSrq = facSqr*radiusSqr; if ( radiusSqr < minRadiusSqr && magSqr(b_-ctr) <= testRadSrq && magSqr(c_-ctr) <= testRadSrq ) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } // mid of edge B-C { point ctr = 0.5*(b_ + c_); scalar radiusSqr = magSqr(b_ - ctr); scalar testRadSrq = facSqr*radiusSqr; if ( radiusSqr < minRadiusSqr && magSqr(a_-ctr) <= testRadSrq && magSqr(d_-ctr) <= testRadSrq ) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } // mid of edge B-D { point ctr = 0.5*(b_ + d_); scalar radiusSqr = magSqr(b_ - ctr); scalar testRadSrq = facSqr*radiusSqr; if ( radiusSqr < minRadiusSqr && magSqr(a_-ctr) <= testRadSrq && magSqr(c_-ctr) <= testRadSrq) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } // mid of edge C-D { point ctr = 0.5*(c_ + d_); scalar radiusSqr = magSqr(c_ - ctr); scalar testRadSrq = facSqr*radiusSqr; if ( radiusSqr < minRadiusSqr && magSqr(a_-ctr) <= testRadSrq && magSqr(b_-ctr) <= testRadSrq ) { pHit.setMiss(false); pHit.setPoint(ctr); minRadiusSqr = radiusSqr; } } pHit.setDistance(sqrt(minRadiusSqr)); return pHit; }
Foam::pointHit Foam::face::ray ( const point& p, const vector& n, const pointField& meshPoints, const intersection::algorithm alg, const intersection::direction dir ) const { point ctr = Foam::average(points(meshPoints)); scalar nearestHitDist = GREAT; scalar nearestMissDist = GREAT; bool eligible = false; // Initialize to miss, distance = GREAT pointHit nearest(p); const labelList& f = *this; label nPoints = size(); point nextPoint = ctr; for (label pI = 0; pI < nPoints; pI++) { nextPoint = meshPoints[f[fcIndex(pI)]]; // Note: for best accuracy, centre point always comes last // HJ, 9/Sep/2001 pointHit curHit = triPointRef ( meshPoints[f[pI]], nextPoint, ctr ).ray(p, n, alg, dir); if (curHit.hit()) { if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist)) { nearestHitDist = curHit.distance(); nearest.setHit(); nearest.setPoint(curHit.hitPoint()); } } else if (!nearest.hit()) { // Miss and no hit yet. Update miss statistics. if (curHit.eligibleMiss()) { eligible = true; // Miss distance is the distance between the plane intersection // point and the nearest point of the triangle scalar missDist = Foam::mag ( p + curHit.distance()*n - curHit.missPoint() ); if (missDist < nearestMissDist) { nearestMissDist = missDist; nearest.setDistance(curHit.distance()); nearest.setPoint(curHit.missPoint()); } } } } if (nearest.hit()) { nearest.setDistance(nearestHitDist); } else { // Haven't hit a single face triangle nearest.setMiss(eligible); } return nearest; }