bool IntrSphere3Sphere3<Real>::Test ( Real tmax,
                                          const Vector3<Real>& velocity0, const Vector3<Real>& velocity1 )
    {
        Vector3<Real> relVelocity = velocity1 - velocity0;
        Real a = relVelocity.SquaredLength();
        Vector3<Real> CDiff = mSphere1->Center - mSphere0->Center;
        Real c = CDiff.SquaredLength();
        Real rSum = mSphere0->Radius + mSphere1->Radius;
        Real rSumSqr = rSum * rSum;

        if ( a > ( Real )0 )
        {
            Real b = CDiff.Dot( relVelocity );
            if ( b <= ( Real )0 )
            {
                if ( -tmax * a <= b )
                {
                    return a * c - b * b <= a * rSumSqr;
                }
                else
                {
                    return tmax * ( tmax * a + ( ( Real )2 ) * b ) + c <= rSumSqr;
                }
            }
        }

        return c <= rSumSqr;
    }
bool IntrSphere3Sphere3<Real>::Test (Real fTMax,
    const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1)
{
    Vector3<Real> kVDiff = rkVelocity1 - rkVelocity0;
    Real fA = kVDiff.SquaredLength();
    Vector3<Real> kCDiff = m_rkSphere1.Center - m_rkSphere0.Center;
    Real fC = kCDiff.SquaredLength();
    Real fRSum = m_rkSphere0.Radius + m_rkSphere1.Radius;
    Real fRSumSqr = fRSum*fRSum;

    if (fA > (Real)0.0)
    {
        Real fB = kCDiff.Dot(kVDiff);
        if (fB <= (Real)0.0)
        {
            if (-fTMax*fA <= fB)
            {
                return fA*fC - fB*fB <= fA*fRSumSqr;
            }
            else
            {
                return fTMax*(fTMax*fA + ((Real)2.0)*fB) + fC <= fRSumSqr;
            }
        }
    }

    return fC <= fRSumSqr;
}
Example #3
0
bool Wml::TestIntersection (const Sphere3<Real>& rkS0,
    const Sphere3<Real>& rkS1, Real fTime, const Vector3<Real>& rkV0,
    const Vector3<Real>& rkV1)
{
    Vector3<Real> kVDiff = rkV1 - rkV0;
    Real fA = kVDiff.SquaredLength();
    Vector3<Real> kCDiff = rkS1.Center() - rkS0.Center();
    Real fC = kCDiff.SquaredLength();
    Real fRSum = rkS0.Radius() + rkS1.Radius();
    Real fRSumSqr = fRSum*fRSum;

    if ( fA > (Real)0.0 )
    {
        Real fB = kCDiff.Dot(kVDiff);
        if ( fB <= (Real)0.0 )
        {
            if ( -fTime*fA <= fB )
                return fA*fC - fB*fB <= fA*fRSumSqr;
            else
                return fTime*(fTime*fA + ((Real)2.0)*fB) + fC <= fRSumSqr;
        }
    }

    return fC <= fRSumSqr;
}
Example #4
0
bool Wml::FindIntersection (const Sphere3<Real>& rkS0,
    const Sphere3<Real>& rkS1, Vector3<Real>& rkU, Vector3<Real>& rkV,
    Vector3<Real>& rkC, Real& rfR)
{
    // plane of intersection must have N as its normal
    Vector3<Real> kN = rkS1.Center() - rkS0.Center();
    Real fNSqrLen = kN.SquaredLength();
    Real fRSum = rkS0.Radius() + rkS1.Radius();
    if ( fNSqrLen > fRSum*fRSum )
    {
        // sphere centers are too far apart for intersection
        return false;
    }

    Real fR0Sqr = rkS0.Radius()*rkS0.Radius();
    Real fR1Sqr = rkS1.Radius()*rkS1.Radius();
    Real fInvNSqrLen = ((Real)1.0)/fNSqrLen;
    Real fT = ((Real)0.5)*((Real)1.0+(fR0Sqr-fR1Sqr)*fInvNSqrLen);
    if ( fT < (Real)0.0 || fT > (Real)1.0 )
        return false;

    Real fRSqr = fR0Sqr - fT*fT*fNSqrLen;
    if ( fRSqr < (Real)0.0 )
        return false;

    // center and radius of circle of intersection
    rkC = rkS0.Center() + fT*kN;
    rfR = Math<Real>::Sqrt(fRSqr);

    // compute U and V for plane of circle
    kN *= Math<Real>::Sqrt(fInvNSqrLen);
    Vector3<Real>::GenerateOrthonormalBasis(rkU,rkV,kN,true);

    return true;
}
Example #5
0
Real Mgc::SqrDistance (const Vector3& rkPoint, const Line3& rkLine,

    Real* pfParam)

{

    Vector3 kDiff = rkPoint - rkLine.Origin();

    Real fSqrLen = rkLine.Direction().SquaredLength();

    Real fT = kDiff.Dot(rkLine.Direction())/fSqrLen;

    kDiff -= fT*rkLine.Direction();



    if ( pfParam )

        *pfParam = fT;



    return kDiff.SquaredLength();

}
Example #6
0
	Sphere3<Real> MergeSpheres (const Sphere3<Real>& sphere0,
		const Sphere3<Real>& sphere1)
	{
		Vector3<Real> cenDiff = sphere1.Center - sphere0.Center;
		Real lenSqr = cenDiff.SquaredLength();
		Real rDiff = sphere1.Radius - sphere0.Radius;
		Real rDiffSqr = rDiff*rDiff;

		if (rDiffSqr >= lenSqr)
		{
			return (rDiff >= (Real)0 ? sphere1 : sphere0);
		}

		Real length = Math<Real>::Sqrt(lenSqr);
		Sphere3<Real> sphere;

		if (length > Math<Real>::ZERO_TOLERANCE)
		{
			Real coeff = (length + rDiff)/(((Real)2)*length);
			sphere.Center = sphere0.Center + coeff*cenDiff;
		}
		else
		{
			sphere.Center = sphere0.Center;
		}

		sphere.Radius = ((Real)0.5)*(length + sphere0.Radius + sphere1.Radius);

		return sphere;
	}
Real DistPoint3Segment3<Real>::GetSquared ()
{
    Vector3<Real> diff = *mPoint - mSegment->Center;
    mSegmentParameter = mSegment->Direction.Dot(diff);

    if (-mSegment->Extent < mSegmentParameter)
    {
        if (mSegmentParameter < mSegment->Extent)
        {
            mClosestPoint1 = mSegment->Center +
                mSegmentParameter*mSegment->Direction;
        }
        else
        {
            mClosestPoint1 = mSegment->P1;
            mSegmentParameter = mSegment->Extent;
        }
    }
    else
    {
        mClosestPoint1 = mSegment->P0;
        mSegmentParameter = -mSegment->Extent;
    }

    mClosestPoint0 = *mPoint;
    diff = mClosestPoint1 - mClosestPoint0;
    return diff.SquaredLength();
}
Example #8
0
//----------------------------------------------------------------------------
Sphere Mgc::MergeSpheres (const Sphere& rkSphere0, const Sphere& rkSphere1)
{
    Vector3 kCDiff = rkSphere1.Center() - rkSphere0.Center();
    Real fLSqr = kCDiff.SquaredLength();
    Real fRDiff = rkSphere1.Radius() - rkSphere0.Radius();
    Real fRDiffSqr = fRDiff*fRDiff;

    if ( fRDiffSqr >= fLSqr )
        return ( fRDiff >= 0.0f ? rkSphere1 : rkSphere0 );

    Real fLength = Math::Sqrt(fLSqr);
    const Real fTolerance = 1e-06f;
    Sphere kSphere;

    if ( fLength > fTolerance )
    {
        Real fCoeff = (fLength + fRDiff)/(2.0f*fLength);
        kSphere.Center() = rkSphere0.Center() + fCoeff*kCDiff;
    }
    else
    {
        kSphere.Center() = rkSphere0.Center();
    }

    kSphere.Radius() = 0.5f*(fLength + rkSphere0.Radius() +
        rkSphere1.Radius());

    return kSphere;
}
Example #9
0
Real DistLine3Line3<Real>::GetSquared ()
{
    Vector3<Real> kDiff = m_pkLine0->Origin - m_pkLine1->Origin;
    Real fA01 = -m_pkLine0->Direction.Dot(m_pkLine1->Direction);
    Real fB0 = kDiff.Dot(m_pkLine0->Direction);
    Real fC = kDiff.SquaredLength();
    Real fDet = Math<Real>::FAbs((Real)1.0 - fA01*fA01);
    Real fB1, fS0, fS1, fSqrDist;

    if (fDet >= Math<Real>::ZERO_TOLERANCE)
    {
        // lines are not parallel
        fB1 = -kDiff.Dot(m_pkLine1->Direction);
        Real fInvDet = ((Real)1.0)/fDet;
        fS0 = (fA01*fB1-fB0)*fInvDet;
        fS1 = (fA01*fB0-fB1)*fInvDet;
        fSqrDist = fS0*(fS0+fA01*fS1+((Real)2.0)*fB0) +
            fS1*(fA01*fS0+fS1+((Real)2.0)*fB1)+fC;
    }
    else
    {
        // lines are parallel, select any closest pair of points
        fS0 = -fB0;
        fS1 = (Real)0.0;
        fSqrDist = fB0*fS0+fC;
    }

    m_kClosestPoint0 = m_pkLine0->Origin + fS0*m_pkLine0->Direction;
    m_kClosestPoint1 = m_pkLine1->Origin + fS1*m_pkLine1->Direction;
    m_fLine0Parameter = fS0;
    m_fLine1Parameter = fS1;
    return Math<Real>::FAbs(fSqrDist);
}
Real DistVector3Segment3<Real>::GetSquared ()
{
    Vector3<Real> kDiff = m_rkVector - m_rkSegment.Origin;
    m_fSegmentParameter = m_rkSegment.Direction.Dot(kDiff);

    if (-m_rkSegment.Extent < m_fSegmentParameter)
    {
        if (m_fSegmentParameter < m_rkSegment.Extent)
        {
            m_kClosestPoint1 = m_rkSegment.Origin +
                m_fSegmentParameter*m_rkSegment.Direction;
        }
        else
        {
            m_kClosestPoint1 = m_rkSegment.Origin +
                m_rkSegment.Extent*m_rkSegment.Direction;
        }
    }
    else
    {
        m_kClosestPoint1 = m_rkSegment.Origin -
            m_rkSegment.Extent*m_rkSegment.Direction;
    }

    m_kClosestPoint0 = m_rkVector;
    kDiff = m_kClosestPoint1 - m_kClosestPoint0;
    return kDiff.SquaredLength();
}
Example #11
0
Real Wml::SqrDistance (const Vector3<Real>& rkPoint,
    const Segment3<Real>& rkSegment, Real* pfParam)
{
    Vector3<Real> kDiff = rkPoint - rkSegment.Origin();
    Real fT = kDiff.Dot(rkSegment.Direction());

    if ( fT <= (Real)0.0 )
    {
        fT = (Real)0.0;
    }
    else
    {
        Real fSqrLen= rkSegment.Direction().SquaredLength();
        if ( fT >= fSqrLen )
        {
            fT = (Real)1.0;
            kDiff -= rkSegment.Direction();
        }
        else
        {
            fT /= fSqrLen;
            kDiff -= fT*rkSegment.Direction();
        }
    }

    if ( pfParam )
        *pfParam = fT;

    return kDiff.SquaredLength();
}
Example #12
0
	Sphere3<Real> ContSphereAverage (int numPoints, const Vector3<Real>* points)
	{
		Sphere3<Real> sphere;

		sphere.Center = points[0];
		int i;
		for (i = 1; i < numPoints; ++i)
		{
			sphere.Center += points[i];
		}
		sphere.Center /= (Real)numPoints;

		for (i = 0; i < numPoints; ++i)
		{
			Vector3<Real> diff = points[i] - sphere.Center;
			Real radiusSqr = diff.SquaredLength();
			if (radiusSqr > sphere.Radius)
			{
				sphere.Radius = radiusSqr;
			}
		}

		sphere.Radius = Math<Real>::Sqrt(sphere.Radius);
		return sphere;
	}
