2D Game Physics Vectors issue - c#

I've been working on a simple program in C# in which a Ball [X,Y] cordinates are periodical incremented.
I've managed to implement a collision detection method, but I'm trying to determine how to reflect the ball at an angle oposed bouncing it back along the same linear path.
dx = -dx //This bounces the ball back along the same linear path
dy = -dy
Solution
Trigonometry
theta = range between 0<theta<=360 depending on where it bounced
x = cos(theta)*time
y= sin(theta)*time

The whole point of Newtonian physics is that it is not random, it is deterministic. If you throw the same ball against the same wall at the same angle and with the same velocity and the same spin, it goes to the same place every time.
This sort of program is a really great learning opportunity for both programming and physics. What I encourage you to do is to first write a program that simulates very simple bouncing. As you note, when an object is moving straight down and hits a horizontal surface, then you can model the bounce as simply reversing the vertical velocity component. Just get that right; no gravity, no nothing. That's a great start.
Then try adding bouncing off of horizontal walls, the same way.
Then try adding bouncing off of walls that are not aligned with horizontal or vertical directions. That's where you're going to have to learn how vectors and trigonometry work, because you'll have to work out what component of the ball's velocity is changed by striking the wall obliquely.
Then add gravity. Then add friction from the air. Then add the fact that the ball can be spinning. Add elasticity, so that you can model deformation of the ball.
Once you get to that point, if you want to introduce randomness you'll be able to figure out how to do it. For example, you might introduce randomness by saying "well, when the ball strikes the wall and deforms, I'll introduce a random element that changes its deformation by 0-10%". That will then change how the simulation bounces the ball. You can experiment with different kinds of randomness: add random air currents, for instance.

You will have to add in randomness yourself. To rephrase your question: "Deterministically, it bounces off at angle theta. How can I make it bounce back at angle theta + epsilon, where epsilon is some random value?"
To rotate a vector, see this. You will just specify theta.
pseudocode:
RotateVector(vec):
bounce_vec = [-vec.x vec.y]; //deterministic answer is negative x, normal y
bounce_angle = acos(dot(vec,bounce_vec) / (norm(vec)*norm(bounce_vec)));
modified_angle = bounce_angle + random_number();
ca = cos(modified_angle);
sa = sin(modified_angle);
rotation_matrix = [ca -sa; sa ca];
return rotation_matrix * vec;
Line 3 uses the law of cosines to figure out the angle. In line 4, that angle is modified randomly. The rest of the function rotates the original vector by your new angle.

As long as it's a perfect ball with a perfect surface it will not bounce back randomly. Neither vectors nor trigonometry will give you any randomness.

"randomly, though applying to the basic laws of physics" seems like an oxymoron. However...
If you want it to bounce in a random direction, while maintaining its current speed, you might do something like this (pseudocode):
first, bounce back the canonical way (dx = -dx or dy = -dy depending on the collision)
then convert the dx and dy to polar coordinates (theta and r)
jitter theta by a small amount (+ or - a few degrees, according to your taste)
make sure theta isn't heading into a wall that you just bounced off
convert theta and r back to dx and dy
That would be conserving scalar momentum.

Related

ball reflection angles Xna c#

