Czech

OpenGL game

Ray sphere intersection test

Download sources (711,5kB)

06.11.20

For example ray sphere intersection test is using for aiming to some objects in scene. Ray origin is camera position and ray direction is infinite position by camera direction vector. If ray intersect object bounding sphere that camera takes aim to the object.

1. Ray and sphere class:

class K3dRay
{
	// Ray is R(t) = P+t*D for t >= 0.  D is not necessarily unit length.

    K3dVector3 m_kOrigin;  // P
    K3dVector3 m_kDirection;  // D
public:
	K3dRay(K3dVector3 &_rkOrigin, K3dVector3 &_rkDirection)
	{
		m_kOrigin = _rkOrigin;
		m_kDirection = _rkDirection;
	}
	K3dRay()
	{
		m_kOrigin.Reset();
		m_kDirection.Reset();
	}
	~K3dRay() {}

	K3dVector3& GetOrigin()
	{
		return m_kOrigin;
	}

	const K3dVector3& GetOrigin() const
	{
		return m_kOrigin;
	}

	K3dVector3& GetDirection()
	{
		return m_kDirection;
	}

	const K3dVector3& GetDirection() const
	{
		return m_kDirection;
	}
};



class K3dSphere
{
	K3dVector3 m_kPosition;	///< Sphere position
	float m_fRadius;	///< Sphere radius
	
	public:		
		K3dSphere()
		{
			m_kPosition.Reset();
			m_fRadius = (float) 32;
		}
		K3dSphere(const K3dVector3 &_rkPosition, const float _fRadius)
		{
			m_kPosition = _rkPosition;
			m_fRadius = _fRadius;
		}
		~K3dSphere()
		{
		}

		///\brief Get or set sphere position
		K3dVector3 &GetPosition()
		{
			return m_kPosition;
		}
		const K3dVector3 &GetPosition() const
		{
			return m_kPosition;
		}

		///\brief Get or set sphere radius
		float &GetRadius()
		{
			return m_fRadius;
		}
		const float &GetRadius() const
		{
			return m_fRadius;
		}
};


2. Calculate dot product between ray direction vector
K3dVector3 &_rkVector
and different vector (sphere position - ray origin)
float m_afVector[3]

///\brief Calculate dot product between two vectors
float K3dVector3::Dot(const K3dVector3 &_rkVector)
{
	float fX,fY, fZ, fResult;

	fX = m_afVector[0] * _rkVector.m_afVector[0];
	fY = m_afVector[1] * _rkVector.m_afVector[1];
	fZ = m_afVector[2] * _rkVector.m_afVector[2];

	fResult = fX + fY + fZ;
	return fResult;
}


3. Calculate vector square length equation:

///\brief Calc vector square length
float K3dVector3::SquaredLength ()
{
	float fSqrLen = 0.0f;
	for (int i = 0; i < 3; i++)
		fSqrLen += (float) m_afVector[i]*m_afVector[i];
	return fSqrLen;
}


4. Calculate square distance between point and ray where point is camera position:

///\brief Calculate squared distance between point and ray
float SqrPointRay(const K3dVector3 &_rkPoint,const K3dRay &_rkRay, float* _pfParam=NULL)
{
	float fDotMM;
	float fT = (float) 0;
	K3dVector3 kDiff;
			
	kDiff = _rkPoint - _rkRay.GetOrigin();
	fT = kDiff.Dot(_rkRay.GetDirection());
		
			
	if ( fT <= (float)0.0 )
	{
		fT = (float)0.0;
	}
	else
	{
		fDotMM = _rkRay.GetDirection().SquaredLength();
		if(fDotMM)
		{
			fT = fT / fDotMM;
			kDiff -= _rkRay.GetDirection()*fT;
		}
	}
		
	if ( _pfParam )
		*_pfParam = fT;
		
	return kDiff.SquaredLength();
}


5. Final intersection test between ray and sphere:

///\brief Test intersection between ray and sphere
bool K3dIntrLinSph::TestIntersection(const K3dRay &_rkRay, const K3dSphere &_rkSphere)
{
	K3dDistance kDistance;
	float fSqrDist = (float) 0;
	float fSqr = (float) 0;

	fSqrDist = kDistance.SqrPointRay(_rkSphere.GetPosition(),_rkRay, 0);
	fSqr = _rkSphere.GetRadius()*_rkSphere.GetRadius();
	if(fSqrDist<=fSqr)
	{
		return true;
	}
	return false;
}



home / opengl game


Valid XHTML 1.0 Transitional