Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Angular timer and how to convert to a rect using an angular algorithm...

This thread is locked; no one can reply to it. rss feed Print
Angular timer and how to convert to a rect using an angular algorithm...
Don Freeman
Member #5,110
October 2004
avatar

Hello again all!

Does anyone have any ideas / suggestions on how to write this to do the
'sweep' but with a rect instead of a circle? I still want to be able to do
the circular sweep function, but extend to the entire rect. Below is the
circle based 'sweep' program. Also, any suggestions on how to simplify the
math would be great. Hope someone could use this code some how too...
Command & Conquer anyone? ;D

1/////////////////////////////////////////////////////////////////////////////
2// <Main.cpp>
3// Donald C Freeman June 29th, 2007
4// Simple 'sweep' program to simulate functionality of angular timer.
5/////////////////////////////////////////////////////////////////////////////
6#define ALLEGRO_USE_CONSOLE
7#include <allegro.h>
8#include <math.h>
9/////////////////////////////////////////////////////////////////////////////
10int main( void )
11{
12 /////////////////////////////////////////////////////////////////////////
13 allegro_init();
14 set_color_depth(32);
15 set_gfx_mode(GFX_AUTODETECT_WINDOWED,800,600,0,0);
16 set_color_conversion(COLORCONV_TOTAL);
17 install_timer();
18 install_keyboard();
19 install_mouse();
20 /////////////////////////////////////////////////////////////////////////
21 BITMAP *pBmp = create_bitmap(SCREEN_W,SCREEN_H);
22 clear_bitmap(pBmp);
23 bool bQuit = false;
24 clear_keybuf();
25 /////////////////////////////////////////////////////////////////////////
26 //pi = 3.1415926535897932384626433832795
27 // 1 degree = pi/180 radians. (0.017453292519943295769236907684886)
28 // 1 radian = 180/pi degrees. (57.295779513082320876798154814105)
29 float PI = 3.141592654f;
30 float x = SCREEN_W / 2;
31 float y = SCREEN_H / 2;
32 float angle = 0.0f;
33 int nTime = 0;
34 int nTimeEnd = 100;
35 float angleStep = 0.0f;
36 int color1 = makecol(200,128,128);
37 int color2 = makecol(128,200,128);
38 int radius = 50;
39 float x2 = 0;
40 float y2 = 0;
41 bool done = false;
42 float nTimeSliced = (nTime+1 / nTimeEnd+1)-1;
43 /////////////////////////////////////////////////////////////////////////
44 while ( !bQuit )
45 {
46 /////////////////////////////////////////////////////////////////////
47 if ( keypressed() )
48 {
49 if ( key[KEY_ESC] )
50 bQuit = true;
51 if ( key[KEY_UP] )
52 {
53 if ( nTimeEnd > 0 )
54 nTimeEnd-=10;
55 done = false;
56 nTime = 0;
57 angle = 0.0f;
58 angleStep = 0.0f;
59 }
60 if ( key[KEY_DOWN] )
61 {
62 done = false;
63 nTimeEnd+=10;
64 nTime = 0;
65 angle = 0.0f;
66 angleStep = 0.0f;
67 }
68 if ( key[KEY_SPACE] )
69 {
70 done = false;
71 nTime = 0;
72 angle = 0.0f;
73 angleStep = 0.0f;
74 clear_keybuf();
75 }
76 clear_keybuf();
77 }
78 /////////////////////////////////////////////////////////////////////
79 clear_bitmap(pBmp);
80 /////////////////////////////////////////////////////////////////////
81 // [Drawing code/Processing]
82 if ( !done )
83 {
84 nTime++;
85 }
86 if ( nTime == nTimeEnd )
87 {
88 done = true;
89 angle = 0.0f;
90 angleStep = 0.0f;
91 }
92 if ( nTime < nTimeEnd && !done )
93 {
94 nTimeSliced = ((float)((nTimeEnd)*0.01745329251f));
95 angleStep = (PI/nTimeSliced)*(0.01745329251f*2);
96 }
97 if ( nTimeEnd < nTime )
98 {
99 done = true;
100 nTime = nTimeEnd;
101 }
102 angle+=angleStep;
103 x2 = sin(angle)*radius;
104 y2 = cos(angle)*radius;
105 circle(pBmp,x,y,radius,color1);
106 line(pBmp,x,y,x+x2,y-y2,color2);
107 textprintf(pBmp,font,0,0,color2,"Donald C Freeman June 29th, 2007");
108 textprintf(pBmp,font,0,8,color2,"Simple 'sweep' program to simulate functionality of angular timer.");
109 textprintf(pBmp,font,0,16,makecol(100,200,255),"[Spacebar] <Reset Timer>");
110 textprintf(pBmp,font,0,24,makecol(100,200,255),"[Up] <Shorten Timer>");
111 textprintf(pBmp,font,0,32,makecol(100,200,255),"[Down] <Lengthen Timer>");
112 textprintf(pBmp,font,0, 40,color1,"angle: %f, angleStep: %f, time: %i, timeEnd: %i",
113 angle,angleStep,nTime,nTimeEnd);
114 /////////////////////////////////////////////////////////////////////
115 acquire_bitmap(screen);
116 blit(pBmp,screen,0,0,0,0,pBmp->w,pBmp->h);
117 release_bitmap(screen);
118 /////////////////////////////////////////////////////////////////////
119 }
120 /////////////////////////////////////////////////////////////////////////
121 destroy_bitmap(pBmp);
122 clear_keybuf();
123 /////////////////////////////////////////////////////////////////////////
124 return 0;
125 /////////////////////////////////////////////////////////////////////////
126}
127/////////////////////////////////////////////////////////////////////////////

