gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Pinball bumper help

#46297 - LOst? - Wed Jun 22, 2005 8:39 pm

I'm doing a pinball bumper. You know those things that shoot the pinball ball away (accelerating it of course to make it harder to control) and give you some score.

I have everything set for it. It detects the ball when it is inside the bumper's radius area.

My GBA game uses a Sine LUT with 256 as the maximum angle.
It's really simple. I just thake the angle of the ball and the bumper and and run it through the Sine LUT, multiply it for a speed effect.

But the main problem is getting the angle between the ball and the bumper.

I need help understanding how to make up a LUT angle table. Maybe an example formula to puch me into the right direction would be great.

The only thing I can think of is using ArcTan2. But I think this can be done with only ArcTan, or maybe just Tan?

What's the difference between ActTan2 and ArcTan?
Can you make a macro that converts ArcTan2 into ArcTan?

My main goal is to send in bumper_x - ball_x, and bumper_y - ball_y as arguments, and the return value will be the angle between 0 and 255.

How do I make a formula that can make up a LUT table with these angles? What will I use when I make up the LUT? ArcTan2, ArcTan, or Tan? And how do I convert the LUT so it uses the angles 0 to 255 instead of 0 to 360 or 0 to 2pi?


Thank you if you can help me, I would appreciate it :)

#46311 - MrD - Wed Jun 22, 2005 11:26 pm

Quote:
What's the difference between ActTan2 and ArcTan?
Can you make a macro that converts ArcTan2 into ArcTan?


ArcTan2 is an inverse tan function which takes an X distance and a Y distance between 1 and -1 and returns the angle counterclockwise from horizontally right. (This probably makes more sense!)

ArcTan returns the same angle, except this time the parameter is Y divided by X. (Or in other words, the gradient of the line. ArcTan returns the angle counterclockwise from horizontal to this line)

Example: ArcTan 1 (Gradient of 1 is a 'diagonal' line) is 45 degrees. (Or pi/4 radians)

Quote:
My main goal is to send in bumper_x - ball_x, and bumper_y - ball_y as arguments, and the return value will be the angle between 0 and 255. But the main problem is getting the angle between the ball and the bumper.


I'm assuming you mean a circular bumper... so it looks like you need an inverse tan LUT... (To take the angle between bumper and ball to be able to use sin and cos later) but an inverse tan LUT would require the y value divided by the x value, so I'm sure how fast querying an inverse tan LUT would be. The function you could use is BIOS SWI 10 (0Ah) - ArcTan2.

Here's another note against an inverse tan LUT: Taking the tan of an angle results the gradient, a value between -infinity and +infinity. Therefore the inverse tan LUT would need to cover the same range. I dunno how you'd do that, I'm probably wrong anyway, somebody prove me wrong!

Quote:
The only thing I can think of is using ArcTan2. But I think this can be done with only ArcTan, or maybe just Tan?


If you're doing a bumper which deflects the ball away from the bumper at exactly the same angle as it's approached from, consider solutions not involving angles, but instead simply waiting for the ball to come within the bumpers radius and (if your simulation's time-step is small enough) try simply adding a multiple of the X and Y distances away from the bumper to the speed.

(It's a late night explanation... I apologize if this is incorrect, confusing and doesn't make any sense to anyone... ._.)
_________________
Not active on this forum. For Lemmings DS help see its website.

#46314 - Miked0801 - Wed Jun 22, 2005 11:52 pm

You can do it without angles if you wish as well - and it may be faster yet.

At collision, create a vector from the center of the ball to the center of the bumper. This is your base acceleration vector. Turn it into a unit if you want, or leave it alone and have it push harder as the radius between them decrease (or sq of radius for true gravity) If you want an anti-gravity sort of effect, add this to the ball each tic. For a bumber that hits and pushes, you need to do a reflection and an acceleration.

The same accel vector is also the normal vector for a reflection, though I can't recall the equation for actual reflection at the moment.

Just another idea.

#46373 - LOst? - Thu Jun 23, 2005 8:16 pm

MrD wrote:
ArcTan returns the same angle, except this time the parameter is Y divided by X. (Or in other words, the gradient of the line. ArcTan returns the angle counterclockwise from horizontal to this line)


Yes, this is the code I have been wondering about all the time. Look here, the table just have to be ArcTan:
Code:

unsigned char return_angle (short x, short y)
{
   short tmp_x = x;
   short tmp_y = y;
   unsigned long divu = 0;
   unsigned short angle = 0;

   if ((tmp_y & tmp_x) == 0)
   {
      return 0x40;
   }

   if (tmp_x < 0)
      tmp_x = -tmp_x;

   if (tmp_y < 0)
      tmp_y = -tmp_y;



   if (tmp_x < tmp_y)
   {
      divu = (tmp_y << 8);
      divu /= (unsigned long) tmp_x;
      
      angle = (unsigned short) ANGLE_TABLE [divu];
   }
   else
   {
      divu = (tmp_x << 8);
      divu /= (unsigned long) tmp_y;
      
      angle = 0x40;
      angle -= (unsigned short) ANGLE_TABLE [divu];
   }


   if (x < 0)
   {
      angle = -angle;
      angle += 0x80;
   }

   if (y < 0)
   {
      angle = -angle;
      angle += 0x100;
   }

   return (unsigned char) angle;
}

unsigned char ANGLE_TABLE [258] =
{
   0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05,
   0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0A, 0x0A, 0x0A,
   0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
   0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
   0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11,
   0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13,
   0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15,
   0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17,
   0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
   0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
   0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C,
   0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
   0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F,
   0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x00
};


The big question is, how do I make that ANGLE_TABLE up from a formula? It is ArcTan right?
Anyone really good at math that can figure out a formula for making up this LUT table? (doesn't need to be completely exact because this was handwritten and that's why I don't know the formula. Someone else did the work a long time ago).
I will probably use ArcTan2 with GBA, but I really want to know how to figure out this LUT table and how to make it in realtime. Please anyone?

#46438 - LOst? - Fri Jun 24, 2005 7:28 pm

Miked0801 wrote:
You can do it without angles if you wish as well - and it may be faster yet.


Yea I know that, but the effect is will be very bad. If you have a playable ball that you can move with the direction keys, you can't predict where you will land because the collision reaction will not throw you in exact angle.

I appriciate your help though. I will use this collision methods for breakable bumpers.

But my method I poster above is the one I want to use. I know the result of it. I just want to know the math for making up the table.

#46444 - Miked0801 - Fri Jun 24, 2005 10:18 pm

Huh? You hit a round bumber that smacks you, it pushes you on the tangent of the collide spot which is the vector connecting the 2 centers. The velocity itself is the reflection around that collision. How is that now accurate? In truth, vectors will be more accurate as you don't need worry about sin/cos atan2 round off issues. Or am I missing something?

#46450 - merodia - Sat Jun 25, 2005 1:11 am

wouldn't it perhaps be alot easier and use good old anayltical geometry and calculus and determine a slope of the ball. You then increment it by a x distance and y distance, which is pre-determined by the slope.
This way the only thing you have to do for the ball to bounce the other way is invert the x (multiply by -1) or the invert the y.

#46587 - Miked0801 - Mon Jun 27, 2005 6:49 pm

Quote:

This way the only thing you have to do for the ball to bounce the other way is invert the x (multiply by -1) or the invert the y.


No. This only works if the surface you care colliding with is axis bound. For any other collision, you have to do a reflection calculation for it to work correctly. The negate the correct term method is derived from the reflection code when the surface tangent unit vector is aligned - that is equal it either (1,0), (0,1), (-1,0), or (0,-1).

Proof: A ball moving with a velocity of (10, 0) (moving due right) hits a wall that is at an angle of 45 degrees with respect the the moving velocity. Physics state that for a true reflection, angle of insidence equals angle of reflection along the wall normal (the forward slashes below.)

Code:

   \
    \
-----\
    /|\
   / | \


Here the final velocity is (0, 10) which cannot be derived from jsut negating velocity terms.

The above problem can be solved with geometry/trig (sin/cos/angle work) or linear algerbra (unit vector with a dot-product.) Computers processors just have an easier time with vectors - no look-ups, no round off, just multiplies, adds, and subtracts (with a divide/sqrt for unit if you don't have it :P)

#47615 - batblaster - Mon Jul 11, 2005 12:44 pm

Hi Miked0801,

is possible for you to make an example on how to use verctor reflection ??/ i love the pinball game but i never understand how i can try to write 1 for the problem of the rebound... If you have time and can help me i'm happy...

Thanks a lot...

Cu...
_________________
Batblaster / 7 Raven Studios Co. Ltd
------------------------------------------

#47663 - Miked0801 - Tue Jul 12, 2005 1:49 am

I'm in the middle of an Alpha Beta Final march this month at work. As soon as that's complete, I'll go figure out the formula again. Give me a couple weeks. Right now, I scan the boards once a day and answer easier problems when possible :)

#47730 - Mucca - Tue Jul 12, 2005 9:03 pm

Crunch time eh?

Not for me :) I just had my first ever game lot-check approved today. Weeeeee :-) Only three months to roll out the next one though :(

#47732 - Miked0801 - Tue Jul 12, 2005 10:04 pm

Crunching away :)