4 Replies Latest reply on Mar 8, 2010 8:26 AM by 843853

# Force Physics Problem

With my Ball Physics engine I'm trying to apply a force with it's own power and direction on a body that also has a speed and direction. This force should should alter the bodies speed and direction. Here's a diagram of what I'm trying to do [Force Physics.jpg|http://www.splorg.org.uk/Personal/Force%20Physics.jpg] . Somewhere along the way my code messes up. When the force is applied at 270 degrees the body moves at 90 degrees but when the force is applied at 180 degrees the body moves in the right direction but twice as fast as before.

There's a lot of pieces code that could affect this but here it is:
public class maths {

public static double sqr( double x ) {
return x*x;
}

public static double vd_x( double sp, double dir ) {
return sp*Math.cos(dir/180*Math.PI);
}

public static double vd_y( double sp, double dir ) {
return sp*-Math.sin(dir/180*Math.PI);
}

public static double x_dist( double x1, double x2 ) {
double xd = x2-x1;
return xd;
}

public static double p_dist( double x1, double y1, double x2, double y2) {
double pd = Math.sqrt(sqr(x_dist(x1,x2))+sqr(x_dist(y1,y2)));
if (pd<0)
{
pd = -pd;
}
return pd;
}

public static double radtodeg( double a ) {
double r  = 180/Math.PI;
return a*r;
}

public static double p_dir( double x1, double y1, double x2, double y2) {
return d;
}

}
public class Ball {

// r = radius; m = mass; b = bouncyness;
public static double x;
public static double y;
public static double r;
public static double m;
public static double b;

// dir = direction; sp = speed
public static double dir;
public static double sp;

// ang = angle; rot = rotation (none of these are used yet)
public static double ang;
public static double rot;

public Ball(double xx, double yy, double rr, double mm, double bb)
{
x = xx;
y = yy;
r = rr;
dir = 0;
sp = 0;
ang = 0;
rot = 0;
m = mm;
b = bb;
}

public static void move() {
x += maths.vd_x(sp, dir);
y += maths.vd_y(sp, dir);
}

// here's where i apply a force
public static void force(double f, double d) {
double nx;
double ny;
nx = x + maths.vd_x(f,d) + maths.vd_x(sp,dir);
ny = y + maths.vd_y(f,d) + maths.vd_y(sp,dir);
sp = maths.p_dist(x,y,nx,ny);
dir = maths.p_dir(x,y,nx,ny);
}

}
public class World {

public static int inst_no;
public static Ball[] b_inst;
public static double density;

public static void start(double dense) {
inst_no = 0;
b_inst = new Ball[9999];
density = dense;
}

public static int add_ball_inst(double x, double y, double r, double m, double b) {
b_inst[inst_no] = new Ball(x,y,r,m,b);
return inst_no;
}

// This is where everything is applied every frame
public static void step() {
int i;
int ii;
double f;
for(i=0;i<=inst_no;i+=1)
{
// here i'm just applying friction where f = force of friction
if (b_inst.m!=0&&b_inst[i].sp!=0)
{
f = -0.5*((b_inst[i].sp*b_inst[i].r*density)/(b_inst[i].m*b_inst[i].sp));

if ((b_inst[i].sp>0&&b_inst[i].sp-f>=0)||(b_inst[i].sp<0&&b_inst[i].sp+f<=0)) {
b_inst[i].sp+=f; }
else {
b_inst[i].sp=0; }

b_inst[i].move();
}
}

}

}
I know it's a lot of code and I'm pretty sure that the problem is coming from the 'force' function but just in case it's not I put the rest of the code in as well.
Tom.

Edit: Don't worry I think I've got it fixed.
Working code:
public static void force(double f, double d) {
double xspeed = maths.vd_x(f, d) + maths.vd_x(sp, dir);
double yspeed = maths.vd_y(f, d) + maths.vd_y(sp, dir);
sp = maths.p_dist(x,y,x+xspeed,y+yspeed);
dir = maths.p_dir(x,y,x+xspeed,y+yspeed);
}
public static double p_dir( double x1, double y1, double x2, double y2) {
return -d;
}
Edited by: tomster1996 on Feb 13, 2010 10:45 AM

Edited by: tomster1996 on Feb 13, 2010 10:49 AM
• ###### 1. Re: Force Physics Problem
I didn't fish through all of your code, but you should have simpler formulas:

Xchange = distance * cos(theta);
Ychange = distance * sin(theta);

You don't simplify that, it's the basic direction vectors of 2D. if you are worried that you're getting theta to be over 360, then you can have something along the line of theta %= 360;

You have several formulas that look suspect, but without a description of what each does, then I'm only guessing as to what it is you want the actual result to be, for instance:

distance = sqrt((X1-X2)^2 + (Y1-Y2)^2); you don't need a scaler in there.

Theta = atan(Ychange/Xchange); No scalers needed there either.

You also have at least one place where you have x_dist as the scaler for your X and Y functions.
• ###### 2. Re: Force Physics Problem
Apply a force on a ball, I will do this:
class Ball {
double mass;
double x, y; //location
double vx, vy; // velocity
double ax, ay; // acceleration
double fx, fy; // the force applies on this ball.

public void run() {
// Just assume it's call per second in a loop
ax = fx/mass;
ay = fy/mass;
vx += ax;
vy += ay;
x += vx;
y += vy;
}

public void setForce(double fx, double fy) {
this.fx = fx;
this.fy = fy;
}

public void setForce2(double f, double direction) {
setForce(f*Math.cos(direction), f*Math.sin(direction));
}
}
• ###### 3. Re: Force Physics Problem
Applying a force is different tonsetig a force. When I apply a force it changes the motion and directionr proportionally to it's current motion and direction.
• ###### 4. Re: Force Physics Problem
I just follow basic physical law: s = v*t = (v+a*t)*t = F/m*t*t

Maybe what I want to say is you don't need too many math operations like sqrt, sin, cos when calculating motion. If you treat motion parameters as vector like position (in 2D coordinates), the calculation is very simple. Anyway, I just noticed you find the solution, that's ok.

Edited by: qqsu_azure on Mar 8, 2010 4:25 PM