Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Sin And Cos Help

This thread is locked; no one can reply to it. rss feed Print
Sin And Cos Help
dakatt
Member #10,695
February 2009

Can someone with a bit more knowledge tell me where I'm going wrong. I've tried different combinations of fixed and floats but the results seem weird. The rotation is off after a full rotation.

<code ="1">
class CPlayer{
public:
CPlayer(CKeyboard*,CMouse*);
~CPlayer(){}

void Update();
void Move();

void Draw();

CShip* my_ship;

CKeyboard* keyboard;
CMouse* mouse;

al_fixed xpos,ypos,xvel,yvel;
al_fixed angle_rad,angle_deg;
al_fixed speed_acc,speed_current;
};

CPlayer::CPlayer(CKeyboard* k,CMouse* m){
keyboard = k;
mouse = m;

my_ship = new CShip();

angle_rad = al_ftofix(0.0);
angle_deg = al_ftofix(0.0);

speed_acc = al_ftofix(0.5);
speed_current = al_itofix(0);

xpos = al_itofix(0);
ypos = al_itofix(0);

xvel = al_itofix(0);
yvel = al_itofix(0);
}

void CPlayer::Update(){
Move();
}

void CPlayer::Move(){
if(keyboard->key_flag[KEY_NAME_LEFT]){angle_deg--;}
if(keyboard->key_flag[KEY_NAME_RIGHT]){angle_deg++;}

if(keyboard->key_flag[KEY_NAME_UP]){speed_current =1;}
if(keyboard->key_flag[KEY_NAME_DOWN]){speed_current -= speed_acc;}

if(angle_deg < 0)
angle_deg += 360;
else if(angle_deg > 360)
angle_deg -= 360;

angle_rad = (angle_deg * PI) / 180;

xvel = al_fixmul(speed_current, al_fixcos(angle_rad));
yvel = al_fixmul(speed_current, al_fixsin(angle_rad));

xpos+=xvel;
ypos+=yvel;
}

void CPlayer::Draw(){
al_draw_rotated_bitmap(my_ship->my_image,64,64,SCREEN_WIDTH/2,SCREEN_HEIGHT/2,(angle_rad),NULL);
al_draw_textf(myfont,al_map_rgb(255,255,255),10,100,NULL,"ANGLE RADIANS : %f",angle_rad);
al_draw_textf(myfont,al_map_rgb(255,255,255),10,144,NULL,"ANGLE DEGREES : %f",angle_deg);

al_draw_textf(myfont,al_map_rgb(255,255,255),10,188,NULL,"SPEED : %f",al_fixtof(speed_current));
al_draw_textf(myfont,al_map_rgb(255,255,255),10,222,NULL,"X POS : %f",al_fixtof(xpos));
al_draw_textf(myfont,al_map_rgb(255,255,255),10,266,NULL,"Y POS : %f",al_fixtof(ypos));
}
</code>

Thanks

Edgar Reynaldo
Member #8,592
May 2007
avatar

There is no reason to use the 'fixed' class anymore. Just use regular floats or doubles, don't mess around with converting back and forth between ftofix.

As a rule, you can always regenerate your speed and heading from your rotation value.

You can use transforms or just regular sin and cos and rotation matrices. Generally I keep a speed (magnitude of velocity) and angle in radians, since that's what the C library works with.

Here's a treat from old days about working with angles :

angles, how I hate them

And here's sin and cos, a programmer's pal, except I think they give you bad advice about using fixed numbers.

Neil Roy
Member #2,229
April 2002
avatar

I highly recommend reading the following series of blog posts which cover things like rotations and the like using vectors which is the best way to represent locations and to do rotations etc. This is probably one of the best posts on the subject I have seen.

http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

dakatt
Member #10,695
February 2009

I'll check that blog out later today Neil, it looks interesting and I don't know much about vectors but it looks user friendly. You were right Edgar, I replaced all the fixeds and it works as it should. Also the code I posted wasn't right since I was playing around with some variables and pasted it after. Here's the working code for anyone interested

<code ="1">

class CPlayer{
public:
CPlayer(CKeyboard*,CMouse*);
~CPlayer(){}

void Update();
void Move();

void Draw();

CShip* my_ship;

CKeyboard* keyboard;
CMouse* mouse;

float angle_deg,angle_rad;
float xpos,ypos,speed,xvel,yvel;
};

CPlayer::CPlayer(CKeyboard* k,CMouse* m){
keyboard = k;
mouse = m;

my_ship = new CShip();

xpos = 0;
ypos = 0;
speed = 0;

angle_deg = 0.0;
angle_rad = 0.0;

}

void CPlayer::Update(){
Move();
}

void CPlayer::Move(){
if(keyboard->key_flag[KEY_NAME_LEFT]){angle_deg--;}
if(keyboard->key_flag[KEY_NAME_RIGHT]){angle_deg++;}

if(angle_deg >= 360)angle_deg-=360;
if(angle_deg < 0) angle_deg+=360;

angle_rad = (angle_deg * PI) / 180;

if(keyboard->key_flag[KEY_NAME_UP]){speed = 1;}
else if(keyboard->key_flag[KEY_NAME_DOWN]){speed = -1;}
else speed = 0;

xvel = speed * cos(angle_rad);
yvel = speed * sin(angle_rad);

xpos += xvel;
ypos += yvel;
}

</code>

Thanks guys

Edgar Reynaldo
Member #8,592
May 2007
avatar

LennyLen
Member #5,313
December 2004
avatar

code goes here... tags are helpful

He used code tags, but he has '="1"' instead of 'start="1"'.

Edgar Reynaldo
Member #8,592
May 2007
avatar

dakatt
Member #10,695
February 2009

Damn it, I tried using the formatting help. Hopefully this is better

Also you can't edit a post?

LennyLen
Member #5,313
December 2004
avatar

dakatt said:

Also you can't edit a post?

Yes click on the edit post button at the top of the post: 611325

edit: ok, that is NOT the image I uploaded.

edit2: the image isn't showing, but it's the correct one now.

Go to: