views:

439

answers:

5

Just curious. When I bounce a ball off the walls of the stage using the following technique.

if(y > sRef.stageHeight || y < 0)
{
    yDir = yDir * -1;
}
else if ( x > sRef.stageWidth || x < 0)
{
        xDir = xDir * -1;
}


x += xspeed * xDir;
y += yspeed * yDir;

The above seems fine and works well. But If I choose to use angles instead like the following...

if(y > sRef.stageHeight || y < 0)
{
    angle += 45;

}
else if ( x > sRef.stageWidth || x < 0)
{
    //angle = angle * -1;
    angle += 45;

}
vx = Math.cos(angle * Math.PI / 180) * bSpeed;
vy = Math.sin(angle * Math.PI / 180) * bSpeed;
x += vx;
y += vy;

Not only is the ball jumpy and skippy. but after so often it begins to go either in a vertal motion y = 5; x = 0; or a horzontal motion x = 5, y = 0. And stays that way. Why is it that the first method works fine but the other method works terrible. Could it be because the Math.cos and Math.sin returns very large decimals. could someone help me out please, cause I really prefer to use the second method.

Thanks

+1  A: 

it doesn't make sense to add 45 to the angle. That will steer your ball counterclockwise, regardless of which wall it is hitting. why would you prefer to use the second way? the first way makes more sense. you can use angle = Math.atan2(vy,vx) to get the angle from your vx/vy coordinates

Edit You claim you can have easier way of controlling the speed of the ball hitting a moving paddle using the angle. Actually, what really occurs is that when the ball hits the paddle, some part of the paddle's velocity is transferred to the ball, (in reality some of it is lost due to friction or conversion to angular momemtum)

if (hit a paddle) {
   vx = -vx;
   vy += a * paddle_vy; // a is a fudge factor between 0 and 1
}
if (hit a vertical wall)
   vx = -vx;
if (hit a horizontal wall)
   vy = -vy;

There really is no way to simulate this kind of behavior using just an angle.

Jimmy
Not only is the direction sometimes wrong, but 45 is only the correct angle when the ball is approaching at a 67.5 degree angle.
Shmoopty
and even then, only in one direction :) so 1 out of 4 collisions (assuming a straight-line trajectory) would be correct
Jimmy
well I was doing a little trial an error to see what would work. when I tried the second one out. it bounced off the walls like it suppose to but now that I think about it, it could been hitting the wall repeatedly changing its direction until it began to move in the right direction. I would prefer to stir the ball using angles because later I will using a paddle that will stir the ball in different directions based on the speed of the paddle moving on the x axis. I tried the other method but it hard to get it down perfectly.
numerical25
I just feel like I can have more control using angles, if there is no possible way then I can deal with the other method and do a bunch of logic to get rid of all the kinks
numerical25
+1  A: 

For one, incrementing by 45 degrees doesn't represent a reflection off of a surface. Imagine a ball heading nearly straight up, and slightly to the left - angle 70 degrees, say. When it hits the top, you'll add 45 to get 105, which is still nearly straight up, so the ball will continue out of bounds (up), and you'll add 45 again, to get 155, which is still going up, before finally getting around to 200.

You should use -ve the existing angle for a reflection of the "roof" and 180-angle for a reflection off the wall, I think.

BeeOnRope
a 180-angle doesn't really work for anything except bouncing off a 90-degree corner or a straight-on wall collision.
Jimmy
Sure, but from the original "working" example (yDir = yDir * -1;) it was clear to me that the containing shape is an aligned rectangle.If the ball can collide with a wall at arbitrary angle then you'll have to use a calculation relative to the wall angle as well.
BeeOnRope
A: 

From your other thread, your vx,vy are actually the cathetus of the angle you are looking for (vector actually, cause it has a magnitude)...

It's good thinking that you may have better control using angles, but for what you are trying to do you will mostly need to work with the X and Y components of that angle...