Be nice about the code please, it is only a quick and dirty test...::)
As always, thanks to all of you.;D

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

gnolam
Member #2,030
March 2002
avatar

Quote:

Also, any suggestions on how to simplify the math would be great.

int current_time = 0; // increment this by one in every cycle until done
int end_time = SOME_VALUE;

line(buffer, center_x, center_y, center_x + radius*cos(((double)current_time/end_time)*2.0*M_PI), center_y + radius*sin(((double)current_time/end_time)*2.0*M_PI), color);

Quote:

Does anyone have any ideas / suggestions on how to write this to do the
'sweep' but with a rect instead of a circle?

The easiest way? Just use a sub bitmap.

But before you write another line of code, I suggest you enable compiler warnings. Also, use a non-ancient version of Allegro. And stop inserting manual linebreaks into your posts. :P

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Andrei Ellman
Member #3,434
April 2003

Another way is to use the tan() of the angle to find out how far along each edge you have to draw the line.

The following assumes that the angle of 0 corresponds to a line pointing rightwards and the line rotates anticlockwise as the angle increases.

You will have to divide the rectangle into four quadrants because for each quadrant (note that these quadrants do not correspond to what are usually referred to as quadrants when discussing trigonometric functions), you want to trace round a different edge of the rectangle. To find the angular border to separate the quadrants, work out the inverse tangent of the horizontal distance from the rectangle-centre to the rectangle-edge divided by the vertical distance from the rectangle-centre to the rectangle-edge (this can be done using the atan2()) function. This will give you the boundry angle (B). That is, one quadrant boundry is at B, the other at 2pi-B, one is at pi+B and the last one at pi-B.

If the angle lies in the first quadrant, multiply the horizontal distance from the rectangle-centre to the rectangle-edge by the tan() of the angle to get the Y coordinate on the rectangle's right edge to draw the line to. If in the second quadrant, multiply the vertical distance from the rectangle-centre to the rectangle-edge by tan((pi/2)-angle). For the third quadrant, -horizontal_distance * tan(angle), and for the fourth, -vertical_distance * tan(-(pi/2)-angle). Note that this is unchecked.

AE.

--
Don't let the illegitimates turn you into carbon.

Go to: