问题描述
我从碰撞算法得到了碰撞结果。碰撞结果包含两个碰撞体的接触点、分离长度和碰撞法向量。
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();
}
我认为一切都很清楚,但我得到了错误的结果:
bodyA 的质量是 100kg,我认为 bodyB 是质量无穷大的地面。 矩形的宽度和高度相同,1米。
bodyA 的位置是 (0,-2),bodyB 的位置是 (0,-8)。
我使用的单位是 Kg/M/N。
答错了怎么解决?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)