Я знаю, что есть несколько превосходных ответов выше, но я хотел добавить очень простое решение, чтобы вписать ограничивающую сферу в область действия камеры. Предполагается, что вы хотите, чтобы вектор цели и прямой камеры оставались одинаковыми, и просто отрегулировать расстояние от камеры до цели.
Обратите внимание, это не даст вам наилучшего соответствия, но даст приблизительное соответствие, показывая всю геометрию, и только в нескольких строках кода, и без экрана в мир преобразования
// Compute camera radius to fit bounding sphere
// Implementation in C#
//
// Given a bounding box around your scene
BoundingBox bounds = new BoundingBox();
// Compute the centre point of the bounding box
// NOTE: The implementation for this is to take the mid-way point between
// two opposing corners of the bounding box
Vector3 center = bounds.Center;
// Find the corner of the bounding box which is maximum distance from the
// centre of the bounding box. Vector3.Distance computes the distance between
// two vectors. Select is just nice syntactic sugar to loop
// over Corners and find the max distance.
double boundSphereRadius = bounds.Corners.Select(x => Vector3.Distance(x, bounds.Center)).Max();
// Given the camera Field of View in radians
double fov = Math3D.DegToRad(FieldOfView);
// Compute the distance the camera should be to fit the entire bounding sphere
double camDistance = (boundSphereRadius * 2.0) / Math.Tan(fov / 2.0);
// Now, set camera.Target to bounds.Center
// set camera.Radius to camDistance
// Keep current forward vector the same
Реализация BoundingBox в C # приведена ниже. Важными моментами являются свойства Центра и Углов. Vector3 - довольно стандартная реализация 3-компонентного (X, Y, Z) вектора
public struct BoundingBox
{
public Vector3 Vec0;
public Vector3 Vec1;
public BoundingBox(Vector3 vec0, Vector3 vec1)
{
Vec0 = vec0;
Vec1 = vec1;
}
public Vector3 Center
{
get { return (Vec0 + Vec1)*0.5; }
}
public IList<Vector3> Corners
{
get
{
Vector3[] corners = new[]
{
new Vector3( Vec0.X, Vec0.Y, Vec0.Z ),
new Vector3( Vec1.X, Vec0.Y, Vec0.Z ),
new Vector3( Vec0.X, Vec1.Y, Vec0.Z ),
new Vector3( Vec0.X, Vec0.Y, Vec1.Z ),
new Vector3( Vec1.X, Vec1.Y, Vec0.Z ),
new Vector3( Vec1.X, Vec0.Y, Vec1.Z ),
new Vector3( Vec0.X, Vec1.Y, Vec1.Z ),
new Vector3( Vec1.X, Vec1.Y, Vec1.Z ),
};
return corners;
}
}
}