Allegro.cc Forums » Programming Questions » [Math] Rotation

Credits go to FrankyR for helping out!
 ngiacomelli Member #5,114 October 2004 In my game the player is divided into three sections. Torso, legs and arms. This is because the game uses an Abuse-style control system. Where you aim with the mouse and the arm rotates accordingly. This works fines.When rendering the arm I use the following code (please exclude hardcoded values!): ``` if( mouse_x >= ( player.x + (player.body[0]->w/2)) ) { pivot_sprite( bmp, weapon_base[player.inv.weapon[player.inv.c_slot].weap_type].sprite, player.x + 6, player.y - 8, 1, 23, float_to_fixed( player.torso_angle ) ); } else { pivot_sprite_v_flip( bmp, weapon_base[player.inv.weapon[player.inv.c_slot].weap_type].sprite, player.x + 15, player.y - 8, 0, 13, float_to_fixed( player.torso_angle ) ); } ``` The problem I have is with my projectile spawning:``` player.x+(cos(player.torso_angle)*5), player.y+(sin(player.torso_angle)*5), ``` The problem is the actual start coordinates. Right now the bullets come from 'inside' of the player, rather than the tip of his/her weapon. In my game each weapon has its own set of hands rendered along with it. Meaning the weapons sprites can be of a variable height and width. So what I really need to know is how can I go about getting the coordinates for the 'tip' of the gun 'nozzle'. So that the bullets appear to spawn out of the weapon?
 ngiacomelli Member #5,114 October 2004 You'll have to excuse my terrible math knowledge. But can you explain the theta value in greater detail?```x' = cos(theta)*x - sin(theta)*y y' = sin(theta)*x + cos(theta)*y ``` As I understand it, I'd take the (x,y) location on the player sprite. The location that the arm actually pivots around. And also the (w,h) of the arm sprite. Then get the rotated values for the arm sprite, and add it to the pivot location... right?
 FrankyR Member #243 April 2000 Oh, sorry, theta is the angle that you want to rotate.My suggestion was to take a simple unit-length (i.e. magnitude of 1) vector and rotate that, multiply it by the length of the arm and add it to the point where the arm is attached. I'll go into more detail:If your player is standing at position (x,y), the shoulder is offset from the player position by (shoulder_offset_x, shoulder_offset_y), and the angle between the x-axis and the arm is theta radians.I take the axis: (1,0) and rotate it by theta radians: rotated_axis_x = cos(theta)*1 - sin(theta)*0rotated_axis_y = sin(theta)*1 + cos(theta)*0this gives me a new vector: (cos(theta), sin(theta)).Now, since this is a unit-length vector I multiply it by arm_length to get an offset value from the point where the arm is attached to the end of the arm.So, now the end of the arm is: ```arm_end_x = x + shoulder_offset_x + cos(theta)*arm_length arm_end_y = y + shoulder_offset_y + sin(theta)*arm_length | | | player position | angle between x-axis and arm offset from position to where arm is attached ```
 ngiacomelli Member #5,114 October 2004 I see! So in practice:``` p_x = player.x + 6 + cos( player.torso_angle )*weapon_base[player.inv.weapon[player.inv.c_slot].weap_type].sprite->w; p_y = player.y - 8 + sin( player.torso_angle )*weapon_base[player.inv.weapon[player.inv.c_slot].weap_type].sprite->w; ``` Works perfectly, thanks for the explanation!