确定球体和平面之间休息接触使用外力时,球体、外力、平面

2023-09-11 22:54:36 作者:如果爱可以重来

这个问题有一个主要的问题,一个小的问题。我相信,我是正确的,从我的研究两个问题,但不能同时使用。

有关我的物理循环,我做的第一件事就是申请一个引力到我的 TotalForce 刚体对象。然后我检查碰撞用我的 TotalForce 和我的速度。我的 TotalForce 重置为(0,0,0)每一个物理循环之后,虽然我会继续我的速度

我所熟悉的只使用速度时,感动球体和一个静态平面之间做一个碰撞检查。但是,如果我有,除了速度,比如重力的力量?我把其他的部队进入 TotalForces (现在我只有重力)。为了弥补,当我确定该领域目前不重叠的飞机上,我做

  Vector3类型的力=(sphereTotalForces + sphereVelocity);
    Vector3类型forcesDT =力* fElapsedTime;
    浮DENOM = Vec3Dot(安培; plane-> GetNormal(),放大器;力);
 

不过,这可能是有问题的,因为我怎么想是假设静养接触。我想休息接触是通过计算

  DENOM * DIST == 0.0
 
问题提出 平面内不在同一条直线上的三点确定一个圆.那么平面内的四点 任意三点均不在同一直线上 .能否在同一个圆呢 初步思考 设不在同一条直线上的三点A.B.C确定的圆为

其中, DIST

 浮法DIST = Vec3Dot(安培; plane-> GetNormal(),放大器; spherePosition) -  plane-> D组;
 

(仅供参考,明显的 DENOM * DIST> 0.0 的意思是从飞机上移开球体)

然而,这决不是真实的。即使当存在似乎是静止接触。这是因为我的力量上面总是为-9.8(我的重力)至少.Y计算。当对一个平面的运动与正常时(0,1,0)将AY DENOM 的-9.8。对

我的问题是

1)我是正确计算休息接触我如何与我的头两个code段提及?

如果这样,

2)如何使我的其他因素,如重力可以用吗?是我使用 TotalForces 不正确?

作为参考,我的时间步长

  mAcceleration = mTotalForces / mMass;
  mVelocity + = mAcceleration * fElapsedTime;
  Vector3类型转换=(mVelocity * fElapsedTime);
 

修改

由于它似乎有些建议的修改将会改变我的碰撞code,这里是我发现我的碰撞状态

 如果(晶圆厂(DIST)< = sphereRadius)
{//这里已经发生碰撞}
其他
{
    Vector3类型的力=(sphereTotalForces + sphereVelocity);
    浮DENOM = Vec3Dot(安培; plane-> GetNormal(),放大器;力);

    //休息接触
    如果(DIST == 0){}
    //球从平面搬走
    否则,如果(DENOM * DIST> 0.0){}
    //这里最终会碰撞
    其他
    {
        浮动fIntersectionTime =(sphereRadius  -  DIST)/ DENOM;
        浮动 -  [R;
        如果(DIST> 0.0)
            R = sphereRadius;
        其他
            R = -sphereRadius;

        Vector3类型collisionPosition = spherePosition + fIntersectionTime * sphereVelocity  -  R * planeNormal;
    }
}
 

解决方案

您应该使用如果(晶圆厂(DIST)< 0.0001f){/ *相撞* /} 这是acocunt浮点精度。你肯定不会得到最多角或接触一个确切的0.0。

的值 DIST 如果为负,其实你需要的情况下,机身背部转嫁到平面的表面的实际金额是经过的平面表面。 sphere.position = sphere.position - plane.Normal *晶圆厂(DIST);

在您移动回面,你可以选择让它在有关飞机正常的反方向反弹;或者只是停留在飞机上。

parallel_vec = Vec3.dot(plane.normal,-sphere.velocity);

perpendicular_vec = sphere.velocity - parallel_vec;

bounce_velocity =并行 - perpendicular_vec;

您不能盲目做 totalforce = external_force +速度,除非一切都具有单位质量。

修改

要完全定义在三维空间中的平面,则平面结构应存储的平面法线矢量和在飞机上的一个点。 http://en.wikipedia.org/wiki/Plane_(geometry )。

Vector3类型planeToSphere = sphere.point - plane.point;

浮法DIST = Vector3.dot(plane.normal,planeToSphere) - plane.radius;

如果(DIST< 0) {    //相撞。 }

我建议你多学习数学第一,如果这是一部分,你不知道。

注:对不起,格式化被搞砸了......为code座,我不能将其标记

编辑2 : 根据我对你的code的理解,无论您是严重或正如我前面提到的命名变量,你需要修改你的数学和物理理论。该行不会做任何有用的东西。

浮法DENOM = Vec3Dot(安培; plane-> GetNormal(),放大器;力);

一个在任何时间的情况下,在球上的力可在任何方向都无关行进方向。所以DENOM基本计算在平面方向力的大小,而是告诉你任何关于球是否会击中飞机。例如重力是向下的,但一个球可以有向上的速度,撞上上方的平面。有了这一点,你需要在 Vec3Dot(plane.normal,速度)代替。

另外,马克Phariss和格哈德·鲍威尔已经给你线性运动的物理方程,你可以使用它们来直接计算影响未来的位置,速度和时间。

例如。 S = 0.5 *(U + V)* T; 后给出未来时间t的位移。比较了位移与飞机的距离,你会得到球体是否会击中飞机。所以,再一次,我建议你阅读起来 http://en.wikipedia.org/wiki/Linear_motion和简单的东西先然后 http://en.wikipedia.org/wiki/Kinematics 。

另一种方法,如果你期望或假设没有其他力量作用于球,那么你就做一个射线/撞机试验,找到时间t,在它会击中飞机,在这种情况下,读 http://en.wikipedia.org/wiki/Line-plane_intersection 。

This question has one major question, and one minor question. I believe I am right in either question from my research, but not both.

For my physics loop, the first thing I do is apply a gravitational force to my TotalForce for a rigid body object. I then check for collisions using my TotalForce and my Velocity. My TotalForce is reset to (0, 0, 0) after every physics loop, although I will keep my velocity.

I am familiar with doing a collision check between a moving sphere and a static plane when using only velocity. However, what if I have other forces besides velocity, such as gravity? I put the other forces into TotalForces (right now I only have gravity). To compensate for that, when I determine that the sphere is not currently overlapping the plane, I do

    Vector3 forces = (sphereTotalForces + sphereVelocity);
    Vector3 forcesDT = forces * fElapsedTime;
    float denom = Vec3Dot(&plane->GetNormal(), &forces);

However, this can be problematic for how I thought was suppose to be resting contact. I thought resting contact was computed by

denom * dist == 0.0f

Where dist is

float dist = Vec3Dot(&plane->GetNormal(), &spherePosition) - plane->d;

(For reference, the obvious denom * dist > 0.0f meaning the sphere is moving away from the plane)

However, this can never be true. Even when there appears to be "resting contact". This is due to my forces calculation above always having at least a .y of -9.8 (my gravity). When when moving towards a plane with a normal of (0, 1, 0) will produce a y of denom of -9.8.

My question is

1) Am I calculating resting contact correctly with how I mentioned with my first two code snippets?

If so,

2) How should my "other forces" such as gravity be used? Is my use of TotalForces incorrect?

For reference, my timestep is

  mAcceleration = mTotalForces / mMass;
  mVelocity += mAcceleration * fElapsedTime;
  Vector3 translation = (mVelocity * fElapsedTime);

EDIT

Since it appears that some suggested changes will change my collision code, here is how i detect my collision states

if(fabs(dist) <= sphereRadius)
{ // There already is a collision }
else
{
    Vector3 forces = (sphereTotalForces + sphereVelocity);
    float denom = Vec3Dot(&plane->GetNormal(), &forces);

    // Resting contact
    if(dist == 0) { }
    // Sphere is moving away from plane
    else if(denom * dist > 0.0f) { }
    // There will eventually be a collision
    else
    {
        float fIntersectionTime = (sphereRadius - dist) / denom;
        float r;
        if(dist > 0.0f)
            r = sphereRadius;
        else
            r = -sphereRadius;

        Vector3 collisionPosition = spherePosition + fIntersectionTime * sphereVelocity - r * planeNormal;
    }
}

解决方案

You should use if(fabs(dist) < 0.0001f) { /* collided */ } This is to acocunt for floating point accuracies. You most certainly would not get an exact 0.0f at most angles or contact.

the value of dist if negative, is in fact the actual amount you need to shift the body back onto the surface of the plane in case it goes through the plane surface. sphere.position = sphere.position - plane.Normal * fabs(dist);

Once you have moved it back to the surface, you can optionally make it bounce in the opposite direction about the plane normal; or just stay on the plane.

parallel_vec = Vec3.dot(plane.normal, -sphere.velocity);

perpendicular_vec = sphere.velocity - parallel_vec;

bounce_velocity = parallel - perpendicular_vec;

you cannot blindly do totalforce = external_force + velocity unless everything has unit mass.

EDIT:

To fully define a plane in 3D space, you plane structure should store a plane normal vector and a point on the plane. http://en.wikipedia.org/wiki/Plane_(geometry) .

Vector3 planeToSphere = sphere.point - plane.point;

float dist = Vector3.dot(plane.normal, planeToSphere) - plane.radius;

if(dist < 0) { // collided. }

I suggest you study more Maths first if this is the part you do not know.

NB: Sorry, the formatting is messed up... I cannot mark it as code block.

EDIT 2: Based on my understanding on your code, either you are naming your variables badly or as I mentioned earlier, you need to revise your maths and physics theory. This line does not do anything useful.

float denom = Vec3Dot(&plane->GetNormal(), &forces);

A at any instance of time, a force on the sphere can be in any direction at all unrelated to the direction of travel. so denom essentially calculates the amount of force in the direction of the plane surface, but tells you nothing about whether the ball will hit the plane. e.g. gravity is downwards, but a ball can have upward velocity and hit a plane above. With that, you need to Vec3Dot(plane.normal, velocity) instead.

Alternatively, Mark Phariss and Gerhard Powell had already give you the physics equation for linear kinematics, you can use those to directly calculate future positions, velocity and time of impact.

e.g. s = 0.5 * (u + v) * t; gives the displacement after future time t. compare that displacement with distance from plane and you get whether the sphere will hit the plane. So again, I suggest you read up on http://en.wikipedia.org/wiki/Linear_motion and the easy stuff first then http://en.wikipedia.org/wiki/Kinematics .

Yet another method, if you expect or assume no other forces to act on the sphere, then you do a ray / plane collision test to find the time t at which it will hit the plane, in that case, read http://en.wikipedia.org/wiki/Line-plane_intersection .