Ball is bouncing unrealistically fast - math

I am trying to create a simple bouncy ball simulator, and I want the balls to move at approximately the same speed as they would in real life. However, currently, after being dropped from 5 feet, the ball hits the ground almost instantly and bounces a few times before stopping in than a second. I know I could just experiment with my gravity value until it's semi-realistic, but I'm confused as to why my current gravity value doesn't work. Here's how I got the current one:
Gravity in real life = 9.8 m/sec^2
= 32.152 ft/sec^2
= 1.072 ft per 1/30th of a sec^2 (my frame rate is set to 30 in my program)
= 102.887 pixels per 1/30th of a sec^2 (a foot is 96 pixels in my program)
Here's my code for moving the ball (using Processing 3.2.1):
void move() {
dy+=102.88704; //gravity
x+=dx;
y+=dy;
z+=dz;
if(y+size*8>480) {
dy*=-0.85;
}
y=constrain(y,-100000.0,480-(size*8));
}
Currently, x and z just stay at 0. Since it's being dropped from 5 feet, it hits the ground when it gets to 480-size*8 (size is in inches). The 0.85 value is temporary and I might tweak it later, but it shouldn't have any impact on this issue. Any and all help is greatly appreciated. Thanks!

Your mistake is in converting your measurements from seconds to 1/30 seconds. Note that the unit is ft/sec^2: that is seconds squared. So to convert the time unit from seconds to 1/30 seconds you must also square the 1/30. Therefore
32.152 ft/sec^2
= 32.152/30^2 ft/(1/30 sec)^2
= 0.035724 ft/(1/30 sec)^2
= 0.035724 * 96 pixels/(1/30 sec)^2
= 3.4295 pixels/(1/30 sec)^2
So try replacing the number 102.88704 with 3.4295 and see if that fixes the problem.

Related

Different rendering speed Qt widgets

I'm building an app (in Qt) that includes a few graphs in it which are dynamic (meaning refreshes to new values rapidly), and gets there values from a background thread.
I want the first graph, whose details are important refreshing at one speed (100 Hz) and 4 other graphs refreshing in lower speed (10Hz).
The problem is, that when I'm refreshing them all at the same rate (100 Hz) the app can't handle it and the computer stucks, but when the refresh rate is different the first signal gets artifacts on it (comparing to for example running them all an 10Hz).
The artifacts are in the form of waves (instead of straight line for example I get a "snake").
Any suggestions regarding why it has artifacts (rendering limits I guess) and what can be done about it?
I'm writing this as an answer even if this doesn't quite answer your question, because this is too long for a comment.
When the goal is to draw smooth moving graphics, the basic unit of time is frame. At 60 Hz drawing rate, the frame is 16.67 ms. The drawing rate needs to match the monitor drawing rate. Drawing faster than the monitor is totally unnecessary.
When drawing graphs, the movement speed of graph must be kept constant. If you wonder why, walk 1 second fast, then 1 seconds slow, 1 second fast and so on. That doesn't look smooth.
Lets say the data sample rate is 60 Hz and each sample is represented as a one pixel. In each frame all new samples (in this case 1 sample) is drawn and the graph moves one pixel. The movement speed is one pixel per frame, in each frame. The speed is constant, and the graph looks very smooth.
But if the data sample rate is 100 Hz, during one second in 40 frames 2 pixels are drawn and in 20 frames 1 pixel is drawn. Now the graph movement speed is not constant anymore, it varies like this: 2,2,1,2,2,1,... pixels per frame. That looks bad. You might think that frame time is so small (16.67 ms) that you can't see this kind of small variation. But it is very clearly seen. Even single varying speed frames can be seen.
So how is this data of 100 Hz sample rate is drawn smoothly? By keeping the speed constant, in this case it would be 1.67 (100/60) pixels per frame. That of course will require subpixel drawing. So in every frame the graph moves by 1.67 pixels. If some samples are missing at the time of drawing, they are simply not drawn. In practice, that will happen quite often, for example USB data acquisition cards can give the data samples in bursts.
What if the graph drawing is so slow that it cannot be done at 60 Hz? Then the next best option is to draw at 30 Hz. Then you are drawing one frame for every 2 images the monitor draws. The 3rd best option is 20 Hz (one frame for every 3 images the monitor draws), then 15 Hz (one frame for every 4 images) and so on. Drawing at 30 Hz does not look as smooth as drawing at 60 Hz, but the speed can still be kept constant and it looks better than drawing faster with varying speed.
In your case, the drawing rate of 20 Hz would probably be quite good. In each frame there would be 5 new data samples (if you can get the samples at a constant 100 Hz).

