Allegro.cc Forums » Programming Questions » Trig question

 Trig question
 ngiacomelli Member #5,114 October 2004 I have two sets of locations: x, y and t_x, t_y. When something is fired it is spawned at x, y and travels toward t_x, t_y. How do I increment the change to x,y so that eventually the object will reach t_x and t_y?
 Richard Phipps Member #1,632 November 2001 1. add dx and dy variables.2. dist = sqrt(t_x - x * t_x - x + t_y - y * t_y - y);3. dx = (t_x - x) / dist;4. dy - (t_y - y) / dist;
 ngiacomelli Member #5,114 October 2004 I take it I would then add dx and dy to x and y?
 Richard Phipps Member #1,632 November 2001 Yes, for each frame of game logic.
 Arthur Kalliokoski Second in Command February 2005 I believe line 4 "dx - (t_y - y) / dist" should be "dx = (t_y - y) / dist" (typo)And if the object doesn't move one unit per logic cycle you'd have to multiply it by the units moved per cycle. “Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”― Robert A. Heinlein
 Richard Phipps Member #1,632 November 2001 Yep sorry. There was a typo there.
ngiacomelli
Member #5,114
October 2004

I may be missing something here. Is dx and dy gradually increased over a period of time? Because at the moment the values for dx and dy seem to be coming up with 0, 0. EDIT: sqrt deals in double's. Will I have to cast back for blitting, etc?

 1 void render_attacks(BITMAP *bmp) { 2 3 int i=0; 4 5 for(i = 0; i < MAX_ATTACK_S; i++ ) { 6 7 if( gAttacks.state ) { 8 line( bmp, gAttacks.x, gAttacks.y, gAttacks.t_x, gAttacks.t_y, makecol(255,255,255)); 9 } 10 11 } 12 13 } 14 15 void attack_increment(void) { 16 17 int i=0, dist=0; 18 19 for(i = 0; i < MAX_ATTACK_S; i++ ) { 20 21 if( gAttacks.state ) { 22 23 dist = sqrt(gAttacks.t_x - gAttacks.x * gAttacks.t_x - gAttacks.x + gAttacks.t_y - gAttacks.y * gAttacks.t_y - gAttacks.y); 24 gAttacks.x += ((gAttacks.t_x - gAttacks.x) / dist); 25 gAttacks.y += ((gAttacks.t_y - gAttacks.y) / dist); 26 27 } 28 29 } 30 31 }

 Richard Phipps Member #1,632 November 2001 You have dist as an int when it should really be a float. You'll need to use floats for the x and y values of your sprites as well.
 ngiacomelli Member #5,114 October 2004 Quote: You have dist as an int when it should really be a float. Should x, y and t_x, t_y become floats also?
 Richard Phipps Member #1,632 November 2001
ngiacomelli
Member #5,114
October 2004

With float values the code does nothing! dist also seems to be giving out junk values.

 1 2 struct gAttack { 3 4 int state, type; 5 float x, y, t_y, t_x; 6 7 } gAttacks[MAX_ATTACK_S]; 8 9 void render_attacks(BITMAP *bmp) { 10 11 int i=0; 12 13 for(i = 0; i < MAX_ATTACK_S; i++ ) { 14 15 if( gAttacks.state ) { 16 line( bmp, gAttacks.x, gAttacks.y, gAttacks.t_x, gAttacks.t_y, makecol(255,255,255)); 17 } 18 19 } 20 21 } 22 23 void attack_increment(void) { 24 25 int i=0; float dist=0; 26 27 for(i = 0; i < MAX_ATTACK_S; i++ ) { 28 29 if( gAttacks.state ) { 30 31 dist = sqrt(gAttacks.t_x - gAttacks.x * gAttacks.t_x - gAttacks.x + gAttacks.t_y - gAttacks.y * gAttacks.t_y - gAttacks.y); 32 gAttacks.x += ((gAttacks.t_x - gAttacks.x) / dist); 33 gAttacks.y += ((gAttacks.t_y - gAttacks.y) / dist); 34 35 } 36 37 } 38 39 } 40 41 void local_add_attack( int type, float x, float y, float t_x, float t_y ) { 42 43 int i=0; 44 45 for(i = 0; i < MAX_ATTACK_S; i++ ) { 46 47 if( !gAttacks.state ) { 48 gAttacks.state = 1; 49 gAttacks.type = type; 50 gAttacks.x = x; 51 gAttacks.y = y; 52 gAttacks.t_x = t_x; 53 gAttacks.t_y = t_y; 54 55 break; 56 } 57 58 } 59 60 }

 Richard Phipps Member #1,632 November 2001 Not sure why it's not working. Blah, just use some sin/cos/tan: ``` float dx, dy, angle; dx = x - t_x; dy = y - t_y; angle = atan2(dy, dx); dx = cos(angle); dy = sin(angle); gAttacks.x += dx; gAttacks.y += dy; ```
 Frank Drebin Member #2,987 December 2002 i use an angle to the target like this: ```angle=atan2(y_t-y,x_t-x); x+=cos(angle); y+=sin(angle); ```
 gnolam Member #2,030 March 2002 1)Quote: gAttacks.t_x - gAttacks.x * gAttacks.t_x - gAttacks.x + gAttacks.t_y - gAttacks.y * gAttacks.t_y - gAttacks.y Should be:(gAttacks.t_x - gAttacks.x)*(gAttacks.t_x - gAttacks.x) + (gAttacks.t_y - gAttacks.y)*(gAttacks.t_y - gAttacks.y)You know, like the Pythagorean theorem. (Phipps made the original mistake)2) Don't recalculate dx and dy every loop cycle. Compute them once.3) Make sure you avoid dividing with zero (if (dist > 0) ...).4) Don't use the bad sin/cos solutions. -- Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!
 NyanKoneko Member #5,617 March 2005 You could compute the X / Y vectors and normalize them. Then you have a ratio for far on the x and y axis your sprite should move each iteration.Think in terms of triangles...```(x,y)+ | + c a | + |----------(t_x,t_y) -> x vector b | V Y Vector ``` To normalize the x and y vector, divide each by the hypotenuse of the triangle.Example: ``` (t_y - y) --------------- sqrt(a^2 + b^2) ``` Pretty simple huh? Since it's normalized, just multiply the x and y vector by a constant to make it go that speed.For example, if you want to move the object 5 pixels per frame...```object.x = normalized_vector.x * 5; object.y = normalized_vector.y * 5; ``` -----------------Website: Playing With YarnMy Games: Flying Flammie, CorruptionWare, Hero of Light VS. Warriors of Darkness.Other: Collegro, The Seasons
 Indeterminatus Member #737 November 2000 On another note, I don't see you initialize values anywhere. Of course, if you already do that you can ignore me now saying to initialize, especially the int state. _______________________________Indeterminatus. [Atomic Butcher]si tacuisses, philosophus mansisses
 Johan Halmén Member #1,550 September 2001 Then there's do_line()but that function returns each int coordinate of the pixels of a line drawn between the start point and end point. Only trouble is that you get different number of pixels on different directions even if the length is the same. It includes a pointer parameter to a call-back function, which you could set to create an array of all the coordinates you travel through. I once made a class that does something like that, without the callback and array stuff. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.
 Go to: Allegro Development Installation, Setup & Configuration Allegro.cc Comments Off-Topic Ordeals The Depot Game Design & Concepts Programming Questions Recent Threads