开发者

Object in sphere(bounding sphere), want it to restrict movement within sphere

So how can I constraint movement of my object ONLY in a Sphere? I tried with the bounding box and the intersection meth开发者_如何转开发od but it doesn't seem to work?

Edit 1 :

this was not a question... i was asking this: i have 2 bounding spheres, one big and one small , the small will be moving inside the big but i dont want it to go outside the big bounding sphere how do i do it?


There's a faster way of making sure the center distance doesn't exceed the radius difference. It doesn't require taking a square root every time.

Precompute max_distance_squared whenever one of the radiuses are set or changed, and store it somewhere it can be reused:

local max_distance = big.radius - small.radius
max_distance_squared = max_distance*max_distance    

Now you can omit taking the square root to get the 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

The time saved can increase your frame rate or simulation speed a bit.


The distance of the center of the small sphere from the center of the big sphere must never be more than (BigRadius - SmallRadius). If you want to calculate the position where contact is made, you can scale the movement vector by the ratio of the difference in radii needed to make contact and the total difference in radii from starting point to ending point (unless the movement is large enough to cross a plane defined by one of the big bounding sphere's axis)

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;
}

I think this will work UNLESS the movement crosses a plane defined by one of the coordinates of the big sphere and moves outside. Maybe you could add special checking for sign of movement X, Y, or Z being different than big.Pos - small.Pos (relative position of small sphere center to big sphere center) X, Y or Z...


if (Vector3.Distance(bigSphere, smallSphere) < bigSphereradius - smallSphereradius) {
 // inside
}

Or use the BoundingSphere class:

http://msdn.microsoft.com/en-us/library/bb195373.aspx

ps. if vectors are normalized then radiuses must be too :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