bool IntrArc2Circle2<Real>::Find () { m_iQuantity = 0; Circle2<Real> kCircleOfArc(m_pkArc->Center,m_pkArc->Radius); IntrCircle2Circle2<Real> kIntr(*m_pkCircle,kCircleOfArc); if (!kIntr.Find()) { // arc and circle do not intersect m_iIntersectionType = IT_EMPTY; return false; } if (kIntr.GetIntersectionType() == IT_OTHER) { // arc is on the circle m_iIntersectionType = IT_OTHER; return true; } // test if circle-circle intersection points are on the arc for (int i = 0; i < kIntr.GetQuantity(); i++) { if (m_pkArc->Contains(kIntr.GetPoint(i))) { m_akPoint[m_iQuantity++] = kIntr.GetPoint(i); } } m_iIntersectionType = (m_iQuantity > 0 ? IT_POINT : IT_EMPTY); return m_iIntersectionType != IT_EMPTY; }
bool BoundingSphere::IsIntersect( BoundingVolume * pBound ) { switch ( pBound->GetBoundType() ) { case Bounding_Box: { IntrBox3Sphere3f kIntr( ( (BoundingBox *) pBound )->GetBox(), GetSphere() ); return kIntr.Test(); break; } case Bounding_Sphere: { IntrSphere3Sphere3f kIntr( ( (BoundingSphere *) pBound )->GetSphere(), GetSphere() ); return kIntr.Test(); break; } default: break; } return false; }
bool IntrLine2Triangle2<Real>::Find () { Real afDist[3]; int aiSign[3], iPositive, iNegative, iZero; TriangleLineRelations(m_pkLine->Origin,m_pkLine->Direction,*m_pkTriangle, afDist,aiSign,iPositive,iNegative,iZero); if (iPositive == 3 || iNegative == 3) { // No intersections. m_iQuantity = 0; m_iIntersectionType = IT_EMPTY; } else { Real afParam[2]; GetInterval(m_pkLine->Origin,m_pkLine->Direction,*m_pkTriangle,afDist, aiSign,afParam); Intersector1<Real> kIntr(afParam[0],afParam[1], -Math<Real>::MAX_REAL,+Math<Real>::MAX_REAL); kIntr.Find(); m_iQuantity = kIntr.GetQuantity(); if (m_iQuantity == 2) { // Segment intersection. m_iIntersectionType = IT_SEGMENT; m_akPoint[0] = m_pkLine->Origin + kIntr.GetOverlap(0)* m_pkLine->Direction; m_akPoint[1] = m_pkLine->Origin + kIntr.GetOverlap(1)* m_pkLine->Direction; } else if (m_iQuantity == 1) { // Point intersection. m_iIntersectionType = IT_POINT; m_akPoint[0] = m_pkLine->Origin + kIntr.GetOverlap(0)* m_pkLine->Direction; } else { // No intersections. m_iIntersectionType = IT_EMPTY; } } return m_iIntersectionType != IT_EMPTY; }
bool IntrSegment3Sphere3<Real>::Find (Real fTMax, const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1) { // check if initially intersecting if (Find()) { m_fContactTime = (Real)0.0; m_iIntersectionType = IT_OTHER; return true; } // Substract the segment velocity from the sphere velocity so that // the calculations are based in the coordinate system of the segment. // In this system, the line is of course stationary. The sphere spans // a capsule, but instead we will "grow" the segment by the sphere radius // and shrink the sphere to its center. The problem is now to detect // the first time the moving center intersects the capsule formed by // the line segment and sphere radius. Capsule3<Real> kCapsule; kCapsule.Segment = *m_pkSegment; kCapsule.Radius = m_pkSphere->Radius; Vector3<Real> kRelativeVelocity = rkVelocity1 - rkVelocity0; Real fRelativeSpeed = kRelativeVelocity.Normalize(); Segment3<Real> kPath; kPath.Extent = ((Real)0.5)*fTMax*fRelativeSpeed; kPath.Direction = kRelativeVelocity; // unit-length vector kPath.Origin = m_pkSphere->Center + kPath.Extent*kPath.Direction; IntrSegment3Capsule3<Real> kIntr(kPath,kCapsule); if (!kIntr.Find()) { m_iIntersectionType = IT_EMPTY; return false; } // We now know the sphere will intersect the segment. This can happen // either at a segment end point or at a segment interior point. We // need to determine which. m_fContactTime = (kIntr.GetParameter(0) + kPath.Extent)/fRelativeSpeed; m_iQuantity = 1; Vector3<Real> kMCenter = m_pkSphere->Center + m_fContactTime*rkVelocity1; Vector3<Real> kMOrigin = m_pkSegment->Origin + m_fContactTime*rkVelocity0; Real fOrigin = m_pkSegment->Direction.Dot(kMOrigin); Real fNegEnd = fOrigin - m_pkSegment->Extent; Real fPosEnd = fOrigin + m_pkSegment->Extent; Real fCenter = m_pkSegment->Direction.Dot(kMCenter); if (fCenter < fNegEnd) { // intersection at segment end point P-e*D m_akPoint[0] = kMOrigin - m_pkSegment->Extent*m_pkSegment->Direction; } else if (fCenter > fPosEnd) { // intersection at segment end point P+e*D m_akPoint[0] = kMOrigin + m_pkSegment->Extent*m_pkSegment->Direction; } else { // Intersection with interior point on edge. Use the projection // along direction axis to find which point that is. m_akPoint[0] = kMOrigin + (fCenter - fOrigin)*m_pkSegment->Direction; } return true; }