对象在球体(边界球体)中,希望它限制球体内的移动
本文关键字:移动 希望 边界 对象 | 更新日期: 2023-09-27 17:51:25
那么,如何仅在球体中约束对象的移动?我尝试了边界框和交集方法,但似乎不起作用?
编辑1:
这不是一个问题。。。我在问:我有两个边界球,一个大的,一个小的,小的会在大的里面移动,但我不想它在大的边界球外面,我该怎么做?
有一种更快的方法可以确保中心距离不超过半径差。它不需要每次都取一个平方根。
每当设置或更改其中一个半径时,预先计算max_distance_squared
,并将其存储在可以重复使用的地方:
local max_distance = big.radius - small.radius
max_distance_squared = max_distance*max_distance
现在你可以省略取平方根来获得距离:
local dx = big.center_x - small.center_x
local dy = big.center_y - small.center_y
if (dx*dx + dy*dy <= max_distance_squared)
# great
else
# explode
节省的时间可以稍微提高帧速率或模拟速度。
小球体的中心与大球体的中心的距离不得大于(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…
if (Vector3.Distance(bigSphere, smallSphere) < bigSphereradius - smallSphereradius) {
// inside
}
或者使用BoundingSphere类:
http://msdn.microsoft.com/en-us/library/bb195373.aspx
ps。如果矢量被归一化,那么半径也必须是:(