Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Rotational Transformation

This thread is locked; no one can reply to it. rss feed Print
Rotational Transformation
ngiacomelli
Member #5,114
October 2004

I have a triangle that I wish to rotate to represent the player. I want the tip of the triangle (+) to represent their current angle and the direction in which they would travel (if they were to apply thrust).

      +
     / \
    /   \
   /_____\

The movement code isn't my problem here, though. It's actually drawing the triangle. I want to do this using primitives (so no drawing to a bitmap, then rotating).

I came up with some messy code here as a quick test:

    float t_x, t_y, t_x2, t_y2, t_x3, t_y3;
    
    t_x = 100 * fixtof(fcos(angle)) - 100 * fixtof(fsin(angle));
    t_y = 100 * fixtof(fcos(angle)) + 100 * fixtof(fsin(angle));   
    t_x2 = 200 * fixtof(fcos(angle)) - 200 * fixtof(fsin(angle));
    t_y2 = 200 * fixtof(fcos(angle)) + 200 * fixtof(fsin(angle));   
    t_x3 = 0 * fixtof(fcos(angle)) - 200 * fixtof(fsin(angle));
    t_y3 = 200 * fixtof(fcos(angle)) + 0 * fixtof(fsin(angle));

Which works to slowly rotate the triangle when the angle is adjusted. But I really need the pivot point to be in the triangles centre (I should think). So how do you do this effectively?

Pavel Hilser
Member #5,788
April 2005
avatar

I did rotation around a point, if this is what you want, i did it this way

 x ------ 1
  \
   \
    \
     \
      2

rotating point 1 to 2 - adding 45degrees, rotating around x

get x<->1 lengt
get x<->1 angle
get new angle (angle+45)
get rotated position (2) - from x rotate to new angle and use the current length

  //get the length (to point 0,0)
  delka=sqrt(((f*5)*(f*5))+((g*5)*(g*5)));
  
  //get the angle
  curr_angle = (atan2(g*5, f*5)*180)/M_PI;
 
  //new angle  curr_angle+=angle;
  
  //new position
  mymodel[f+5][g+5].square_x = delka * cos((float)(M_PI*((float)curr_angle))/180);
  mymodel[f+5][g+5].square_y = (delka * sin((float)(M_PI*((float)curr_angle))/180))/2;

(it's taken from my new project, where points are rotated around zero)

anyway, if you have fixed triangle sides, and its always triangle, you can use the pivot as a center of a circle and the two poinst could be easi calculated with the last point (youw kno both angles and both length (cause its a triangle))

_____________________________________
Mein Cannon - see my new 2d game

Ceagon Xylas
Member #5,495
February 2005
avatar

Angles, rotations, and circles sure make for some 'leet' looking code.
What are the first 2 arrays used for in mymodel[][]?

GullRaDriel
Member #3,861
September 2003
avatar

it's taken from his project, so you can imagine that:

  //get the length (to point 0,0)
  delka=sqrt(((f*5)*(f*5))+((g*5)*(g*5)));
  
  //get the angle
  curr_angle = (atan2(g*5, f*5)*180)/M_PI;
 
  //new angle  
   curr_angle+=angle;
  
  //new position
  square_x = delka * cos((float)(M_PI*((float)curr_angle))/180);
  square_y = (delka * sin((float)(M_PI*((float)curr_angle))/180))/2;

is what you need.

EDIT:
where square_x & y are the new position a point rotated around zero.
you must adapt this for your use.

void rotate_around( int cx , int cy , int *X , int *Y , float angle ){

int tx,
    ty;

/* translation to make cx,cy the center of our rotation */
tx = *X - cx;
ty = *Y - cy;

*X = cx +  tx * cos(angle) + ty * sin(angle);
*Y = cy -  tx * sin(angle) + ty * cos(angle);

};

I'll test this and update my post to make it doing the trick.

LAST EDIT:

WORKING EXAMPLE:

1#include <allegro.h>
2#include <winalleg.h>
3 
4#include <math.h>
5 
6void rotate_around( int cx , int cy , float *X , float *Y , float angle );
7 
8 
9float X=150 , Y = 150 ;
10 
11 
12int main( int argc , char *argv[] ){
13 
14allegro_init();
15 
16install_keyboard();
17install_timer();
18 
19set_color_depth( 32 );
20 
21set_gfx_mode( GFX_AUTODETECT_WINDOWED , 640 , 480 , 0 , 0 );
22 
23clear( screen );
24 
25do{
26 
27rotate_around( 320 , 200 , &X , &Y , M_PI/180 );
28 
29putpixel( screen , X , Y , makecol( 255 , 255 , 255 ));
30 
31rest(50);
32 
33 
34}while (!key[KEY_ESC]);
35 
36allegro_exit();
37 
38}END_OF_MAIN();
39 
40 
41/*!\fn void rotate_around( int cx , int cy , float *X , float *Y , float angle )
42 *
43 *\brief rotate a point around center cx,cy
44 *
45 *\param cx the X center
46 *\param cy the Y center
47 *\param X the X coordinate of the point to move
48 *\param Y the Y coordinate of the point to move
49 *\param angle the amount of radian of the rotation (1 degree = PI/180 rad)
50 *
51 */
52 
53void rotate_around( int cx , int cy , float *X , float *Y , float angle ){
54 
55float tx,
56 ty;
57 
58/* translation to make cx,cy the center of our rotation */
59tx = *X - cx;
60ty = *Y - cy;
61 
62*X = cx + tx * cos(angle) + ty * sin(angle);
63*Y = cy - tx * sin(angle) + ty * cos(angle);
64 
65};

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Paul Pridham
Member #250
April 2000
avatar

Turtle is a nice and simple abstraction for Asteroids-like vector drawing with relative movement and rotations.

gillius
Member #119
April 2000

If you are wanting to draw an equilateral triangle with the pivot point in its center then it is easy as the three points are at theta, theta + 120deg, and theta + 240deg, where theta is the direction you are pointing. Then given theta you do sin and cos and multiply by one half of the height of the triangle (since the point is in the center, you want use use "radius" of the triangle).

Gillius
Gillius's Programming -- https://gillius.org/

GullRaDriel
Member #3,861
September 2003
avatar

With all this code posted and all those ideas , can you give your mean of the whole, Nial ?

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Go to: