Archived

This topic is now archived and is closed to further replies.

Afterlife

Moving an object with 360 possible directions...

Recommended Posts

I was trying to make this turnable and movable object. My first idea was to use the cosine algorithm (pow(c)=2*pow(x)*pow(y)*cos(angle)) with sqrt(pow(vx)+pow(vy)=combined speed), compare the current angle to a 0 degree angle (speeds of 0,combined speed, going up) ect ect... But getting the speeds from those algs would be almost impossible, so I figured I''d try vy with many values from -combined speed to combined speed increasing it by 0.0001 and checking with multiplying with 1000 and changing to int if you get the idea... But that would be way too slow and complex. What other ways are there to determining x and y speeds from the angle? Probably I have to check in which fourth the angle is in..

Share this post


Link to post
Share on other sites
float cosine[360], sine[360];

Precalculate the values on startup.

unsigned short PlayerDirection;
short PlayerVelocity;
int PlayerX;
int PlayerY;

case left:
PlayerDirection+=1;
PlayerDirection%=360;
break;

case right:
PlayerDirection+=359;
PlayerDirection%=360;
break;

case up:
PlayerVelocity++;
break;

case Down:
PlayerVelocity--;
break;

PlayerX+=sine[PlayerDirection]*PlayerVelocity;
PlayerY+=cosine[PlayerDirection]*PlayerVelocity;


Ben

[Icarus Independent | Jump Down The Rabbithole | Tombstone: Vendetta ]

Share this post


Link to post
Share on other sites
Thanks, allthough I couldn''t get it working properly . The object turned only about 135 degrees right and no further, and back from 135 degs to 0 degrees with other direction, I just replaced it with this (I forgot that Allegro rotates with 256 system):
  if(key[KEY_RIGHT]) {angle++;rest(10);} if(angle<0) angle=255;
if(key[KEY_LEFT]){angle--;rest(10);} if(angle>255) angle=0;

Now it rotates ok, but the heading is still wrong... I tried it at first with 360 (the drawing wouldn''t be realisktic, but atleast the heading should work), but no luck. Here''s how I calcuate the cosine and sine currently :
  for(i=0;i<256;i++)
{
cosine[i]=cos(360.0/256.0*i); /*Changes 256 "system" to 360 "system", shouldn''t affect the result because its the same as it is with 360 which I tried at first*/
sine[i]=sin(360.0/256.0*i);
}

And here''s the heading code :
  arrow.x+=sine[angle]*speed;
arrow.y-=cosine[angle]*speed;

Can someone still help me?

Share this post


Link to post
Share on other sites
Forget all the cosines.

the easiest(I find) to do that is using a DirectionVector, and UpVector and a LeftVector and position. It evens stop the gimbal lock!!

When you want to move forward, you simply do

speed*DirectionVector + position.

to move backward :

speed*-DirectionVector + position

To strafe left:

speed*-leftVector + position

to strafe right :

speed*-leftVector + position

You can figure out how to move up!!




If you want to rotate your object say, 30 along the y axis, you simply create a matrix with UpVector(because up is your y axis now) as your rotation axis.(You could use quaternions also). DirectionVector is Z and left vector is x.

With that, you get no gimbal lock!

Now the nice thing about this scheme is that if you keep this information in an object you get 2 matrices from it : The view Matrix(the world seen from the object) and the object position Matrix( if you are looking from somewhere else and want to place the object in its right position in the world )

The ViewMatrix is this :

left.x left.y left.w -pos.x
Up.x Up.y Up.w -pos.y
Dir.x Dir.y Dir.y -pos.z
0 0 0 1

The object transform
left.x Up.x Dir.x pos.x
left.y Up.y Dir.y pos.y
left.z Up.z Dir.z pos.z
0 0 0 1

All nice and cool.

If you are using opengl, just load those matrix using glMultMatrixf. But warning, to use these matrices in opengl you need to scale you world by calling
glScalef(-1,1,-1). This is because opengl default position looks at (0,0,-1), but the matrix above default position is (0,0,1). You also need to scale X because then your left will be in the opposite direction.

To use it with Direct3d, you only need to scale x by -1.

You could also scale the vector directly before creating the matrix. You pick which one you prefer.

I know it is probably very heavy on data.

I have implemented a generic camera from this scheme an I use it everywhere, it is so usefull and you get all the degree of freedom and no gimbal lock!!

I knew from other books that we could implement a camera like that, but I only understood all this from a book called realistic ray-tracing. The book also makes you create a bunch of tools which makes writing the camera a breeze!!.

http://www.amazon.com/exec/obidos/ASIN/1568811101/qid=997372138/sr=2-1/ref=aps_sr_b_1_1/102-4097640-2548114

It is a small book about pratical ray-tracing very worth the 35.00USD


Share this post


Link to post
Share on other sites
Thanks, but I should have probably mentioned that I''m tryiong this in 2d first(stupid me). Matrices are too complex for my precambrig brains right now . I think they teach matrices in advanced maths on the second year of highschool, so maby then I''ll be able to try it in 3d. Right now I''m just looking for a simple way to rotate a ship in 2d space (like in asteroids) and make it move in that angle(the rotation part I have already handled).
so the angle is 0-360(I can change it to the 256 degree system when I draw the object), how do I make the object move with a certain angle. What is it that I did wrong with the cosines and sines? Or is it perhaps possible to use algorithms such as circles algorithm (pow(x-x0,2)+pow(y-y0,2)=pow(radius,2))??

Share this post


Link to post
Share on other sites
//X1, Y1 are the objects current coords
//Angle is the direction in degrees

Y2 = cos(angle);
X2 = sin(angle);

X1+=(X2*Velocity);
Y1+=(Y2*Velocity);

//Blit Object at X1,Y1

This will move the object at the angle you set. Only problem is it is kind of slow...

Hope this helps,
PaladinGLT

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
make sure to measure your angles in radians, not degrees. Degrees go from 0 to 360, radians go from 0 to 2pi. Then the cos and sin functions should work correctly.

Share this post


Link to post
Share on other sites