Search code examples
javaprocessingsimulationphysics

Air Resistance In this simulation causes the velocity to rise drastically


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;
    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;
}

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.


Solution

  • 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 = -kv2, and |v|2 = vx2 + vy2, but that doesn't mean that you can decompose f into fx=kvx2 and fy=kvy2. 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 t0 and calculate each new velocity using 1/(kt), or you can calculate the new velocity from the previous velocity: vn+1 =vn/(kd vn + 1), where d is the time interval. (And then of course you have to decompose v into vx and vy 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.