说明:如果仅仅是再Unity环境下使用的话,直接使用Bounds.IntersectRay方法就好了,这里仅仅探索其算法。

        上代码:

bool RayCrossBounds(Ray ray, Bounds bounds)
{
	if (bounds.Contains(ray.origin)) return true;
	//
	float tMinX = float.MinValue;
	float tMaxX = float.MaxValue;
	if (Mathf.Approximately(ray.direction.x, 0))
	{
		if (ray.origin.x <= bounds.min.x || ray.origin.x >= bounds.max.x) return false;
	}
	else
	{
		tMinX = (bounds.min.x - ray.origin.x) / ray.direction.x;
		if (tMinX < 0) tMinX = 0;
		tMaxX = (bounds.max.x - ray.origin.x) / ray.direction.x;
		if (tMaxX < 0) tMaxX = 0;
		if (tMinX < 0 && tMaxX < 0) return false;
	}

	if (tMinX > tMaxX)
	{
		float temp = tMinX;
		tMinX = tMaxX;
		tMaxX = temp;
	}
	//
	float tMinY = float.MinValue;
	float tMaxY = float.MaxValue;
	if (Mathf.Approximately(ray.direction.y, 0))
	{
		if (ray.origin.y <= bounds.min.y || ray.origin.y >= bounds.max.y) return false;
	}
	else
	{
		tMinY = (bounds.min.y - ray.origin.y) / ray.direction.y;
		if (tMinY < 0) tMinY = 0;
		tMaxY = (bounds.max.y - ray.origin.y) / ray.direction.y;
		if (tMaxY < 0) tMaxY = 0;
		if (tMinY < 0 && tMaxY < 0) return false;
	}

	if (tMinY > tMaxY)
	{
		float temp = tMinY;
		tMinY = tMaxY;
		tMaxY = temp;
	}
	//
	float tMinZ = float.MinValue;
	float tMaxZ = float.MaxValue;
	if (Mathf.Approximately(ray.direction.z, 0))
	{
		if (ray.origin.z <= bounds.min.z || ray.origin.z >= bounds.max.z) return false;
	}
	else
	{
		tMinZ = (bounds.min.z - ray.origin.z) / ray.direction.z;
		if (tMinZ < 0) tMinZ = 0;
		tMaxZ = (bounds.max.z - ray.origin.z) / ray.direction.z;
		if (tMaxZ < 0) tMaxZ = 0;
		if (tMinZ < 0 && tMaxZ < 0) return false;
	}

	if (tMinZ > tMaxZ)
	{
		float temp = tMinZ;
		tMinZ = tMaxZ;
		tMaxZ = temp;
	}
	//Get Max min value
	float tMin = tMinX;
	if (tMin < tMinY) tMin = tMinY;
	if (tMin < tMinZ) tMin = tMinZ;
	//Get Min max value
	float tMax = tMaxX;
	if (tMax > tMaxY) tMax = tMaxY;
	if (tMax > tMaxZ) tMax = tMaxZ;

	if (tMax < tMin) return false;

	return true;
}

        该算法应该还有很多优化的余地,使用前应该考虑根据实际情况优化。

原理参考链接

01-14 16:26