//----------------------------------------------------------------------------
Real Mgc::SqrDistance (const Line3& rkLine, const Circle3& rkCircle,
                       Vector3* pkLineClosest, Vector3* pkCircleClosest)
{
    Vector3 kDiff = rkLine.Origin() - rkCircle.Center();
    Real fDSqrLen = kDiff.SquaredLength();
    Real fMdM = rkLine.Direction().SquaredLength();
    Real fDdM = kDiff.Dot(rkLine.Direction());
    Real fNdM = rkCircle.N().Dot(rkLine.Direction());
    Real fDdN = kDiff.Dot(rkCircle.N());

    Real fA0 = fDdM;
    Real fA1 = fMdM;
    Real fB0 = fDdM - fNdM*fDdN;
    Real fB1 = fMdM - fNdM*fNdM;
    Real fC0 = fDSqrLen - fDdN*fDdN;
    Real fC1 = fB0;
    Real fC2 = fB1;
    Real fRSqr = rkCircle.Radius()*rkCircle.Radius();

    Real fA0Sqr = fA0*fA0;
    Real fA1Sqr = fA1*fA1;
    Real fTwoA0A1 = 2.0f*fA0*fA1;
    Real fB0Sqr = fB0*fB0;
    Real fB1Sqr = fB1*fB1;
    Real fTwoB0B1 = 2.0f*fB0*fB1;
    Real fTwoC1 = 2.0f*fC1;

    // The minimum point B+t*M occurs when t is a root of the quartic
    // equation whose coefficients are defined below.
    Polynomial kPoly(5);
    kPoly[0] = fA0Sqr*fC0 - fB0Sqr*fRSqr;
    kPoly[1] = fTwoA0A1*fC0 + fA0Sqr*fTwoC1 - fTwoB0B1*fRSqr;
    kPoly[2] = fA1Sqr*fC0 + fTwoA0A1*fTwoC1 + fA0Sqr*fC2 - fB1Sqr*fRSqr;
    kPoly[3] = fA1Sqr*fTwoC1 + fTwoA0A1*fC2;
    kPoly[4] = fA1Sqr*fC2;

    int iNumRoots;
    Real afRoot[4];
    kPoly.GetAllRoots(iNumRoots,afRoot);

    Real fMinSqrDist = Math::MAX_REAL;
    for (int i = 0; i < iNumRoots; i++)
    {
        // compute distance from P(t) to circle
        Vector3 kP = rkLine.Origin() + afRoot[i]*rkLine.Direction();
        Vector3 kCircleClosest;
        Real fSqrDist = SqrDistance(kP,rkCircle,&kCircleClosest);
        if ( fSqrDist < fMinSqrDist )
        {
            fMinSqrDist = fSqrDist;
            if ( pkLineClosest )
                *pkLineClosest = kP;
            if ( pkCircleClosest )
                *pkCircleClosest = kCircleClosest;
        }
    }

    return fMinSqrDist;
}
Example #14
0
Real Mgc::SqrDistance (const Vector3& rkPoint, const Segment3& rkSegment,

    Real* pfParam)

{

    Vector3 kDiff = rkPoint - rkSegment.Origin();

    Real fT = kDiff.Dot(rkSegment.Direction());



    if ( fT <= 0.0f )

    {

        fT = 0.0f;

    }

    else

    {

        Real fSqrLen= rkSegment.Direction().SquaredLength();

        if ( fT >= fSqrLen )

        {

            fT = 1.0f;

            kDiff -= rkSegment.Direction();

        }

        else

        {

            fT /= fSqrLen;

            kDiff -= fT*rkSegment.Direction();

        }

    }



    if ( pfParam )

        *pfParam = fT;



    return kDiff.SquaredLength();

}
Example #15
0
//----------------------------------------------------------------------------
bool Mgc::InSphere (const Vector3& rkPoint, const Sphere& rkSphere,
    Real fEpsilon)
{
    Real fRSqr = rkSphere.Radius()*rkSphere.Radius();
    Vector3 kDiff = rkPoint - rkSphere.Center();
    Real fSqrDist = kDiff.SquaredLength();
    return fSqrDist <= fRSqr + fEpsilon;
}
Example #16
0
Real DistPoint3Line3<Real>::GetSquared ()
{
    Vector3<Real> diff = *mPoint - mLine->Origin;
    mLineParameter = mLine->Direction.Dot(diff);
    mClosestPoint0 = *mPoint;
    mClosestPoint1 = mLine->Origin + mLineParameter*mLine->Direction;
    diff = mClosestPoint1 - mClosestPoint0;
    return diff.SquaredLength();
}
Example #17
0
 Sphere3<Real> MinSphere3<Real>::ExactSphere2 ( const Vector3<Real>& P0,
         const Vector3<Real>& P1 )
 {
     Sphere3<Real> minimal;
     minimal.Center = ( ( Real )0.5 ) * ( P0 + P1 );
     Vector3<Real> diff = P1 - P0;
     minimal.Radius = ( ( Real )0.25 ) * diff.SquaredLength();
     return minimal;
 }
