我正在尝试使用 SDL2 在 C++ 中制作一个基本的软体引擎。它的工作原理是考虑软体的所有顶点由相同长度和刚度的弹簧互连(具有相同的弹簧常数k
和长度natural_length
)。为了让它更真实,我还引入了一个阻尼常数c
。
然而,我遇到了一个令人沮丧的问题。在过去的 6-7 个小时里,我一直在尝试调试它,但无济于事。柔软的身体遇到许多我看不懂的奇怪错误
- 首先,“软体”一点也不“软”。每次都会变成一堆皱巴巴的分数。我已经尝试只计算相邻点的力,但它仍然变得一团糟。
- 即使我没有施加任何外力,柔软的身体每次都会飞到顶角(原点)。
这两个错误都在这张图片中可见 -
以下 2 个函数(它们与所有变量在同一个类中,因此不需要接受任何参数)是代码的实际模拟部分。(我省略了其余代码,因为它是不必要的。)
我使用 a vector
ofSDL_Points
来存储每个点,并使用 a vector
ofVector
来存储它们的速度。如果您想知道Vector
是什么,它只是一个struct
我创建的,只有 2 个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()
函数返回 a 的大小Vector
。我用于图像
的恢复系数e
、阻尼常数c
和弹簧常数的值分别为 0.5、10 和 100。k
感谢您抽出时间来阅读!帮助将不胜感激。
编辑
如果有人想测试它,这是整个代码。您将需要 SDL 和一个文件夹 'img',在 'img/point.bmp' 中有一个 '.bmp' 文件。