微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何解决二维空间中的碰撞响应?

如何解决如何解决二维空间中的碰撞响应?

我从碰撞算法得到了碰撞结果。碰撞结果包含两个碰撞体的接触点、分离长度和碰撞法向量。

collision info

bodyA:矩形 ABCD

bodyB:线段EF

normal:碰撞面的法向量

接触点对1:D点和G点

接触点对2:C点和H点

分隔长度:1

我创建了一个结构体来保存碰撞信息:

using real = double;
    struct Collision
    {
        bool isColliding = false;
        Body* bodyA = nullptr;
        Body* bodyB = nullptr;
        std::vector<PointPair> contactList;
        Vector2 normal;
        real penetration = 0;
    };

然后我创建一个碰撞求解器类和求解器数据结构:

    struct SolverData
    {
        Collision info;
        real effectiveMassnormal = 0;
        real bias = 0;
        Vector2 ra;
        Vector2 rb;
    };
    class CollisionSolver
    {
        public:
            void add(const Collision& info);
            void prepare(const real& dt);
            void solveVeLocity(const real& dt);
            void solvePosition(const real& dt);
        private:
            std::vector<SolverData> m_dataList;
            std::vector<Collision> m_list;
    };

函数 void prepare() 中,我只是像这样计算接触点的有效质量:

void prepare(const real& dt)
{
    for (Collision& info : m_list)
    {
        for (auto& contact : info.contactList)
        {
            Vector2 ra = contact.pointA - info.bodyA->position();
            Vector2 rb = contact.pointB - info.bodyB->position();
            Vector2 normal = info.normal;

            real im_a = info.bodyA->inverseMass();
            real im_b = info.bodyB->inverseMass();
            real ii_a = info.bodyA->inverseInertia();
            real ii_b = info.bodyB->inverseInertia();

            real ra_n = ra.cross(normal);
            real rb_n = rb.cross(normal);

            real ra_t = ra.cross(tangent);
            real rb_t = rb.cross(tangent);

            real inv_dt = 1.0 / dt;
                
            SolverData data;
            data.bias = -m_bias * inv_dt * info.penetration;

            //effective mass = 1.0 / k-matrix
            data.effectiveMassnormal = 1.0 /
                (im_a + ii_a * ra_n * ra_n + im_b + ii_b * rb_n * rb_n);

            data.info = info;
            data.ra = ra;
            data.rb = rb;
            
            m_dataList.emplace_back(data);
        }
    }
}

在solveVeLocity()函数中,我计算了接触点的速度和相对速度,然后代入公式Jv+b=0得到脉冲的大小:

void solve(const real& dt)
{
    for(int i = 0;i < m_iteration;i++)
        {
            for (SolverData& data : m_dataList)
            {
                Vector2 vB = data.info.bodyB->veLocity() + 
     Vector2::crossproduct(data.info.bodyB->angularVeLocity(),data.rb);

                Vector2 vA = data.info.bodyA->veLocity() + 
     Vector2::crossproduct(data.info.bodyA->angularVeLocity(),data.ra);
                Vector2 rv = vB - vA;
                
                real rv_n = rv.dot(data.info.normal);
                real lambda_n = data.effectiveMassnormal * (rv_n - data.bias);
                
                Vector2 impulsenormal = lambda_n * data.info.normal;
                
                data.info.bodyA->applyImpulse(impulsenormal,data.ra);
                data.info.bodyB->applyImpulse(-impulsenormal,data.rb);
                
            }
        }

        m_dataList.clear();
        m_list.clear();
}

我认为一切都很清楚,但我得到了错误的结果:

wrong

bodyA 的质量是 100kg,我认为 bodyB 是质量无穷大的地面。 矩形的宽度和高度相同,1米。

bodyA 的位置是 (0,-2),bodyB 的位置是 (0,-8)。

我使用的单位是 Kg/M/N。

答错了怎么解决

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?