我有一个物理模拟,它允许你放置区域约束,以便内部的物体不会退出该区域。然而,如果原子越过“壁”中的一个并且区域约束它破坏了物理模拟。为什么这样做? 更新方法:

if (!atom.IsStatic)
{
    Vector2 force = Vector2.Zero;
    bool x = false, y = false;
    if (atom.Position.X - atom.Radius < _min.X)
    {
        force = new Vector2(-(_min.X - atom.Position.X), 0);
        if (atom.Velocity.X < 0)
            x = true;
    }
    if (atom.Position.X + atom.Radius > _max.X)
    {
        force = new Vector2(atom.Position.X - _max.X, 0);
        if (atom.Velocity.X > 0)
            x = true;
    }
    if (atom.Position.Y - atom.Radius < _min.Y)
    {
        force = new Vector2(0, -(_min.Y - atom.Position.Y));
        if (atom.Velocity.Y < 0)
            y = true;
    }
    if (atom.Position.Y + atom.Radius > _max.Y)
    {
        force = new Vector2(0, atom.Position.Y - _max.Y);
        if (atom.Velocity.Y > 0)
            y = true;
    }
    atom.ReverseVelocityDirection(x, y);
    if (!atom.IsStatic)
    {
        atom.Position += force;
    }
}
有帮助吗?

解决方案 3

难道你不知道,在经过大约半个小时的盲目黑客攻击后,我想到的不是应用位置修正。这就像一个魅力。对于任何感兴趣的人,这里是更新的代码:

if (!atom.IsStatic)
{
    if (atom.Position.X - atom.Radius < _min.X && atom.Velocity.X < 0)
    {
        atom.ReverseVelocityDirection(true, false);
    }
    if (atom.Position.X + atom.Radius > _max.X && atom.Velocity.X > 0)
    {
        atom.ReverseVelocityDirection(true, false);
    }
    if (atom.Position.Y - atom.Radius < _min.Y && atom.Velocity.Y < 0)
    {
        atom.ReverseVelocityDirection(false, true);
    }
    if (atom.Position.Y + atom.Radius > _max.Y && atom.Velocity.Y > 0)
    {
        atom.ReverseVelocityDirection(false, true);
    }
}

其他提示

我看到你正在用一个恒定的时间步长T进行计算。当通过每个步骤的建模碰撞时,你应该使用等于最小时间的时间步长,然后任何原子到达任何障碍物。

使时间步长变量,原子永远不会“隧道”障碍。

P.S。碰撞检测有很多优化,请阅读gamedev论文以获取相关信息。

<强> P.S。一个错误?

force = new Vector2(-(_min.X - atom.Position.X), 0);

为X和Y反射单独创建力。当原子进入角落时会发生什么?只会施加第二种力量。

P.P.S:使用epsilon

一个更重要的注意事项:如果使用浮点,则会累积错误,您应该使用eps:

abs(atom.Position.Y + atom.Radium - _max.Y) < eps

其中,eps是比任务中的正常尺寸小得多的数字,例如0.000001。

你似乎已经解决了这个问题,但我注意到“强迫”似乎是错的。它将原子从边界移开,即使它在错误的一侧。假设一个原子射过_max.X:

if (atom.Position.X + atom.Radius > _max.X) 
    { 
        force = new Vector2(atom.Position.X - _max.X, 0); 
        ...
    } 

现在“强迫”将在+ x方向,并且原子与墙的距离将在每次迭代时加倍。吊杆!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top