I'm trying to find a way to handle reflections for a breakout clone.
I would upload an image to the post instead of the following paragraph, however i have not yet gained the privilege of that yet.
If the ball intersects the left hand side i want it to bounce off to the left.
if the ball intersects the right hand side i want it to bounce off to the right. if the ball intersects the middle section i want it to bounce up the way. i want to learn how to make it bounce in a varying direction dependant on what side of the left, right, or middle section was intersected
I would like to not use three separate rectangles for this, i want to learn how to do it with one.
I use a Vector2 for ball velocity, projVel.
It's position is projPos.
A rectangle for the paddle lightRect.
The reason I use proj.collRect for the beginning of the if is because I cannot use the intersect method with Vector2.
This is my makeshift collision handler at present, which does work but the speed changes to an extent which renders the game unplayable. The speed clamp i have only slightly slows it down i think. i have a variable for projSpeed i cannot clamp that or it will never be able to stop.
if (proj.collRect.Intersects(lightSaber.lightRect))
{
proj.projPos.Y = lightSaber.lightRect.Y - proj.projTxr.Height;
proj.projVel.Y *= -1;
proj.projVel.X = 10 * (proj.projPos.X - lightSaber.lightRect.Center.X) / (lightSaber.lightRect.Center.X);
}
proj.projVel.X = Math.Max(-4, Math.Min(proj.projVel.X, 4));
proj.projVel.Y = Math.Max(-4, Math.Min(proj.projVel.Y, 4));
Help me by showing me how I could do this, maybe in the Math. method, or even an alternative to .Intersects so I can use projPos instead of collRect.
I really am not sure where to start, if there is another way I could do it an example would be great.
Instead of manipulating X and Y velocities independently, I recommend that you calculate a reflection angle based on the position and then derive the velocity from the angle and the speed prior to impact.
Example:
// NOTE: this code assumes that positive Y is down
if (proj.collRect.Intersects(lightSaber.lightRect) && projPos.projVel.Y > 0.0f) // only bounce if projectile is moving downward
{
// remember current speed for when we calculate new velocity
var projSpeed = projVel.Length();
// make sure the projectile no longer intersects the bar
proj.projPos = lightRect.Y - proj.projTxr.Height;
// interpolate reflection angle
var t = (proj.projPos.X - lightSaber.lightRect.X) / lightSaber.lightRect.Width;
var reflectDegrees = 150.0f - t * 120f; // straight up +/- 60 degrees
var reflectRadians = reflectDegrees * (float)Math.PI / 180.0f;
// final velocity determined by angle and original projectile speed
proj.projVel = new Vector2((float)Math.Cos(reflectRadians) * projSpeed, -(float)Math.Sin(reflectRadians) * projSpeed);
}

Two colliding circles , unable to convert formula into code

I am at the level where I can detect collision of circles in my rigid body 2D physics program.
These circles have random x, y velocity.
When any of them hits any other of them I can tell that they are colliding against each other then! this step is the problem.
I am trying to take the X and Y values of velocity and convert it based on the axis of collision point, I mean the axis of normal force and another axis that is perpandacular to the normal force axis. The perpandacular axis is called tangent axis... right?
I use sin cos tan, but the problem is that since sin cos tan only returns an angle that is always the right side, my objects never move to the left side.... so the momentum of X axis of all the colliding objects is fixed to the right side.
This leads to whole a lot of problems and I am unable to find out how to fix it.
I would appreciate so much even little piece of advice.
Thank you.
You shouldn't be using trigonometric functions (sin, cos, tan, etc.).
You want to apply an impulse to the objects in the direction of the collision, i.e. the impulse is some multiple of the collision direction vector. Calculate the momentum of the objects and simply add the impulse.
If you're doing simple elastic collisions the momentum and energy are conserved. Given those constraints you can calculate the impulse. This wikipedia article has details.

C# bounce/throw physics for items dropping

I thought I'd be able to find this with some searching on the internet but everything I find is just balls bouncing off walls for something like pong or another arbitrary question. I'm making a 2D dungeon crawler game and when I kill enemies and they drop loot I want the item to come flying out as if it had just been thrown in the air and land a random point on the tile the unit was on.
I've been trying to figure this out myself but I can't figure it out, this is probably asked a lot, I'd be really grateful if someone could help me out.
EDIT AS REQUESTED:
Ok well when a monster would be destroyed I would choose a random location within the tile it's in, let's call this location endLoc and the monster's location startLoc. I would then find the center x point between these two locations and decrease the y by 20 ( because that's how many pixels i want the item to go up by), so let's called this variable launchLoc:
launchLoc = new Vector2(startLoc.X + ((endLoc.X - startLoc.X) / 2), startLoc.Y - 20)
I think that produces the right Vector.
So now I would need to launch the item from startLoc, to launchLoc, then have it come back down to endLoc. This is where it gets confusing and I'm not sure how to make a realistic arc for this. The end result would have the item move like it moved along a gaussian, as if it was thrown into the air.
I tried to make it so during each interval, the velocity is increased by 120th, of the X difference, between the startLoc and launchLoc, by an incrementing multiple, but I couldn't get it to work very well. I'm not sure if this was the best way to do. I use 120th because the y value is 20, and the item moves up 1 pixel every interval, so 1 to 20 added up gives 120, this would make the x movement constantly increase, like it was thrown up.
This is in 2D btw, I hope that helps.
You start with an initial velocity vector at time t0 (v(t0)) and position (p(t0)). Gravity can be assumed to produces a constant acceleration (a(t0) = <0, -9.8 m/s2>, though your value may differ) until the object lands. So the general form of the motion for going from one timeslice to the next is:
p(t) = 0.5*a(0)*(t-t0)2 + v(0)*(t-t0) + p(0)
v(t) = a(0)*(t-t0) + v(0)
To figure out when to stop that motion, you need to figure out at what time the object's path will intersect the surface against which it bounces. You'll have to do this for all of the surfaces for which this can reasonably be expected to happen. So for a plane with line equation Ux + Vy + T = 0 you break the position vector into its components, as in:
p(t) = <px(t), py(t)> Then use the quadratic formula to find tc where p(tc) satisfies the line equation:
0.5*(Uax(t0)+Vay(t0))*tc2 + (Uvx(t0)+Vvy(t0))*tc + (Upx(t0)+Vpy(t0)+T) = 0Chose the branch such that tc > t0. From there it's simple to figure out where the object will collide with the surface. You can then update the velocity vector and position vector based on the behavior of the bounce. If the plane is axially aligned (ie, it's a horizontal plane with normal vector parallel to the Z axis), then just flip the sign of the Z component of the velocity vector and multiply the whole velocity vector by some damping factor d, where 0≤d<1 to damp out the velocity. Then repeat until some predetermined time has passed or the velocity reaches some minimal amount (your call on that).
It becomes a bit more difficult with arbitrarily oriented planes. You will need to calculate the angle of incidence of the collision and reflect the velocity vector about the plane normal. I won't go into the details here, as I suspect you're probably not interested in it.

Simple 2D rocket dynamics

