空气阻力在这个模拟中导致速度急剧上升。

go评论103阅读模式

Air Resistance In this simulation causes the velocity to rise drastically

问题

``````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;
m = Mass;
}

fx -= 0.5 * 1.225 * dx * dx * 0.5 * r * PI;
fy -= 0.5 * 1.225 * dy * dy * 0.5 * r * PI;
}

void update() {
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;
}
``````

• 重新排列 F=ma 得到 `ax = fx / m;`
• 加速度 * 时间 = 速度 得到 `dx += ax / frameRate;`（其中 frameRate 是时间的倒数）
• 距离 = 速度 * 时间，用于 `x += dx / frameRate;`（与上述类似）
• 对于拖力，我使用的是这个方程 https://www.grc.nasa.gov/WWW/K-12/rocket/drageq.html，并添加了常数，如空气密度等。

The issue I have is that I'm attempting to add drag to an object in this basic physics simulation (Java [Processing]), but once I add the appropriate formula, it causes the objects velocity to increase drastically in the opposite direction. Of course the problem is that drag for some reason is being calculated too high but I'm not sure why thats happening as I'm using the real world equation.

``````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;
m = Mass;
}
fx -= 0.5 * 1.225 * dx * dx * 0.5 * r * PI;
fy -= 0.5 * 1.225 * dy * dy * 0.5 * r * PI;
}
void update(){
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;
}
``````

This is the code, essentially there is a Circle class which stores the objects properties and then the forces applies are updated each draw loop. The mouseClicked void is just for testing by adding a force to the objects. All and any help is appreciated, thanks!

Maths I am Using:
Rearranged F=ma for `ax = fx / m;`
Acceleration * time = Speed for `dx += ax / frameRate;` (frameRate is 1/time)
Distance = Speed * time = for `x += dx / frameRate;` (same as above)
For drag im using this equation https://www.grc.nasa.gov/WWW/K-12/rocket/drageq.html with the constants eg air density etc added as seen.

答案1

There are a couple of things wrong here.

You haven't given us numbers (or a minimal complete example), but the vector algebra is off.

Yes, the acceleration is f = -kv<sup>2</sup>, and |v|<sup>2</sup> = v<sub>x</sub><sup>2</sup> + v<sub>y</sub><sup>2</sup>, but that doesn't mean that you can decompose f into f<sub>x</sub>=kv<sub>x</sub><sup>2</sup> and f<sub>y</sub>=kv<sub>y</sub><sup>2</sup>. Not only is your magnitude off, but your acceleration is now not (in general) aligned with the motion; the path of your projectile will tend to curve toward a diagonal between the axes (e.g. x=y).

Also, your code always gives acceleration in the negative x and negative y directions. If your projectile happens to start out going that way, your version of air resistance will speed it up.

Finally, your time interval may simply be too large.

There is a better way. The differential equation is v' = -k v|v|, and the exact solution is v = (1/kt) z, (with appropriate choice of the starting time) where z is the unit direction vector. (I don't know how to put a caret over a letter.) This leads to v(t) = (1/t)v(t=1.0)

So you can either work out a fictional time t<sub>0</sub> and calculate each new velocity using 1/(kt), or you can calculate the new velocity from the previous velocity: v<sub>n+1</sub> =v<sub>n</sub>/(kd v<sub>n</sub> + 1), where d is the time interval. (And then of course you have to decompose v into v<sub>x</sub> and v<sub>y</sub> properly.)

If you're not familiar with vector algebra, this may seem confusing, but you can't get an air-resistance sim to work without learning the basics.

• 本文由 发表于 2020年10月7日 17:14:58
• 转载请务必保留本文链接：https://go.coder-hub.com/64240928.html
• java
• physics
• processing
• simulation

go 109

go 132