|
Using Sine And Cosine For Rotation |
Scooter
Member #16,799
January 2018
|
Hi all: |
Dizzy Egg
Member #10,824
March 2009
|
Hello Scooter. You are looping 4 times when the timer changes, and clearing/drawing 4 times. Why did you need to loop 4 times? Also, radians work for al_rotate_image but you don't need them if you just want your square to rotate around the center. Try my attached code, should help you get started....
---------------------------------------------------- |
Scooter
Member #16,799
January 2018
|
Hi Dizzy: Here is what I have now: box_x[0] -= 640; redraw = true; |
Dizzy Egg
Member #10,824
March 2009
|
Now I see why you were using 4 co-orinates, you wanted to draw a box with the 4 x/y points. You could do that using al_draw_prim with a texture, but personally I would just use al_draw_rotated_bitmap. If you really want to rotate around the center, but don't want to use al_draw_rotated_bitmap, then I would just use a transform. I've attached an example for you. If you want to use the 4 x/y co-oridinates, let me know and I'll do a demo for you using al_draw_prim. EDIT: I've attached another example, using vertices, which is closer to what you originally wanted. This method: void rotate_vertices() { float angleR = angle * PI / 180.0; for (int i = 0; i < 4; i++) { box_x[i] = cos(angleR) * (original_x[i] - center_x) - sin(angleR) * (original_y[i] - center_y) + center_x; box_y[i] = sin(angleR) * (original_x[i] - center_x) + cos(angleR) * (original_y[i] - center_y) + center_y; } } will do what you were trying. Notice before drawing that you have to set the image as target and transform it, otherwise you get a spinning square with a non-spinning texture! EDIT2: For some reason I can't attach the second version, so here is the full code, using the 4 points: 1
2
3#include <allegro5/allegro.h>
4#include <allegro5/allegro_primitives.h>
5#include <allegro5/allegro_image.h>
6#include <stdio.h>
7#include <math.h>
8#include <stdbool.h>
9
10
11bool rotate = true;
12float center_x = 640;
13float center_y = 360;
14float PI = 3.1415929;
15float box_x[4];
16float box_y[4];
17float original_x[4];
18float original_y[4];
19float old_x, old_y = 0;
20float new_x, new_y = 0;
21float image_width, image_height;
22float image_width_half, image_height_half;
23
24float angleX = 0;
25float angle = 10.0;
26int indexx = 0;
27int i;
28int radius = 80;
29
30double update_angle();
31float get_vertices();
32void rotate_vertices();
33
34int main()
35 {
36 ALLEGRO_DISPLAY *display = NULL;
37 ALLEGRO_BITMAP *image = NULL;
38 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
39 ALLEGRO_TIMER *timer = NULL;
40
41 int screen_height = 720;
42 int screen_width = 1280;
43 int image_height;
44 int image_width;
45
46 if(!al_init())
47 {
48 fprintf(stderr,"Couldn't initialize allegro!\n");
49 return -1;
50 }
51
52 if(!al_install_mouse())
53 {
54 fprintf(stderr, "failed to initialize the mouse!\n");
55 return -1;
56 }
57
58 if(!al_init_primitives_addon())
59 {
60 fprintf(stderr,"Couldn't initialize primitives addon!\n");
61 return -1;
62 }
63
64
65 display=al_create_display(screen_width, screen_height);
66
67 if(!display)
68 {
69 fprintf(stderr,"Couldn't create allegro display!\n");
70 return -1;
71 }
72
73 if(!al_init_image_addon())
74 {
75 fprintf(stderr,"Couldn't display image!\n");
76 return -1;
77 }
78
79 al_install_keyboard();
80 event_queue = al_create_event_queue();
81 timer = al_create_timer(1.0 / 60);
82 al_register_event_source(event_queue, al_get_display_event_source(display));
83 al_register_event_source(event_queue, al_get_timer_event_source(timer));
84 al_register_event_source(event_queue, al_get_mouse_event_source());
85 al_register_event_source(event_queue, al_get_keyboard_event_source());
86 al_clear_to_color(al_map_rgb(0,0,0));
87
88 image = al_load_bitmap("checker.jpg");
89
90 if(!image)
91 {
92 fprintf(stderr,"Couldn't display image!\n");
93 return -1;
94 }
95
96 image_height = al_get_bitmap_height(image);
97 image_width = al_get_bitmap_width(image);
98 image_height_half = image_height / 2.0;
99 image_width_half = image_width / 2.0;
100
101 al_start_timer(timer);
102
103 int done = false;
104 bool redraw = false;
105 get_vertices();
106
107 const ALLEGRO_TRANSFORM* original_t = al_get_current_transform();
108 ALLEGRO_VERTEX* vertices = NULL;
109
110 while(!done)
111 {
112 ALLEGRO_EVENT ev;
113 al_wait_for_event(event_queue, &ev);
114
115 if (ev.type == ALLEGRO_EVENT_TIMER && al_event_queue_is_empty(event_queue))
116 {
117 update_angle();
118 rotate_vertices();
119
120 ALLEGRO_VERTEX v[] = {
121 {.x = box_x[0], .y = box_y[0], .z = 0, .color = al_map_rgb_f(1, 1, 1), .u = -128, .v = -128},
122 {.x = box_x[1], .y = box_y[1], .z = 0, .color = al_map_rgb_f(1, 1, 1), .u = -128, .v = 128},
123 {.x = box_x[2], .y = box_y[2], .z = 0, .color = al_map_rgb_f(1, 1, 1), .u = 128, .v = 128},
124 {.x = box_x[3], .y = box_y[3], .z = 0, .color = al_map_rgb_f(1, 1, 1), .u = -128, .v = 128}};
125
126 vertices = v;
127
128 redraw = true;
129 }
130
131
132 if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
133 {
134 rotate = false;
135 done = true;
136 break;
137 }
138
139 if (redraw)
140 {
141 al_clear_to_color(al_map_rgb(0, 0, 0));
142
143 al_set_target_bitmap(image);
144 ALLEGRO_TRANSFORM t;
145 al_identity_transform(&t);
146 al_rotate_transform(&t, angle * PI / 180.0);
147
148 al_set_target_backbuffer(display);
149
150 al_draw_prim(vertices, NULL, image, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN);
151
152 al_flip_display();
153
154 redraw = false;
155 }
156 }
157
158 al_destroy_display(display);
159 al_destroy_bitmap(image);
160 al_destroy_timer(timer);
161 return 0;
162 }
163
164double update_angle()
165 {
166 angle += 0.5;
167 if(angle >= 360) angle = 0.0;
168 return(angle);
169 }
170
171float get_vertices()
172 {
173 original_x[0] = center_x - 128;
174 original_x[1] = center_x - 128;
175 original_x[2] = center_x + 128;;
176 original_x[3] = center_x + 128;;
177
178 original_y[0] = center_y - 128;;
179 original_y[1] = center_y + 128;;
180 original_y[2] = center_y + 128;;
181 original_y[3] = center_y - 128;;
182 }
183
184void rotate_vertices()
185{
186 float angleR = angle * PI / 180.0;
187
188 for (int i = 0; i < 4; i++)
189 {
190 box_x[i] = cos(angleR) * (original_x[i] - center_x) - sin(angleR) * (original_y[i] - center_y) + center_x;
191 box_y[i] = sin(angleR) * (original_x[i] - center_x) + cos(angleR) * (original_y[i] - center_y) + center_y;
192 }
193}
---------------------------------------------------- |
Scooter
Member #16,799
January 2018
|
Hi Dizzy: new_x = (box_x[0] * cos(angle)) - (box_y[0] * sin(angle)); I wrote a separate program to determine that this will not work Thanks for your time!!!! |
DanielH
Member #934
January 2001
|
Let's say you have a rectangle with 4 points. 1. pick a point of rotation cx, cy 2. center it to your point of rotation by subtracting cx, cy from px, py repeat steps 2 to 4 for each point in your rectangle Actually that what Dizzy put here void rotate_vertices() { float angleR = angle * PI / 180.0; for (int i = 0; i < 4; i++) { box_x[i] = cos(angleR) * (original_x[i] - center_x) - sin(angleR) * (original_y[i] - center_y) + center_x; box_y[i] = sin(angleR) * (original_x[i] - center_x) + cos(angleR) * (original_y[i] - center_y) + center_y; } }
|
Dizzy Egg
Member #10,824
March 2009
|
Scooter, I'm not really sure what you're asking for. You already had a rotating image in the centre when I helped with this post: I don't know why you don't want to use al_draw_rotated_bitmap. If you want to use 4 points like you originally tried, I posted that above in Edit2. If you use al_draw_prim you have to transform the texture or it will be a spinning square with a non-spinning texture. At this point I don't know why you don't just use al_draw_rotated_bitmap, like you did in your shoot_a_ball question?? You can't rotate an image using al_draw_bitmap, because it just draws a bitmap at x/y? Again, I'm not sure what you're trying to achieve....
---------------------------------------------------- |
Scooter
Member #16,799
January 2018
|
Hi Dizzy: I am going to try a very simple program to see if I can get a Stay tuned, it"s going to be a bumpy ride! |
Dizzy Egg
Member #10,824
March 2009
|
You need to get a copy of the transform before you enter your game loop. Then after making a new transform and drawing (rotating), set back the original before doing any more drawing.
---------------------------------------------------- |
DanielH
Member #934
January 2001
|
Look at the code for rotating a bitmap. 1static void _draw_tinted_rotated_scaled_bitmap_region(ALLEGRO_BITMAP *bitmap,
2 ALLEGRO_COLOR tint, float cx, float cy, float angle,
3 float xscale, float yscale,
4 float sx, float sy, float sw, float sh, float dx, float dy,
5 int flags)
6{
7 ALLEGRO_TRANSFORM backup;
8 ALLEGRO_TRANSFORM t;
9 ALLEGRO_BITMAP *parent = bitmap;
10 float const orig_sw = sw;
11 float const orig_sh = sh;
12 ASSERT(bitmap);
13
14 al_copy_transform(&backup, al_get_current_transform());
15 al_identity_transform(&t);
16
17 if (bitmap->parent) {
18 parent = bitmap->parent;
19 sx += bitmap->xofs;
20 sy += bitmap->yofs;
21 }
22
23 if (sx < 0) {
24 sw += sx;
25 al_translate_transform(&t, -sx, 0);
26 sx = 0;
27 }
28 if (sy < 0) {
29 sh += sy;
30 al_translate_transform(&t, 0, -sy);
31 sy = 0;
32 }
33 if (sx + sw > parent->w)
34 sw = parent->w - sx;
35 if (sy + sh > parent->h)
36 sh = parent->h - sy;
37
38 if (flags & ALLEGRO_FLIP_HORIZONTAL) {
39 al_scale_transform(&t, -1, 1);
40 al_translate_transform(&t, orig_sw, 0);
41 flags &= ~ALLEGRO_FLIP_HORIZONTAL;
42 }
43
44 if (flags & ALLEGRO_FLIP_VERTICAL) {
45 al_scale_transform(&t, 1, -1);
46 al_translate_transform(&t, 0, orig_sh);
47 flags &= ~ALLEGRO_FLIP_VERTICAL;
48 }
49
50 al_translate_transform(&t, -cx, -cy);
51 al_scale_transform(&t, xscale, yscale);
52 al_rotate_transform(&t, angle);
53 al_translate_transform(&t, dx, dy);
54 al_compose_transform(&t, &backup);
55
56 al_use_transform(&t);
57 _bitmap_drawer(parent, tint, sx, sy, sw, sh, flags);
58 al_use_transform(&backup);
59}
It saves current transform. Processes all needed data for the bitmap transform. draws the bitmap, then restores the backup to the current transform. |
|