I am currently experimenting with some physics toys in XNA using the Farseer Physics library, however my question isn't specific to XNA or Farseer - but to any 2D physics library.
I would like to add "rocket"-like movement (I say rocket-like in the sense that it doesn't have to be a rocket - it could be a plane or a boat on the water or any number of similar situations) for certain objects in my 2D scene. I know how to implement this using a kinematic simulation, but I want to implement it using a dynamic simulation (i.e. applying forces over time). I'm sort of lost on how to implement this.
To simplify things, I don't need the dynamics to rotate the geometry, just to affect the velocity of the body. I'm using a circle geometry that is set to not rotate in Farseer, so I am only concerned with the velocity of the object.
I'm not even sure what the best abstraction should be. Conceptually, I have the direction the body is currently moving (unit vector), a direction I want it to go, and a value representing how fast I want it to change direction, while keeping speed relatively constant (small variations are acceptable).
I could use this abstraction directly, or use something like a "rudder" value which controls how fast the object changes directions (either clockwise or counter clockwise).
What kind of forces should I apply to the body to simulate the movement I'm looking for? Keep in mind that I would also like to be able to adjust the "thrust" of the rocket on the fly.
Edit:
The way I see it, and correct me if I'm wrong, you have two forces (ignoring the main thrust force for now):
1) You have a static "fin" that is always pointed in the same direction as the body. If the body rotates such that the fin is not aligned with the direction of movement, air resistance will apply forces to along the length of the fin, proportional to the angle between the direction of movement and the fin.
2) You have a "rudder", which can rotate freely within a specified range, which is attached some distance from the body's center of mass (in this case we have a circle). Again, when this plane is not parallel to the direction of movement, air resistance causes proportional forces along the length of the rudder.
My question is, differently stated, how do I calculate these proportional forces from air resistance against the fin and rudder?
Edit:
For reference, here is some code I wrote to test the accepted answer:
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
float dc = 0.001f;
float lc = 0.025f;
float angle = MathHelper.ToRadians(45);
Vector2 vel = new Vector2(1, 0);
Vector2 pos = new Vector2(0, 0);
for (int i = 0; i < 200; i++)
{
Vector2 drag = vel * angle * dc;
Vector2 sideForce = angle * lc * vel;
//sideForce = new Vector2(sideForce.Y, -sideForce.X); // rotate 90 degrees CW
sideForce = new Vector2(-sideForce.Y, sideForce.X); // rotate 90 degrees CCW
vel = vel + (-drag) + sideForce;
pos = pos + vel;
if(i % 10 == 0)
System.Console.WriteLine("{0}\t{1}\t{2}", pos.X, pos.Y, vel.Length());
}
}
When you graph the output of this program, you'll see a nice smooth circular curve, which is exactly what I was looking for!
If you already have code to integrate force and mass to acceleration and velocity, then you just need to calculate the individual part of each of the two elements you're talking about.
Keeping it simple, I'd forget about the fin for a moment and just say that anytime the body of your rocket is at an angle to it's velocity, it will generate a linearly increasing side-force and drag. Just play around with the coefficients until it looks and feels how you want.
Drag = angle*drag_coefficient*velocity + base_drag
SideForce = angle*lift_coefficent*velocity
For the rudder, the effect generated is a moment, but unless your game absolutely needs to go into angular dynamics, the simpler thing to do is let the rudder control put in a fixed amount of change to your rocket body angle per time tick in your game.
I suddenly "get" it.
You want to simulate a rocket powered missile flying in air, OK. That's a different problem than the one I have detailed below, and imposes different limits. You need an aerospace geek. Or you could just punt.
To do it "right" (for space):
The simulated body should be provided with a moment of inertia around its center of mass, and must also have a pointing direction and an angular velocity. Then you compute the angular acceleration from the applied impulse and distance from the CoM, and add that to the angular velocity. This allows you to compute the current "pointing" of the craft (if you don't use gyros or paired attitude jets, you also get a (typically very small) linear acceleration).
To generate a turn, you point the craft off the current direction of movement and apply the main drive.
And if you are serious about this you also need to subtract the mass of burned fuel from the total mass and make the appropriate corrections to the moment of inertia at each time increment.
BTW--This may be more trouble than it is worth: maneuvering a rocket in free-fall is tricky (You may recall that the Russians bungled a docking maneuver at the ISS a few years ago; well, that's not because they are stupid.). Unless you tell us your use case we can't really advise you on that.
A little pseudocode to hint at what you're getting into here:
rocket {
float structuralMass;
float fuelMass;
point position;
point velocity;
float heading;
float omega; // Angular velocity
float structuralI; // moment of inertia from craft
float fuelI; // moemnt of inertia from the fuel load
float Mass(){return struturalMass + fuelMass};
float I(){return struturalI + fuelI};
float Thrust(float t);
float AdjustAttitude(float a);
}
The upshot is: maybe you want a "game physics" version.
For reason I won't both to go into here, the most efficient way to run a "real" rocket is generally not to make gradual turns and slow acceleration, but to push hard when ever you want to change direction. In this case you get the angle to thrust by subtracting the desired vector (full vector, not the unit) from the current one. Then you pointing in that direction, and trusting all out until the desired course is reached.
Imagine your in floating in empty space... And you have a big rock in your hand... If you throw the rock, a small impulse will be applied to you in the exact opposite direction you throw the rock. You can model your rocket as something that rapidly converts quantum's of fuel into some amount of force (a vector quantity) that you can add to your direction vector.

How to calculate bounce angle?

I played around with it for a while, but I simply can't figure it out.
I made a tank that fires missiles, and when the missiles hit the walls, I want them to bounce off, but I want them to bounce off to the right angle.
Right now I haven't got any obstacles, the missiles just bounce off when they get outside the viewportRectangle I made.
Is the solution I'm looking for quite advanced?
Is there a relativly simple way to do it?
You might think that because your walls are aligned with the coordinate axes that it makes sense to write special case code (for a vertical wall, negate the x-coordinate of the velocity; for a horizontal wall, negate the y-coordinate of the velocity). However, once you've got the game working well with vertical and horizontal walls, probably the next thing you'll think is, "what about walls at arbitrary angles?" So it's worth thinking about the general case from the beginning.
In the general case, suppose your missile has velocity v and hits a wall with surface normal n.
Split v into components u perpendicular to the wall and w parallel to it.
Where:
u = (v · n / n · n) n
w = v − u
Here, v · n is the dot product of the vectors v and n. See the link for an explanation of how to compute it. The dot product n · n evaluates to the square of the length of the normal vector; if you always keep your normals in the form of unit vectors then n · n = 1 and you can omit the division.
After bouncing, the component of motion parallel to the wall is affected by friction f, and the component perpendicular to the wall is affected by elasticity, which can be given in the form of a coefficient of restitution r.
So the velocity after the collision is v′ = f w − r u. In a perfectly elastic, frictionless collision, v′ = w − u; that is, the motion is reflected about the normal at the point of collision, as in the diagram given in Bill's answer.
This approach works just the same in three dimensions too.
(Obviously this is a very simplified notion of bouncing; it takes no account of angular momentum or deformation. But for many kinds of video games this kind of simplification is perfectly adequate.)
I think an easier way to do this is to use the velocity of the missile instead of calculating angles. Say you have a missile that has xVelocity and yVelocity to represent its movement horizontally and vertically. Those velocities can be positive or negative to represent left, right, up, or down.
If a missile hits a top or bottom border reverse the sign of the yVelocity.
If a missile hits a left or right border reverse the sign of the xVelocity.
This will keep the movement in the opposite axis the same.
Borrowing the image from ChrisF's answer, let's say the missile starts out at position I.
With the xVelocity and yVelocity both being positive (in 2D graphics right and down are typically positive) the missile will travel in the direction indicated. Let's just assign values of
xVelocity = 3
yVelocity = 4
When the missile hits the wall at position C, its xVelocity shouldn't change, but its yVelocity should be reversed to -4 so that it travels back in the up direction, but keeps going to the right.
The benefit to this method is that you only need to keep track of a missile's xPosition, yPosition, xVelocity, and yVelocity. Using just these four components and your game's update rate, the missile will always get redrawn at the correct position. Once you get into more complicated obstacles that are not at straight angles or are moving, it will be a lot easier to work with X and Y velocities than with angles.
For perfect particles (& light) the angle of reflection is equal to the angle of incidence, as illustrated by this diagram (from commons.wikimedia.org).
The Wikipedia page on reflection is quite good at explaining how it works.
It's a little bit more complicated when you take into account the elasticity and materials of the object and the obstacles, but this is probably good enough for most applications.
I've had this problem, the only way I found was separating the axes of collision!
Try it:
x += velocity * Math.cos(angle * Math.PI /180);
y += velocity * Math.sin(angle * Math.PI /180);
if (x < 0 || x > canvas.width) {
angle = 180 - angle;
}
else if (y < 0 ||y > canvas.height) {
angle = 360 - angle;
}
I hope this helps you!
As an aside to the specific physics question you are asking, I would recommend the book "Beginning Math and Physics for Game Programmers" by Wendy Stahler. I found it quite useful for my game/physics programming projects.
The code that accompanies the book is C++ but if you know C#, it would be pretty easy to make the conversion.
Have a good one!
180-a will not work in all instances, unless you are merely working a bounce on a top surface when X is increasing.
One direction to head is the XNA forums or pick up XNA sample code. It is C# and it is for building games. I am not stating you want to build your games in XNA, but it is a great tool, and it is free.
Not complicated at all - pseudo-code:
angleObjectHitWall = a;
bounceAngle = 180-a;
Of course this is a very simple calculation, and is totally irrelevant once you start to take into account factors such as material, gravity, walls which aren't straight, etc...
This is really a physics question, so if you are not a physicist (and since you are asking this question, I'm going to take it that you are not) it will require a lot of reading and brainstorming to get it right.
I suggest reading this wikipedia entry to get the basic idea about the depth of your question.
If you only want to make it "look plausible" then I wouldn't worry about it too much and use Bill the Lizard's answer, however if you want to make it right you will have quite an adventure. Don't let this scare you tho! Good luck!
a = 2w - b
where:
a => resulting angle
w => wall or floor or ceiling angle
b => ball angle
This is what I come up after trying to find the simplest formula for computing just the resulting angle of ball bouncing the walls, ceiling and floor. The result could go beyond +360 or -360 degrees but they are still equivalent angle.For example if the ceiling angle is 270deg and the ball angle is 30deg, the resulting angle is 510deg which is equivalent to +150deg or -210 deg. If you'll use 90deg for the ceiling instead of 270deg, the result is still 150deg.
if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}
It works and is simple, good luck.

Categories