Scaled speed of planets and moons doesn't add up?

So I am working on a simulation of the solar system and ran into a roadblock...
In reality, the speed of the moon compared to the earth is much slower then that of the earth compared to the sun. However, the moon completes its orbit much quicker because it has to travel much less distance. The moon orbits the earth about 13 times in 1 year.
In my simulation however, the moon gets maybe 2 orbits in a year...
I've checked the speed with wikipedia and they are correct.
The only difference is that I scale everything, making me suspect that that's the cause.
All distances are devided by 100 000 and all speeds are devided by 1000
this.angle += (speed * deltatime);
this.x = this.semi_major_axis * Math.cos(this.angle) + this.parent.x + this.focalX;
this.y = this.semi_minor_axis * Math.sin(this.angle) + this.parent.y + this.focalY;
Speed is the speed according to Wikipedia. (29.78 km/s for earth and 1.022 km/s for the moon)
Parent in this case means the object it is orbiting (in case of the earth, it's the sun. In case of the moon, it's the Earth)
focalX and focalY are the offset from the planet.
Speed and the 2 axis values are already scaled at this point.
Am I wrong in the manner of the scale? Am I completely missing something obvious? Am I just doing it completely the wrong way?
Since speed is distance/time (eg kilometres/second) when you scale speed by 1000 and distance by 100000 you have, whether you know it or not, scaled time by 100. Are you sure that you have taken this into account in the rest of your calculations ?
And yes, you are approaching this entirely the wrong way. If you were building a mechanical simulator you would want to scale distances quite early in the process, but in a numerical simulator why scale them at all ? Just work in the original units.
Since you don't have a computer screen which is several AU (astronomical units) across, you might have to scale the numbers for imaging but most graphics systems will do that for you at some point in the pipeline.
I'd say you should go through the exercise of non-dimensionalizing the original equation of motion, similar to what people do with Navier-Stokes equation for fluids (it's a good example to look for). You'll see that non-dimensional groupings should turn up, like the Prandtl and Reynolds numbers for fluids, that will give you meaningful insight into the problem AND make your numerical solution more tractable.
I don't think it'll be the scale, the simulation will do those distances 100 times quicker than is accurate (big drop in distance, small drop in speed), but it should be uniform across the board so the Earth and Moon will both speed up by the same amount, I'd look at the base speeds again and make sure they're correct and also your algorithm that calculates distance travelled.

Arkanoid Physics (projectile physics simulation)

