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

余生长醉 提交于 2020-01-07 05:31:11

问题


So how can I constraint movement of my object ONLY in a Sphere? I tried with the bounding box and the intersection method 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?


回答1:


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...




回答2:


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.




回答3:


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 :)



来源:https://stackoverflow.com/questions/5737440/object-in-spherebounding-sphere-want-it-to-restrict-movement-within-sphere

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!