代码本色–第二章–力
引言
本篇文章主要是记录有关代码本色第二章的一些编程习作,本次习作模拟一些物理场景,主要牵扯到三个力:重力、浮力、摩擦力。
编程作品中涉及到三种场景:1、三个不同大小的小球受到重力作用从静止落下,掉入水(密度为1)中,受到不同的浮力作用最终静止;2、小车以一定初速度行驶在马路上,并且只受摩擦力与重力作用,可观察到当物体在摩擦力作用下做先减速再加速的运动。3、三个相同大小的小球受到重力作用从静止落下,调入不同密度的液体中,可观察到物体受到不同的浮力作用而做不同的运动。程序运行后,点击鼠标左键可进行场景的切换。
场景一
效果示例
使用录屏软件看到最终效果与原效果略有偏差
效果解说
可看到上面三个小球大小不同,三个小球的密度相同,所以它们的重力不同,但是我们可以看到在未及水中时,三者的速度是一样的,因为三者同时从静止开始受重力作用下落,由公式F=ma与G=mg可知三者的加速度a=g,三者拥有相同的加速度与初速度,所以开始做同样的匀加速运动,但是当物体开始掉落到水中时,开始受到浮力作用,浮力:F浮=G排=m排g=ρ液gV排三者的大小不同,所以排出的水的体积不同,自然所受浮力也不同,所以三者开始做不同加速度的运动,右边小球体积最大,所受浮力最大,也最先停下来。
代码展示
本场景中,浮力与重力的模拟使用的物理公式除了’效果解说’中已经提及的,还有速度与位移的公式:v=v0+at,x=v0t+1/2at2。小球使用了自己写的mover类,使用update函数进行位置、速度的更新,三个场景使用的函数有许多共同之处,所以先展示场景一设计的update函数,在博文的最后再附上所有的函数。
void update(float y, float densi)
{
float mass=theta*pow(radius, 3)*this.density;
PVector G_A=new PVector(0, g_a);//重力加速度
this.acceleration=G_A;
//浮力
if (this.location.y>(y-this.radius))
{
float tj;//=pow(radius,3)*theta;
float f;
if (this.location.y<=y)
{
float h=radius-y+this.location.y;
tj=PI*pow(h, 2)*(radius-h/3);//球缺体积
f=tj*densi*g_a/mass;//浮力大小
PVector F=new PVector(0, -f);
this.acceleration.add(F);
} else if (this.location.y<(y+radius))
{
float h=radius+y-this.location.y;
tj=pow(radius, 3)*theta-PI*pow(h, 2)*(radius-h/3);
f=tj*densi*g_a/mass;//浮力大小
PVector F=new PVector(0, -f );
this.acceleration.add(F);
} else
{
tj=pow(radius, 3)*theta;
f=tj*densi*g_a/mass;//浮力大小
PVector F=new PVector(0, -f);
this.acceleration.add(F);
}
}
this.speed.add(this.acceleration.normalize());
//this.checkSpeed();
this.location.add(PVector.div(this.speed, 2));
this.acceleration.mult(0);
}
场景二
效果示例
效果解说
在本场景中,只赋给小车一个初速度,之后小车仅受摩擦力的作用,所以在小车前进时,摩擦力为阻力,小车做减速运动,当小车速度为0时,我们假设小车仍受反方向的摩擦力作用,则小车会在摩擦力作用下向反方向做加速运动,触碰边缘后小车速度大小不变方向相反,所以也就出现了我们所看到的的小球做周期性的往返运动。涉及到摩擦力的计算公式F=uN,以及速度与位移的公式:v=v0+at,x=v0t+1/2at2还有F=ma
部分代码展示
void update2(float u)//摩擦力
{
float normal=1;
if (location.x>100)
{
float f=u*normal;
PVector F