I have a slider, whose velocity I calculate via the difference between positions each tick (this can sometimes be huge due to using it via a touch screen, so maybe I should clamp this at some arbitrary number to avoid some of these issues?)
I have a ball with a 3 dimensional direction vector and a velocity.
When the ball collides with the slider I invert its direction on the Z axis (going away from the slider) and then use the sliders velocity to manipulate its X (left <-> right) direction. so:
ball.direction.x += (slider_friction * slider_velocity)
Now the ball update is carried out as follows:
velocity = ball.velocity * time
ball.direction.normalise()
ball.position = ball.direction * ball.velocity
This seems to work great, except in some cases it seems to be very possible for any of the balls axis to equal zero, resulting in it never returning to the slider in some cases. What would be a good solution to this? And what would be a good way to handle the response with the blocks when it collides with them? Should it return to bouncing at right angles, or should it maintain reflecting with the same bounce modifiers applied by the slider? Also any other physics tips for this kind of projectile simulation would be appreciated.
Hmm, this is a nice problem; the thing is, a good solution (that is, one that looks and feels just like real physics) is by nature one that uses real physics. Luckily, most of the newtonian physics within this problem can be easily simplified. Pardon me if I get overly verbose, but physics tends to do that to you.
So, to define the problem, this is an elastic (as in, no energy is absorbed) collision between an arkanoid ball and a paddle. First of all, since you've obviously got the vertical motion down, I won't concern myself with that. So what follows is all on the horizontal components of the collsions.
The paddle transfers a certain amount of horizontal momentum to the ball (although, since this is Arkanoid physics, the paddle loses no momentum itself :P). This can be recieved in two ways -- by making the ball spin, and by giving the ball some horizontal momentum (obviously, if the ball already has horizontal momentum or spin, the added momentum will be...well, added).
delta momentum + delta angular momentum = momentum paddle gave
Of course, it might be annoying to work with momenta, since you don't really have to. I would asssume that the ball and the paddle have constant mass (that is, the ball does not suddenly become heavier, although you could easily work with that), because then you could factor the mass of each out of your momentum equations. So then,
delta horizontal velocity + delta angular velocity = paddle velocity * mass of paddle / mass of ball
To get an equation you could use out of this, you have to set how much of the momentum from the paddle would go into the spin, and how much would go into ball movement. For example,
mass_factor = 2 # ratio between paddle and ball masses
angular_factor = 0.3 # the amount of the paddle's movement which will go into the ball's spin
# and now for the bouncy-bouncy
ball.hVel += (1 - angular_factor) * paddle.hVel * mass_factor * friction or whatever
ball.spin += angular_factor * paddle.hVel * mass_factor * friction or whatever
ball.vVel = - ball.vVel # of course, its vertical velocity reverses
This will be enough to set up a quasi-realistic bounce, but one nugget remains (which you don't need to adress, but adressing it would make your Arkanoid amazing) -- what happens to all that spin? Can the spin be used somehow for more interesting bounces?
So, to recap, your spin is the speed at which the periphery of the ball is moving relative to the center. Thing is, whenever a spinning ball bounces against something stationary, its spin changes as well as its velocity. If a spinning ball hits a stationary surface, the bal gets a little "kick" in the direction opposite that of its spin (if spin is measured at the point of contact), and the spin will change.
#Upon collision with a surface (assumed horizontal, with the ball above the surface)
ball.hVel += -(ball.Avel * rate) # Where "rate" is the ratio which determines how much angular velocity decays with each bounce
ball.Avel *= 1 - rate # So the angular velocity decays properly
Since angular velocity is rotationally symmetric, you would just treat collisions at different angles (balls on walls, balls on ceilings) as rotations of this.
Phew, that was unintentionally long-winded, and it is nowhere near complete, but it's enough to answer your question IMHO.

Trajectory of a projectile meets a moving object (2D)

I've looked for quite some time now to find a nice math solution for my cannon firing a projectile at a moving target, taking into account the gravity. I've found a solution for determining the angle at which the cannon should be fired, based on the cannon's position, the target's position and the start velocity. The formula is described here: http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_.CE.B8_required_to_hit_coordinate_.28x.2Cy.29.
This works perfectly. However, my target is moving, so if I shoot at the target and the projectile takes a few seconds to get to its destination, the target is long gone. The target's x position can be determined from the time. Lets say that: x = 1000 - (10 * t) where t is the time in seconds. The y can be described as: y = t.
The problem is, that t depends on the angle at which the cannon is fired.
Therefor my question is: How can I modify the formula as described in the wiki, so that it takes the moving target into account?
Additionally, I might have been looking at the wrong words here or on Google, but I didn't find any solution describing this exact problem.
Thank you in advance for your braintime!
As a reply to your comments. I want to fire it now and the target is in range given the speed. I think that are all constraints that are applicable to this problem.
As a reply to the answer, lets take a look at this example:
The cannon is at {0, 0} and isn't moving.
The start speed is 100 m/s.
The target is at {1000, 0} and is moving with 10 m/s towards the cannon (v = -10 m/s).
What angle should I use to hit the moving target, when I want to fire at t=0 (immediately)?
If I shoot without taking the target's speed into account, I would aim at {1000, 0} and the angle could be calculated using the mentioned formula. But it will miserably miss the target because its moving.
As Beta suggested, I could aim at i.e. {500, 0}, calculate what time it takes for the projectile to arrive at those coords (lets say 5 seconds) and wait until the target is 5 seconds away from {500, 0}, being {550, 0}. But this means that I have to wait 450m or 45 seconds before I can fire my cannon. And I don't want to wait, because the target is killing me in the mean time.
I really hope this gives you enough info to go with. I'd prefer some math solution, but anything that would get me really close to firing "right away" and "right on target" is also much appreciated.
The problem is underconstrained, which means that you will have some choices. You can track the target through the air for a while, and the choice of when to fire is up to you.
If you know the target's trajectory, and you know how to hit a stationary target, then you can choose where you want the impact to occur. Just pick a point on the trajectory (comfortably far ahead of the target) and aim there. Then all you have to do is decide when to fire. It is easy to calculate how long the cannonball will take to reach the point of impact; it is easy to calculate where the target will be, that much time before it reaches the point of impact; when the target is there, pull the trigger.
I suspect finding a formula will be quite difficult. However the error in the iterative scheme below will go down by roughly a factor of v/V (v the target speed, V the projectile speed) each step.
start by taking the time of flight to be zero
Repeat
calculate the distance to the target (using time of flight)
calculate the time of flight from the distance.
Until two successive times of flight are close enough

2D Spaceship movement math

I'm trying to make a top-down spaceship game and I want the movement to somewhat realistic. 360 degrees with inertia, gravity, etc.
My problem is I can make the ship move 360° with inertia with no problem, but what I need to do is impose a limit for how fast the engines can go while not limiting other forces pushing/pulling the ship.
So, if the engines speed is a maximum of 500 and the ship is going 1000 from a gravity well, the ship is not going to go 1500 when it's engines are on, but if is pointing away from the angle is going then it could slow down.
For what it's worth, I'm using Construct, and all I need is the math of it.
Thanks for any help, I'm going bald from trying to figure this out.
Take a page from relative physics, where objects cannot exceed the speed of light:
(See below for my working C++ code snippet and running demo [Windows only].)
Set the constant c to the maximum speed an object can reach (the "speed of light" in your game).
If applying a force will increase the speed of the object, divide the acceleration (change in velocity) by the Lorentz factor. The if condition is not realistic in terms of special relativity, but it keeps the ship more "controllable" at high speeds.
Update: Normally, the ship will be hard to maneuver when going at speeds near c because changing direction requires an acceleration that pushes velocity past c (The Lorentz factor will end up scaling acceleration in the new direction to nearly nothing.) To regain maneuverability, use the direction that the velocity vector would have been without Lorentz scaling with the magnitude of the scaled velocity vector.
Explanation:
Definition of Lorentz factor, where v is velocity and c is the speed of light:
This works because the Lorentz factor approaches infinity as velocity increases. Objects would need an infinite amount of force applied to cross the speed of light. At lower velocities, the Lorentz factor is very close to 1, approximating classical Newtonian physics.
Graph of Lorentz factor as velocity increases:
Note: I previously tried to solve a similar problem in my asteroids game by playing with friction settings. I just came up with this solution as I read your question^^
Update: I tried implementing this and found one potential flaw: acceleration in all directions is limited as the speed of light c is approached, including deceleration! (Counter-intuitive, but does this happen with special relativity in the real world?) I guess this algorithm could be modified to account for the directions of the velocity and force vectors... The algorithm has been modified to account for directions of vectors so the ship does not "lose controllability" at high speeds.
Update: Here is a code snippet from my asteroids game, which uses the Lorentz factor to limit the speed of game objects. It works pretty well!
update:* added downloadable demo (Windows only; build from source code for other platforms) of this algorithm in action. I'm not sure if all the dependencies were included in the zip; please let me know if something's missing. And have fun^^
void CObject::applyForces()
{
// acceleration: change in velocity due to force f on object with mass m
vector2f dv = f/m;
// new velocity if acceleration dv applied
vector2f new_v = v + dv;
// only apply Lorentz factor if acceleration increases speed
if (new_v.length() > v.length())
{
// maximum speed objects may reach (the "speed of light")
const float c = 4;
float b = 1 - v.length_squared()/(c*c);
if (b <= 0) b = DBL_MIN;
double lorentz_factor = 1/sqrt(b);
dv /= lorentz_factor;
}
// apply acceleration to object's velocity
v += dv;
// Update:
// Allow acceleration in the forward direction to change the direction
// of v by using the direction of new_v (without the Lorentz factor)
// with the magnitude of v (that applies the Lorentz factor).
if (v.length() > 0)
{
v = new_v.normalized() * v.length();
}
}
Well, lets consider the realistic problem first and see why this doesn't work and how we have to differ from it. In space as long as your engines are firing, you will be accelerating. Your speed is only limited by your fuel (and in fact you can accelerate faster once you've spent some fuel because your moving less mass).
To give this model an effective maximum speed, you can consider particles in space slowing you down and causing friction. The faster you go, the more particles you're hitting and the faster you're hitting them, so eventually at some fast enough speed, you will be hitting enough particles the amount of decelerating they do exactly cancels out the amount of accelerating your engine is doing.
This realistic model does NOT sound like what you want. The reason being: You have to introduce friction. This means if you cut your engines, you will automatically start to slow down. You can probably count this as one of the unintended forces you do not want.
This leaves us with reducing the effective force of your engine to 0 upon reaching a certain speed. Now keep in mind if your going max speed in the north direction, you still want force to be able to push you in the east direction, so your engines shouldn't be cut out by raw velocity alone, but instead based on the velocity your going in the direction your engines are pointing.
So, for the math:
You want to do a cross dot product between your engine pointing vector and your velocity vector to get the effective velocity in the direction your engines are pointing. Once you have this velocity, say, 125 mph (with a max speed of 150) you can then scale back the force of your engines is exerting to (150-125)/150*(Force of Engines).
This will drastically change the velocity graph of how long it will take you to accelerate to full speed. As you approach the full speed your engines become less and less powerful. Test this out and see if it is what you want. Another approach is to just say Force of Engines = 0 if the dot product is >=150, otherwise it is full force. This will allow you to accelerate linearly to your max speed, but no further.
Now that I think about it, this model isn't perfect, because you could accelerate to 150 mph in the north direction, and then turn east and accelerate to 150 mph going in that direction for a total of 212 mph in the north east direction, so not a perfect solution.
I really do like Wongsungi's answer (with the Lorentz factor), but I wanted to note that the code can be simplified to have fewer floating-point operations.
Instead of calculating the Lorentz factor (which itself is a reciprocal) and then dividing by it, like this:
double lorentz_factor = 1/sqrt(b);
dv /= lorentz_factor;
simply multiply by the reciprocal of the Lorentz factor, like this:
double reciprocal_lorentz_factor = sqrt(b);
dv *= reciprocal_lorentz_factor;
This eliminates one floating-point operation from the code, and also eliminates the need to clamp b to DBL_MIN (it can now be clamped to 0 because we're not dividing anymore). Why divide by the reciprocal of x when you can just multiply by x?
Additionally, if you can guarantee that the magnitude of v will never exceed c, then you can eliminate the testing of b being less than zero.
Finally, you can eliminate two additional sqrt() operations by using length_squared() instead of length() in the outer if statement:
if (new_v.length_squared() > v.length_squared())
{
const float c = 4;
float b = 1 - v.length_squared()/(c*c);
if (b < 0) b = 0;
double reciprocal_lorentz_factor = sqrt(b);
dv *= reciprocal_lorentz_factor;
}
This may only make a 0.1% difference in speed, but I think the code is simpler this way.
You need to have three variables for your ship, which you update at each physics time step based on the forces that are acting on it. These will be mass, position, and velocity. (note that position and velocity are single numbers but vectors). At each physics time step you update the position based on the velocity, and the velocity based on the acceleration. you calculate the acceleration based on the forces acting on the ship (gravity, friction, engines)
Newton's equation for force is F = M*A We can rearrange that to A = F/M to get Acceleration. Basically you need to figure out how much the ship should accelerate, and in which direction (vector), then add that acceleration to the ship's velocity, and add the ship's velocity to its position.
Here is the code you should execute each physics time step (I hope you can fill in the blanks) please ask if this is not enough detail
gravity = //calculate force of gravity acting on ship from Newton's law of universal gravitation
friction = //ten percent of the ship's velocity vector, in the opposite direction
engines = 0
if (engines_are_firing)
engines = 500
forces = gravity + friction + engines
acceleration = forces / ship.mass
ship.velocity += acceleration
ship.position += velocity
redraw()
Your question is difficult for me to understand but it seems like you're not using real physics for this game. Have you considered using real physics equations such as velocity, acceleration, force, etc?
Edit:
After your edits, I think I have a better understanding. You are simply keeping track of the current velocity (or something similar) but you don't keep track of the force where that velocity comes from. The ship should not be storing any of that information (other than engine thrust) -- it should come from the environment the ship is in.
For instance, the environment has a gravity vector (directional force) so you would need to take that into account when calculating the directional force provided by the engine.
Your ship should be storing its own engine force, acceleration, and velocity.

Resources