说明:如果仅仅是再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;
}
该算法应该还有很多优化的余地,使用前应该考虑根据实际情况优化。