空气阻力在此模拟中导致速度急剧上升
Air Resistance In this simulation causes the velocity to rise drastically
我遇到的问题是,我试图在此基本物理模拟(Java [处理])中向对象添加阻力,但是一旦我添加了适当的公式,它就会导致对象速度向相反的方向急剧增加。当然,问题是由于某种原因,阻力被计算得太高,但我不确定为什么会这样,因为我正在使用现实世界的方程式。
void setup(){size(1280,720);}
class Circle{
float x,y,r,m,dx,dy,ax,ay,fx,fy;
Circle(float xPos, float yPos, float Radius, float Mass){
x = xPos;
y = yPos;
r = Radius;
m = Mass;
}
void ADD_DRAG(){
fx -= 0.5 * 1.225 * dx * dx * 0.5 * r * PI;
fy -= 0.5 * 1.225 * dy * dy * 0.5 * r * PI;
}
void update(){
ADD_DRAG();
ax = fx / m;
ay = fy / m;
dx += ax / frameRate;
dy += ay / frameRate;
x += dx / frameRate;
y += dy / frameRate;
}
}
Circle[] SceneObjects = {new Circle(50,50,20,20000),new Circle(50,50,2,20)};
void draw(){
background(51);
for (Circle c : SceneObjects){
c.update();
circle(c.x * 3,c.y * 3,c.r * 3);
}
}
void mouseClicked(){
if(SceneObjects[1].fx != 2000)
SceneObjects[1].fx = 2000;
else
SceneObjects[1].fx = 0;
}
这是代码,本质上有一个 Circle class,它存储对象属性,然后在每个绘制循环中更新应用的力。 mouseClicked void 仅用于通过向对象添加力来进行测试。感谢所有帮助,谢谢!
我正在使用的数学:
重新排列 ax = fx / m;
的 F=ma
加速度 * 时间 = dx += ax / frameRate;
的速度(frameRate 为 1/次)
距离=速度*时间=for x += dx / frameRate;
(同上)
对于使用此等式 https://www.grc.nasa.gov/WWW/K-12/rocket/drageq.html 并添加空气密度等常数的阻力,如所见。
这里有一些错误。
你还没有给我们数字(或minimal complete example),但向量代数是关闭的。
对,加速度是f = -kv2,|v|2 = vx2 + vy2,但这并不意味着你可以将f分解为fx =kvx2 和 fy=kvy 2。不仅你的幅度不对,而且你的加速度现在(通常)与运动不一致;弹丸的路径将倾向于 曲线 朝向轴之间的对角线(例如 x=y)。
此外,您的代码总是在负 x 和负 y 方向上提供加速度。如果你的抛射物恰好开始朝那个方向运动,你的空气阻力版本会加速它。
最后,您的时间间隔可能太大了。
有更好的方法。微分方程为v' = -k v|v|,精确解为v = (1/kt) z, (with appropriate choice of the starting time) where z is单位方向向量。 (我不知道如何在字母上加上插入符。)这导致 v(t) = (1/t)v (t=1.0)
所以你可以计算出一个虚构的时间 t0 并使用 1/(kt) 计算每个新速度,或者你可以根据以前的速度计算新速度: vn+1 =vn/(kd vn + 1),其中 d 是时间间隔。 (然后当然你必须将 v 分解成 vx 和 vy 正确。)
如果您不熟悉向量代数,这可能会让人感到困惑,但如果不学习基础知识,您将无法使用 air-resistance 模拟程序。
我遇到的问题是,我试图在此基本物理模拟(Java [处理])中向对象添加阻力,但是一旦我添加了适当的公式,它就会导致对象速度向相反的方向急剧增加。当然,问题是由于某种原因,阻力被计算得太高,但我不确定为什么会这样,因为我正在使用现实世界的方程式。
void setup(){size(1280,720);}
class Circle{
float x,y,r,m,dx,dy,ax,ay,fx,fy;
Circle(float xPos, float yPos, float Radius, float Mass){
x = xPos;
y = yPos;
r = Radius;
m = Mass;
}
void ADD_DRAG(){
fx -= 0.5 * 1.225 * dx * dx * 0.5 * r * PI;
fy -= 0.5 * 1.225 * dy * dy * 0.5 * r * PI;
}
void update(){
ADD_DRAG();
ax = fx / m;
ay = fy / m;
dx += ax / frameRate;
dy += ay / frameRate;
x += dx / frameRate;
y += dy / frameRate;
}
}
Circle[] SceneObjects = {new Circle(50,50,20,20000),new Circle(50,50,2,20)};
void draw(){
background(51);
for (Circle c : SceneObjects){
c.update();
circle(c.x * 3,c.y * 3,c.r * 3);
}
}
void mouseClicked(){
if(SceneObjects[1].fx != 2000)
SceneObjects[1].fx = 2000;
else
SceneObjects[1].fx = 0;
}
这是代码,本质上有一个 Circle class,它存储对象属性,然后在每个绘制循环中更新应用的力。 mouseClicked void 仅用于通过向对象添加力来进行测试。感谢所有帮助,谢谢!
我正在使用的数学:
重新排列 ax = fx / m;
的 F=ma
加速度 * 时间 = dx += ax / frameRate;
的速度(frameRate 为 1/次)
距离=速度*时间=for x += dx / frameRate;
(同上)
对于使用此等式 https://www.grc.nasa.gov/WWW/K-12/rocket/drageq.html 并添加空气密度等常数的阻力,如所见。
这里有一些错误。
你还没有给我们数字(或minimal complete example),但向量代数是关闭的。
对,加速度是f = -kv2,|v|2 = vx2 + vy2,但这并不意味着你可以将f分解为fx =kvx2 和 fy=kvy 2。不仅你的幅度不对,而且你的加速度现在(通常)与运动不一致;弹丸的路径将倾向于 曲线 朝向轴之间的对角线(例如 x=y)。
此外,您的代码总是在负 x 和负 y 方向上提供加速度。如果你的抛射物恰好开始朝那个方向运动,你的空气阻力版本会加速它。
最后,您的时间间隔可能太大了。
有更好的方法。微分方程为v' = -k v|v|,精确解为v = (1/kt) z, (with appropriate choice of the starting time) where z is单位方向向量。 (我不知道如何在字母上加上插入符。)这导致 v(t) = (1/t)v (t=1.0)
所以你可以计算出一个虚构的时间 t0 并使用 1/(kt) 计算每个新速度,或者你可以根据以前的速度计算新速度: vn+1 =vn/(kd vn + 1),其中 d 是时间间隔。 (然后当然你必须将 v 分解成 vx 和 vy 正确。)
如果您不熟悉向量代数,这可能会让人感到困惑,但如果不学习基础知识,您将无法使用 air-resistance 模拟程序。