我试图使用SDL2在C++中制作一个基本的软体引擎。它通过将所有软体的顶点视为由相同长度和刚度的弹簧相互连接 (具有相同的弹簧常数k和长度natural_length) 来工作。为使其更加逼真,我还引入了阻尼常数c。
然而,我遇到了一个令人沮丧的问题。我已经尝试过了过去6-7小时的调试,但毫无进展。软体遇到许多奇怪的错误,我不理解。
我在图像中使用的反弹系数
然而,我遇到了一个令人沮丧的问题。我已经尝试过了过去6-7小时的调试,但毫无进展。软体遇到许多奇怪的错误,我不理解。
- 首先,“软体”根本不“柔软”。每次都会变成一堆杂乱的点。我尝试只计算相邻点之间的力量,但它仍然变成了一堆杂乱的东西。
- 软体总是飞向左上角(原点),尽管我没有实现任何外部力。
这些错误都可以在此图像中看到 -
以下两个函数(它们与所有变量在同一类中,因此不需要接受任何参数)是代码的实际模拟部分。(我省略了其余代码,因为它是不必要的。)
我使用了一个SDL_Points的向量来存储每个点,以及一个Vector的向量来存储它们的速度。如果你想知道Vector是什么,它只是我创建的一个结构体,它只有两个float成员x和y。
acceleratePoints()函数为每个点分配速度和位置,而checkCollision()函数则检查与窗口边界(其宽度为scr_w,高度为scr_h)的碰撞。
void acceleratePoints()
{
vector<SDL_Point> soft_body_copy=soft_body;
vector<Vector> velocity_copy=velocity;
for(int i=0;i<soft_body.size();++i)
{
for(int j=0;j<soft_body.size();++j)
{
if(i!=j)
{
Vector d={(soft_body[j].x-soft_body[i].x)/100.0,(soft_body[j].y-soft_body[i].y)/100.0};
float t=atan2(d.y,d.x);
float disp=fabs(magnitude(d))-natural_length/100.0;
velocity_copy[i].x+=(k*disp*cos(t))/10000.0;
velocity_copy[i].y+=(k*disp*sin(t))/10000.0;
velocity_copy[i].x-=c*velocity_copy[i].x/100.0;
velocity_copy[i].y-=c*velocity_copy[i].y/100.0;
soft_body_copy[i].x+=velocity_copy[i].x;
soft_body_copy[i].y+=velocity_copy[i].y;
}
}
soft_body=soft_body_copy;
velocity=velocity_copy;
}
}
void checkCollision()
{
for(int k=0;k<soft_body.size();++k)
{
if(soft_body[k].x>=scr_w||soft_body[k].x<=0)
{
velocity[k].x*=e;
soft_body[k].x=soft_body[k].x>scr_w/2?scr_w-1:1;
}
if(soft_body[k].y>=scr_h||soft_body[k].y<=0)
{
velocity[k].y*=e;
soft_body[k].y=soft_body[k].y>scr_h/2?scr_h-1:1;
}
}
}
magnitude()
函数返回Vector
的大小。我在图像中使用的反弹系数
e
、阻尼常数c
和弹簧常数k
的值分别为0.5、10和100。
感谢您抽出时间阅读!如有帮助将不胜感激。
编辑
这里是完整的代码,如果有人想测试它。你需要SDL和一个文件夹'img',其中包含一个'.bmp'文件'img/point.bmp'。
natural_length
。 - AvZ