I think you have only one problem with your previous approach: You need a better control when the collition occurs so in the next step the ball wont collide again. For the walls is quite simple:

if(x<0) {
  vx*=-1;
  x=0;
}

You can use the same logic with the paddle, but its quite tricky to get it right, since in the next iteration the paddle might move over the position of the bounced ball, bounce back again, this time in the opposite direction, hence get stuck in the paddle.

You could try a few things to correct that, like preventing two or more consecutive paddle collitions, and/or restraining the vertical movement of the paddle, so on each collition you set the Y of the ball away from the paddle to ensure it wont hit it again in the next iteration (like with the walls).

The correct way of doing it though is much harder, since it depends on predicting exactly where the ball will hit (discarding the problem with iterations), combining the vector of the paddle with the ball's on that exact point, and a whole lot more math. Someone else can probably explain this much better than me. Or you might want to check some physics engine ^^

For learning porpouses though, I would advise you to keep trying to solve the collition with your previous approach and then get into the more complex stuff.

Cay
A: 

Gotta learn some physics to get this right. You need to think about the velocity in a coordinate system that is relative to the wall: one component parallel to the wall and the other perpendicular. (I'll assume 2D for simplicity's sake.)

The component of velocity perpendicular to the wall reverses in sign after the collision and has the same magnitude as before the collision (assuming an elastic impact with no energy loss).

The component of velocity parallel to the wall is unchanged (assuming an elastic impact and neglecting friction and rotational effects).

If you use that recipe to work out the velocity vector after impact you'll get it right.

  1. Transform from (x,y) coordinates to "wall coordinates" (parallel and perpendicular).
  2. Reverse the sign of the perpendicular component of velocity.
  3. Transform back to (x, y) coordinates.
duffymo
A: 

I appreciate all the feed back. But the reason I wanted to use angles, is to control the direction of where the ball goes based on the speed of the paddle. In psuedo, this is what I am trying to do...

var tempSpeedX:Number = xspeed;
var tempSpeedY:Number = yspeed;
var tempDirY:Number = yDir * -1;

tempSpeedY = tempSpeedY * tempDirY;
var angle:Number = Math.atan2(tempSpeedY , tempSpeedX );

//angle = angle + ( paddle.cspeed * .4 );
xspeed = Math.cos(angle);
yspeed = Math.sin(angle);
trace(xspeed);
trace(yspeed);
yDir += tempDirY;
isHit = false;

tempSpeedX, tempSpeedY, and tempDirY are temporary variables used to hold my ball's x and y velocity. tempDirY is used to hold my Y axis direction. Either -1 or 1. What I am doing is trying to recreate the new angle.

Lets say the ball is moving at vx = 3, vy = 3. I know upon impact that ball will be heading at that direction. So what I do is flip the Y axis and get angle. That is what the following code does

tempSpeedY = tempSpeedY * tempDirY;

I take the current direction and multiply it by the speed to flip it going the other direction. What I do next is get the angle using atan2

var angle:Number = Math.atan2(tempSpeedY , tempSpeedX);

Once I get the new angle, At this point in time. I could alter the direction to where I want the ball to go based on my paddle.speed. where it is commented out I put code to alter the direction. I then would put it back to normal angle by using sin and cosine. then at it back to xspeed and yspeed. but this code doesnt work. not sure whats wrong.

I know what I am doing is little too complicated because of my lack of knowledge in physics. But the basic way is causing too many complication that I cant really explain it.

Lets say that the old way , the ball doesnt move in the direction the paddle is trying to take it. xDir is constantly flipping back and forth from -1 to positive makeing the speed flip back and forth from negative to positive. my paddle moves back and forth so that speed is negative and positive. and therefore sometimes the directions dont go they way they are suppose to. so I am trying to think of a better way of controlling the ball with the paddle

numerical25
Physics is the same regardless. My comments still apply. You'll want to add in the effect of the impulse added by the motion of the paddle.
duffymo