Real DistLine3Circle3<Real>::GetSquared ()
{
    Vector3<Real> diff = mLine->Origin - mCircle->Center;
    Real diffSqrLen = diff.SquaredLength();
    Real MdM = mLine->Direction.SquaredLength();
    Real DdM = diff.Dot(mLine->Direction);
    Real NdM = mCircle->Normal.Dot(mLine->Direction);
    Real DdN = diff.Dot(mCircle->Normal);

    Real a0 = DdM;
    Real a1 = MdM;
    Real b0 = DdM - NdM*DdN;
    Real b1 = MdM - NdM*NdM;
    Real c0 = diffSqrLen - DdN*DdN;
    Real c1 = b0;
    Real c2 = b1;
    Real rsqr = mCircle->Radius*mCircle->Radius;

    Real a0sqr = a0*a0;
    Real a1sqr = a1*a1;
    Real twoA0A1 = ((Real)2)*a0*a1;
    Real b0sqr = b0*b0;
    Real b1Sqr = b1*b1;
    Real twoB0B1 = ((Real)2)*b0*b1;
    Real twoC1 = ((Real)2)*c1;

    // The minimum point B+t*M occurs when t is a root of the quartic
    // equation whose coefficients are defined below.
    Polynomial1<Real> poly(4);
    poly[0] = a0sqr*c0 - b0sqr*rsqr;
    poly[1] = twoA0A1*c0 + a0sqr*twoC1 - twoB0B1*rsqr;
    poly[2] = a1sqr*c0 + twoA0A1*twoC1 + a0sqr*c2 - b1Sqr*rsqr;
    poly[3] = a1sqr*twoC1 + twoA0A1*c2;
    poly[4] = a1sqr*c2;

    PolynomialRoots<Real> polyroots(Math<Real>::ZERO_TOLERANCE);
    polyroots.FindB(poly, 6);
    int count = polyroots.GetCount();
    const Real* roots = polyroots.GetRoots();

    Real minSqrDist = Math<Real>::MAX_REAL;
    for (int i = 0; i < count; ++i)
    {
        // Compute distance from P(t) to circle.
        Vector3<Real> P = mLine->Origin + roots[i]*mLine->Direction;
        DistPoint3Circle3<Real> query(P, *mCircle);
        Real sqrDist = query.GetSquared();
        if (sqrDist < minSqrDist)
        {
            minSqrDist = sqrDist;
            mClosestPoint0 = query.GetClosestPoint0();
            mClosestPoint1 = query.GetClosestPoint1();
        }
    }

    return minSqrDist;
}
Example #19
0
bool Wml::TestIntersection (const Sphere3<Real>& rkS0,
    const Sphere3<Real>& rkS1)
{
    Vector3<Real> kDiff = rkS1.Center() - rkS0.Center();
    Real fSqrLen = kDiff.SquaredLength();
    Real fRSum = rkS0.Radius() + rkS1.Radius();
    Real fRSumSqr = fRSum*fRSum;

    return fSqrLen <= fRSumSqr;
}
Example #20
0
    bool MinSphere3<Real>::Contains ( const Vector3<Real>& point,
                                      const Sphere3<Real>& sphere, Real& distDiff )
    {
        Vector3<Real> diff = point - sphere.Center;
        Real test = diff.SquaredLength();

        // NOTE:  In this algorithm, Sphere3 is storing the *squared radius*,
        // so the next line of code is not in error.
        distDiff = test - sphere.Radius;

        return distDiff <= ( Real )0;
    }
Example #21
0
 bool MinSphere3<Real>::Support::Contains ( int index, Vector3<Real>** points,
         Real epsilon )
 {
     for ( int i = 0; i < Quantity; ++i )
     {
         Vector3<Real> diff = *points[index] - *points[Index[i]];
         if ( diff.SquaredLength() < epsilon )
         {
             return true;
         }
     }
     return false;
 }
Example #22
0
Real DistLine3Ray3<Real>::GetSquared ()
{
	Vector3<Real> kDiff = mLine->Origin - mRay->Origin;
	Real a01 = -mLine->Direction.Dot(mRay->Direction);
	Real b0 = kDiff.Dot(mLine->Direction);
	Real c = kDiff.SquaredLength();
	Real det = Math<Real>::FAbs((Real)1 - a01*a01);
	Real b1, s0, s1, sqrDist;

	if (det >= Math<Real>::ZERO_TOLERANCE)
	{
		b1 = -kDiff.Dot(mRay->Direction);
		s1 = a01*b0 - b1;

		if (s1 >= (Real)0)
		{
			// Two interior points are closest, one on line and one on ray.
			Real invDet = ((Real)1)/det;
			s0 = (a01*b1 - b0)*invDet;
			s1 *= invDet;
			sqrDist = s0*(s0 + a01*s1 + ((Real)2)*b0) +
			          s1*(a01*s0 + s1 + ((Real)2)*b1) + c;
		}
		else
		{
			// Origin of ray and interior point of line are closest.
			s0 = -b0;
			s1 = (Real)0;
			sqrDist = b0*s0 + c;
		}
	}
	else
	{
		// Lines are parallel, closest pair with one point at ray origin.
		s0 = -b0;
		s1 = (Real)0;
		sqrDist = b0*s0 + c;
	}

	mClosestPoint0 = mLine->Origin + s0*mLine->Direction;
	mClosestPoint1 = mRay->Origin + s1*mRay->Direction;
	mLineParameter = s0;
	mRayParameter = s1;

	// Account for numerical round-off errors.
	if (sqrDist < (Real)0)
	{
		sqrDist = (Real)0;
	}
	return sqrDist;
}
Example #23
0
static bool FindSphereVertexIntersection (const Vector3<Real>& rkVertex, 
    const Sphere3<Real>& rkSphere, const Vector3<Real>& rkSphVelocity,
    const Vector3<Real>& rkTriVelocity, Real& rfTFirst, Real fTMax,
    int& riQuantity, Vector3<Real> akP[6])
{
    // Finds the time and place (and possible occurance, it may miss) of an
    // intersection between a sphere of fRadius at rkOrigin moving in rkDir
    // towards a vertex at rkVertex.

    Vector3<Real> kVel = rkSphVelocity - rkTriVelocity;
    Vector3<Real> kD = rkSphere.Center() - rkVertex;
    Vector3<Real> kCross = kD.Cross(kVel);
    Real fRSqr = rkSphere.Radius()*rkSphere.Radius();
    Real fVSqr = kVel.SquaredLength();

    if ( kCross.SquaredLength() > fRSqr*fVSqr )
    {
        // ray overshoots the sphere
        return false;
    }

    // find time of intersection
    Real fDot = kD.Dot(kVel);
    Real fDiff = kD.SquaredLength() - fRSqr;
    Real fInv = Math<Real>::InvSqrt(Math<Real>::FAbs(fDot*fDot-fVSqr*fDiff));

    rfTFirst = fDiff*fInv/((Real)1.0-fDot*fInv);
    if ( rfTFirst > fTMax )
    {
        // intersection after max time
        return false;
    }

    // place of intersection is triangle vertex
    riQuantity = 1;
    akP[0] = rkVertex + rfTFirst*rkTriVelocity;
    return true;
}
Example #24
0
bool IntrSphere3Cone3<Real>::Find ()
{
    // test if cone vertex is in sphere
    Vector3<Real> kDiff = m_pkSphere->Center - m_pkCone->Vertex;
    Real fRSqr = m_pkSphere->Radius*m_pkSphere->Radius;
    Real fLSqr = kDiff.SquaredLength();
    if (fLSqr <= fRSqr)
    {
        return true;
    }

    // test if sphere center is in cone
    Real fDot = kDiff.Dot(m_pkCone->Axis);
    Real fDotSqr = fDot*fDot;
    Real fCosSqr = m_pkCone->CosAngle*m_pkCone->CosAngle;
    if (fDotSqr >= fLSqr*fCosSqr && fDot > (Real)0.0)
    {
        // sphere center is inside cone, so sphere and cone intersect
        return true;
    }

    // Sphere center is outside cone.  Problem now reduces to looking for
    // an intersection between circle and ray in the plane containing
    // cone vertex and spanned by cone axis and vector from vertex to
    // sphere center.

    // Ray is t*D+V (t >= 0) where |D| = 1 and dot(A,D) = cos(angle).
    // Also, D = e*A+f*(C-V).  Plugging ray equation into sphere equation
    // yields R^2 = |t*D+V-C|^2, so the quadratic for intersections is
    // t^2 - 2*dot(D,C-V)*t + |C-V|^2 - R^2 = 0.  An intersection occurs
    // if and only if the discriminant is nonnegative.  This test becomes
    //
    //     dot(D,C-V)^2 >= dot(C-V,C-V) - R^2
    //
    // Note that if the right-hand side is nonpositive, then the inequality
    // is true (the sphere contains V).  I have already ruled this out in
    // the first block of code in this function.

    Real fULen = Math<Real>::Sqrt(Math<Real>::FAbs(fLSqr-fDotSqr));
    Real fTest = m_pkCone->CosAngle*fDot + m_pkCone->SinAngle*fULen;
    Real fDiscr = fTest*fTest - fLSqr + fRSqr;

    // compute point of intersection closest to vertex V
    Real fT = fTest - Math<Real>::Sqrt(fDiscr);
    Vector3<Real> kB = kDiff - fDot*m_pkCone->Axis;
    Real fTmp = m_pkCone->SinAngle/fULen;
    m_kPoint = fT*(m_pkCone->CosAngle*m_pkCone->Axis + fTmp*kB);

    return fDiscr >= (Real)0.0 && fTest >= (Real)0.0;
}
Example #25
0
bool IntrSphere3Cone3<Real>::Test ()
{
    Real fInvSin = ((Real)1.0)/m_pkCone->SinAngle;
    Real fCosSqr = m_pkCone->CosAngle*m_pkCone->CosAngle;

    Vector3<Real> kCmV = m_pkSphere->Center - m_pkCone->Vertex;
    Vector3<Real> kD = kCmV + (m_pkSphere->Radius*fInvSin)*m_pkCone->Axis;
    Real fDSqrLen = kD.SquaredLength();
    Real fE = kD.Dot(m_pkCone->Axis);
    if (fE > (Real)0.0 && fE*fE >= fDSqrLen*fCosSqr)
    {
        Real fSinSqr = m_pkCone->SinAngle*m_pkCone->SinAngle;
        fDSqrLen = kCmV.SquaredLength();
        fE = -kCmV.Dot(m_pkCone->Axis);
        if (fE > (Real)0.0 && fE*fE >= fDSqrLen*fSinSqr)
        {
            Real fRSqr = m_pkSphere->Radius*m_pkSphere->Radius;
            return fDSqrLen <= fRSqr;
        }
        return true;
    }
    return false;
}
Example #26
0
bool IntrSphere3Cone3<Real>::Test ()
{
    Real invSin = ((Real)1)/mCone->SinAngle;
    Real cosSqr = mCone->CosAngle*mCone->CosAngle;

    Vector3<Real> CmV = mSphere->Center - mCone->Vertex;
    Vector3<Real> D = CmV + (mSphere->Radius*invSin)*mCone->Axis;
    Real DSqrLen = D.SquaredLength();
    Real e = D.Dot(mCone->Axis);
    if (e > (Real)0 && e*e >= DSqrLen*cosSqr)
    {
        Real sinSqr = mCone->SinAngle*mCone->SinAngle;
        DSqrLen = CmV.SquaredLength();
        e = -CmV.Dot(mCone->Axis);
        if (e > (Real)0 && e*e >= DSqrLen*sinSqr)
        {
            Real rSqr = mSphere->Radius*mSphere->Radius;
            return DSqrLen <= rSqr;
        }
        return true;
    }
    return false;
}
Example #27
0
bool IntrSphere3Cone3<Real>::Find ()
{
    // Test whether cone vertex is in sphere.
    Vector3<Real> diff = mSphere->Center - mCone->Vertex;
    Real rSqr = mSphere->Radius*mSphere->Radius;
    Real lenSqr = diff.SquaredLength();
    if (lenSqr <= rSqr)
    {
        return true;
    }

    // Test whether sphere center is in cone.
    Real dot = diff.Dot(mCone->Axis);
    Real dotSqr = dot*dot;
    Real cosSqr = mCone->CosAngle*mCone->CosAngle;
    if (dotSqr >= lenSqr*cosSqr && dot > (Real)0)
    {
        // Sphere center is inside cone, so sphere and cone intersect.
        return true;
    }

    // Sphere center is outside cone.  Problem now reduces to looking for
    // an intersection between circle and ray in the plane containing
    // cone vertex and spanned by cone axis and vector from vertex to
    // sphere center.

    // Ray is t*D+V (t >= 0) where |D| = 1 and dot(A,D) = cos(angle).
    // Also, D = e*A+f*(C-V).  Plugging ray equation into sphere equation
    // yields R^2 = |t*D+V-C|^2, so the quadratic for intersections is
    // t^2 - 2*dot(D,C-V)*t + |C-V|^2 - R^2 = 0.  An intersection occurs
    // if and only if the discriminant is nonnegative.  This test becomes
    //
    //     dot(D,C-V)^2 >= dot(C-V,C-V) - R^2
    //
    // Note that if the right-hand side is nonpositive, then the inequality
    // is true (the sphere contains V).  I have already ruled this out in
    // the first block of code in this function.

    Real uLen = Math<Real>::Sqrt(Math<Real>::FAbs(lenSqr-dotSqr));
    Real test = mCone->CosAngle*dot + mCone->SinAngle*uLen;
    Real discr = test*test - lenSqr + rSqr;

    // compute point of intersection closest to vertex V
    Real t = test - Math<Real>::Sqrt(discr);
    Vector3<Real> B = diff - dot*mCone->Axis;
    Real tmp = mCone->SinAngle/uLen;
    mPoint = t*(mCone->CosAngle*mCone->Axis + tmp*B);

    return discr >= (Real)0 && test >= (Real)0;
}
bool IntrTriangle3Sphere3<Real>::FindSphereVertexIntersection (
    const Vector3<Real>& vertex, Real tmax,
    const Vector3<Real>& velocity0, const Vector3<Real>& velocity1)
{
    // Finds the time and place (and possible occurrence it may miss) of an
    // intersection between a sphere of fRadius at rkOrigin moving in rkDir
    // towards a vertex at vertex.

    Vector3<Real> relVelocity = velocity1 - velocity0;
    Vector3<Real> D = mSphere->Center - vertex;
    Vector3<Real> cross = D.Cross(relVelocity);
    Real rSqr = mSphere->Radius*mSphere->Radius;
    Real vsqr = relVelocity.SquaredLength();

    if (cross.SquaredLength() > rSqr*vsqr)
    {
        // The ray overshoots the sphere.
        return false;
    }

    // Find the time of intersection.
    Real dot = D.Dot(relVelocity);
    Real diff = D.SquaredLength() - rSqr;
    Real inv = Math<Real>::InvSqrt(Math<Real>::FAbs(dot*dot - vsqr*diff));

    mContactTime = diff*inv/((Real)1 - dot*inv);
    if (mContactTime > tmax)
    {
        // The intersection occurs after max time.
        return false;
    }

    // The intersection is a triangle vertex.
    mPoint = vertex + mContactTime*velocity0;
    return true;
}
Example #29
0
Sphere Mgc::ContSphereAverage (int iQuantity, const Vector3* akPoint)

{

    Vector3 kCenter = akPoint[0];

    int i;

    for (i = 1; i < iQuantity; i++)

        kCenter += akPoint[i];

    Real fInvQuantity = 1.0f/iQuantity;

    kCenter *= fInvQuantity;



    Real fMaxRadiusSqr = 0.0f;

    for (i = 0; i < iQuantity; i++)

    {

        Vector3 kDiff = akPoint[i] - kCenter;

        Real fRadiusSqr = kDiff.SquaredLength();

        if ( fRadiusSqr > fMaxRadiusSqr )

            fMaxRadiusSqr = fRadiusSqr;

    }



    Sphere kSphere;

    kSphere.Center() = kCenter;

    kSphere.Radius() = Math::Sqrt(fMaxRadiusSqr);



    return kSphere;

}
static Real UpdateInvRSqr (int iQuantity, const Vector3<Real>* akPoint,
    const Vector3<Real>& rkC, const Vector3<Real>& rkU, Real& rfInvRSqr)
{
    Real fASum = (Real)0.0, fAASum = (Real)0.0;
    for (int i = 0; i < iQuantity; i++)
    {
        Vector3<Real> kDelta = akPoint[i] - rkC;
        Vector3<Real> kDxU = kDelta.Cross(rkU);
        Real fL2 = kDxU.SquaredLength();
        fASum += fL2;
        fAASum += fL2*fL2;
    }

    rfInvRSqr = fASum/fAASum;
    Real fMin = (Real)1.0 - rfInvRSqr*fASum/(Real)iQuantity;
    return fMin;
}