Расстояние центра маленькой сферы от центра большой сферы никогда не должно быть больше (BigRadius - SmallRadius).Если вы хотите рассчитать положение, в котором установлен контакт, вы можете масштабировать вектор движения на отношение разницы в радиусах, необходимых для установления контакта, и общей разницы в радиусах от начальной точки до конечной точки (если движение не достаточно велико, чтобыпересечь плоскость, определяемую одной из осей большой ограничивающей сферы)
class Sphere {
public Vector3 Pos;
public double Radius;
}
void Test()
{
Sphere big = new Sphere() { Pos = new Vector3(0, 0, 0), Radius = 10.0 };
Sphere small = new Sphere() { Pos = new Vector3(8, 0, 0), Radius = 1.0 };
Vector3 move = new Vector3(0, 10, 0);
// new position without check, if within sphere ok
Vector3 newPos = small.Pos + move;
if (Vector3.Distance(newPos, big.Pos) < big.Radius - small.Radius)
return;
// diff in radius to contact with outer shell
double space = (big.Radius - small.Radius) - Vector3.Distance(small.Pos, big.Pos);
// movement past moment of hitting outer shell
double far = Vector3.Distance(newPos, big.Pos) - (big.Radius - small.Radius);
// scale movement by ratio to get movement to hit shell
move = move * (space / (space + far));
newPos = small.Pos + move;
}
Я думаю, что это сработает, ЕСЛИ движение не пересекает плоскость, определенную одной из координат большой сферы, и выходит наружу.Может быть, вы могли бы добавить специальную проверку для того, чтобы знак движения X, Y или Z отличался от большого. POS - маленький. POS (относительное положение центра маленькой сферы к центру большой сферы) X, Y или Z ...