PDA

View Full Version : Help With Bearing Movement



BloodLust_89
June 19, 2006, 04:31 PM
Greetings, all! Just need a little help with movement of objects in a more complex fashion - using bearing.

I want to move an object at specific degrees but the following isnt working.



//Main Class
public void createBullet()
{
Bullet b = new Bullet(getWidth()/2, getHeight()/2, 33, 3);
}

public void run()
{
while (bRunning)
{
try
{
b.move();
b.paint(getGraphics());
Thread.sleep(tickTime);
}
catch (Exception e)
bRunning = false;
}
}



//Bullet Class
//declaration stuff
int x, //Current x co-ord
y, //Current Y co-ord
pX, //Previous x co-ord
pY, //Previous x co-ord
bearing, //Direction in gegrees of movement
speed; //velocity

//some other stuff

//Constructor
public Bullet(int sX, int sY, int sBearing, int sSpeed)
{
//'s' means Start
x = sX;
y = sY;
pX = sX;
pY = sY;
bearing = sBearing;
speed = sSpeed;
}

//move method
public void move()
{
//convert bearing to radians
int angle = bearing * 2 * Math.PI / 360;
//Set previous x & y co-ord
pX = x;
pY = y;

//Use trig functions to get new X an Y co-ords
x += Math.cos(angle) * speed;
y += Math.sin(angle) * speed;

//Mirror the bearing if the x reach the side of the screen
//and all that.
}

//Paint methos
public paint(Graphics g)
{
g.setColor(new Color(0, 255, 0));
g.drawLine(pX, pY, x, y);
}


Ignoring the errors if n e, the code works, however the movement is definately not rite. I hope u get wat im saying, and if n e 1 has n code for the angle movement post it. l8er

codex
June 20, 2006, 12:33 AM
Haven't looked at the code thoroughly but your angle variable should definitely be a double and not an int!

crosswire
June 21, 2006, 08:28 AM
I would second codex except that I am away from my dev machine to know how java handles int.

I remember having a problem with sin and cosine w.r.t. the sign in a problem the other day and it was solve using an alternate function tangent, but that will not help you. Only test with different angle ranges, eg angle between 0,90,180,270, and -0,-90,-180,-270

Remember also that the y display is negative to traditional y in coordinate geometry.

crosswire
June 21, 2006, 02:41 PM
Try adding a displacement vector to the bullet class
Then set the values once you get the initial bearings.


//Constructor
public Bullet(int sX, int sY, int sBearing, int sSpeed)
{
//'s' means Start
x = sX;
y = sY;
pX = sX;
pY = sY;
bearing = sBearing;
speed = sSpeed;

dX; //displacement vector
dY; //displacement vector

//Note sine use for X

//The convention i used is to have Y up, X right and angle clockwise from up
//calculate angle in rads from bearing here
dX = Math.sin(angle) * speed;
dY = Math.cos(angle) * speed;

}

//Once displacement vector is set then add displacement on every frame in Move()

//Reflect displacement vector on boundary condition


//move method
public void move()
{
pX = x;
pY = y;

x += dX;
y += dY;
}

I still have not fixed the issue with display y is negative of the convention of y coordinate as up

The code is the same but I was just addressing one of the minor errors.

To fix the y sign issue , use

//calculate angle in rads from bearing here
dX = Math.sin(angle) * speed;
dY = - Math.cos(angle) * speed; //negative here
}

//move method
public void move()
{
pX = x;
pY = y;

x += dX;
y += dY;
}
Hope that helps, but test for different ranges of angle because I think that cos function works funny for some angles.

BTW, how does the movement look for what you have

codex
June 21, 2006, 02:55 PM
Let me be more verbose about the "angle is an int" problem.

The line

int angle = bearing * 2 * Math.PI / 360;

is supposed to transform the bearing from degrees (0 - 360) into radians (0 - 2*pi).

If bearing is 90 degrees, the result should be 90*2*pi/360, which is pi/2, about 1.57.

But angle is an int, and it will end up as 1 (no rounding)!!!

The difference is 0.57 in radians, which is almost 33 degrees! That is a big difference.

Furthermore, how do you compile your code? My compiler doesn't allow that line at all, because you cannot assign a double (the expression on the right side of the assignment is double because of Math.PI) to an int variable without explicit casting.

BloodLust_89
June 21, 2006, 03:56 PM
Well, the 'int angle' was a typo, and all the code was typed quickly from out of my head, i had to hurry cuz i was at taits internet cafe. I know radians are in doubles. Thanks for the info on the y co-ord, ill try it out. I guess that the y co-ord thing was the problem, ill let ya know.

Magma
June 21, 2006, 04:36 PM
the first thing that popped into my head has already been said...darnnit


java x,y coordinates are flipped...that's all i had to say *sighs and leaves*

BloodLust_89
June 29, 2006, 06:33 PM
well, i figured it out. It seems the following worked,



double angle = bearing * 2 * Math.PI / 360;

x += Math.cos(angle) * speed;
y += Math.sin(angle) * speed;




when the following didnt.


double angle = bearing * 2 * Math.PI / 360;

x += (int) Math.cos(angle) * speed;
y += (int) Math.sin(angle) * speed;


hmmmmmm, the '(int)' casting part seems to prevent rounding. im gonna investigate.