Gravity Equation - Velocity Equation | Why is it only good in certain FPS? - java

The jump size with these equations decreases as amount of updates per second goes down. With a delta value multiplying gravity force and amount that jumpspeed force decreases, as well as time elapsed being added by delta every iteration (the delta value is the amount of milliseconds passed since last update), one would think that it would work fine.
//d is delta
...
if(isFalling||isJumping){
elapsedTime +=d;
//the elapsed time is the total amount of time passed since one started jumping,
//so that's logical to add the amount of time since last update.
long tesquared = (long) Math.pow(elapsedTime, 2);
//amount of time elapsed squared.
jumpSpeed+=-0.0000005*elapsedTime*d;
//this is the amount that jumpspeed is taken down by every time.
if(jumpSpeed > 0){
isJumping = true;
} else {
isJumping = false;
}
double fGravity = 0.0000001*tesquared*d;
// this is the equation for gravity, the amount that the player goes down
yRend += jumpSpeed - fGravity;
//the amount it goes up, minus the amount it goes down.
xRend -= strafeSpeed;
oldyRend = yRend;
}
To start a jump, one adds jumpSpeed by whatever amount.
The problem is that when the amount of updates per second decreases, the jumps decrease in duration and magnitute. I'm fairly certain that the delta values here are fine, which means that the problem must be in the equations themselves.
I'm thinking that fGravity is overrunning jumpSpeed more quickly when the delta is larger.
So my question. If the problem really is in the equations themselves, what is the correct way to model the upward force of a player minus the downward gravity force other than
jumpSpeed+=-0.0000005*elapsedTime*d;
and
double fGravity = 0.0000001*tesquared*d;?
If the problem is in the delta value not being applied correctly, then what would be the correct way to apply it?

Players do not have an "upward force" (except at the very point at which they're jumping). Forces impart momentum generating velocity. Once in the air, they do feel a downward force (i.e. gravity) which causes them to decelerate, ultimately generating a negative velocity which returns them to the ground.
If the player starts jumping upwards with velocity u, then at time t after the start of that jump the classic equation for calculating the position is y = ut + 0.5 * at^2.
In this case, a is gravity (which is negative, if y is "up"), giving y = u * t - 0.5 * g * t ^ 2

Basically the equation of a jump are like that:
the gravity applies vertically and produce a constant force downward. So the vertical velocity is vy = vy0 - elapsedTime * g with g being the gravity constant and vy0 the initial velocity at the beginning of the jump.
You don't have to compute the elapsed time. Simply at every frame, you do this:
vy -= g * dt; // dt is the elapsed time since last frame
y += vy * dt;
x += vx * dt; // vx doesn't change in the jump

Related

Calculating speed from set of longitude and latitudes values obtained in one minute?

I need to calculate speed after each 10 seconds or less (currently i am using fused location api to get the location after each 10 seconds). The problem is that the equipment is too slow and sometimes it gives the distance covers equal to zero.
I have tried using Location.distanceBetween() but it also produces zeros even when the equipment is moving. I have tried to calculate distance by a formula but sometimes distance is too small that it gives zero.
Now i want to calculate average speed. I want to save the points obtained in 1 minute (6 lat long values). And then after each 10 seconds, i want to calculate average speed between them. Thus after each 10 seconds I will add one points at the end and remove one point from the start. That will remove the possibility of zero.
Now is there any formula that can calculate speed or distance from set of lat long values or any better approach will be highly appreciated.
You can calculate distance between two point, that are close enough, using simple geometry
deltaLngMeters = R * cos(latitude) * deltaLongitudeRadians;
deltaLatMeters = R * deltaLatitudeRadians;
whereas deltas are in radians, deltaLatitudeRadians = deltaLatitudeDegrees * pi / 180
Hence distance = sqrt(deltaLngMeters ^2 + deltaLatMeters ^ 2).
To sum up
function distance(point1, point2) {
var degToRad = Math.PI / 180;
return R * degToRad * Math.sqrt(Math.pow(Math.cos(point1.lat * degToRad ) * (point1.lng - point2.lng) , 2) + Math.pow(point1.lat - point2.lat, 2));
}
If you have array of six points, you can calculate average speed.
points = [{lat: .., lng: ..}, ... ]; // 6 points
distancesSum = 0;
for(i = 0; i < distances.length - 1; i++) {
distancesSum += distance(points[i], points[i + 1]);
}
return (distancesSum / (points.length - 1));
Yes, R is for the Earth radius, R = 6371000;// meters
You can use multi threading(Thread.sleep()) to calculate a formula repeatedly for every 10 seconds. You can verify it here https://beginnersbook.com/2013/03/multithreading-in-java/.
For small distances(hope the device won't move at speeds above 1 km/s), earth's surface can be treated as a plane. Then the latitude and longitude will be the coordinates of the device on the Cartesian plane attached to earth. Hence you can calculate the distance by this formula:
√(delta(longitude)^2 + delta(latitude)^2)
delta: difference

Game Physics - Friction

My very simple question is: how would I implement friction? Nothing I try seems to be working.
Oh, and speedX = 1.
Here's my code:
public void update() {
x += velocityX;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT)
vx = xSpeed;
if (key == KeyEvent.VK_LEFT)
vx = -xSpeed;
}
public void KeyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT)
vx = 0;
if (key == KeyEvent.VK_LEFT)
vx = 0;
}
Edit:
Now, once the player stops, he slows down (which is good), but he doesn't stop completely.
if (key == KeyEvent.VK_RIGHT) {
vx = 0.20 * vx;
if (vx < 0.2)
vx = 0;
playerAction = "still";
}
Friction is a force opposite to velocity. If you're dealing with forces at all, gravity or electric fields or rocket engines or something more mysterious, just add to the total force one more computed as velocity times some coefficient. You could get fancy and make its magnitude proportional to the speed squared or cubed, for different effects. Then compute velocity and position as usual.
If you're not dealing with forces and F=ma, but using a simpler kind of physics based only on velocity, which is common in video games, you need to decrease that velocity gradually. For each time step, compute new_velocity = 0.99 * current_velocity. Use whatever coefficient gives the right amount of slow-down. Again, you could get fancy and involve velocity squared in some way to alter the feel of the object's slowdown.
Often friction is assumed to be a constant force, considering the friction between two surfaces with a constant normal force, which would slowdown your objects velocity linearly. Other frictional forces like air drag often also have linear and quadratic terms.
If you would want to use friction between two surfaces you could do it like this:
if (vx > 0) vx += -friction / mass;
if (vx < 0) vx += friction / mass;
I also included the mass to suffice F = m * a for the acceleration. If there are also other forces acting on the object it would be a little more complicated since if the object has stopped moving it would only start moving again if the remaining forces exceed the frictional force.
By the way if you would like to make it more numerical correct, you could add a time step size into the simulation: vX += accelerationX * timeStep; and x += vX * timeStep;.
I have worked as a game AI engineer. That often involves making gameplay and physics. I recently had to answer this question myself. That's why I found this. Here is my solution. My problem may be a little different from yours but my challenge was to make it work no matter what framerate I was using. Here's my solution:
speed -= (speed * (1 - friction)) / fps;
friction is always a float between 0 and 1, 1 being no friction and 0 being essentially infinite friction. This makes sure the the right amount of friction will be applied proportional to frames per second.
If u, m and g in Ff=umg for the formula for the force of surface friction is constant, then a in F=ma would also be a constant number. Also because a = deltaV/s that means that the velocity equals acceleration times time (as=deltaV). This means that for every time interval the deltaV remains the same if Ff is the same. The change in speed only stops if it is not moving(v=0). So I think the best way to do this is to detect whether it's moving or not and apply the constant deltaV (for the opposite direction) and not apply it when v reaches zero.
Friction is a force that slows down any objects you have that are moving. So you'd need to have something like a background thread that constantly looks at the speed of all your objects, and slowly decrements each speed towards zero.

Libgdx, physics, acceleration and FPS

I am making a platform game in the Libgdx framework. I want to implement the ability to jump for my character. I use the simply formula:
speed += acceleration * delta_time
r += speed * delta_time
It works well, but only for constant frames per second. The lower FPS is, the lower my character jumps. I have no idea what is the cause of this behavior, the height of jumps should be the same :/
There is a fragment of my code:
delta_time=Gdx.graphics.getDeltaTime();
if(input.getUpArrow()){
if(is_in_air==false){
is_in_air=true;
speed_y=speed_y_0;
}
}
if(is_in_air==true){
speed_y-=acceleration*delta_time;
}
else{
speed_y=0;
}
x+=speed_x*delta_time;
y+=speed_y*delta_time;
And here is an illustration (black dots are character positions):
http://i.imgur.com/tfSTM.jpg
This is perfectly normal behaviour given the very simple and highly inaccurate integrator that you use. It is pretty easy to do the math and show that.
Let's take a single time span of 1/30 seconds. When the game runs at 30 FPS there would be only one update to speed_y and y, so after 1/30 s the new position y' would be:
speed_y' = speed_y - a*dt
y' = y + speed_y'*dt = y + speed_y*dt - a*dt^2
Here dt is the time delta of 1/30 seconds.
When the game runs at 60 FPS, in the same 1/30 seconds there would be two updates happening with twice as shorter time delta, dt/2:
// First update
speed_y' = speed_y - a*(dt/2)
y' = y + speed_y'*(dt/2) = y + speed_y*(dt/2) - a*(dt/2)^2
// Second update
speed_y'' = speed_y' - a*(dt/2) = speed_y - a*dt
y'' = y' + speed_y''*(dt/2) = y + speed_y*dt - 3*a*(dt/2)^2
Now compare both updated y positions:
at 30 FPS it is: y + speed_y*dt - a*dt^2
at 60 FPS it is: y + speed_y*dt - a*(3/4)*dt^2
Obviously at 60 FPS the new position of y would be higher than that at 30 FPS because the subtracted value is lower.
This only affects the vertical motion. The horizontal speed is constant and it doesn't matter if you update x once or twice with twice as short time delta, hence when your character jumps it always travels the same horizontal distance to the place where it hits the ground, no matter what the FPS.
To solve this you have to take a closer look at the equation of motion under constant acceleration:
y(t) = y(t=0) + v(t=0)*t - (1/2)*a*t^2
The choice of t=0 is arbitrary since laws of physics are invariant under time shifts, so one may take t=0 to be the beginning of the update interval and then t=delta_time would give the position after the current update. The correct update algorithm as follows:
x += speed_x*delta_time;
if (is_in_air) {
y += (speed_y - 0.5*acceleration*delta_time)*delta_time;
speed_y -= acceleration*delta_time;
}
Note that speed_y should be updated after the vertical position as per the values found in the equation of motion.

To determine the time when the angle between the clock hands is known in analog clock in android

I want to set time from the analog clock in an Android Application. For this I have overridden the Analogclock.java class and have established the Ontouchevent listener. I followed this method and this formula to calculate the angle between the hour and the minute hand from the obtained Coordinates. Now I'm able to move the hand to a new position. And I can also fetch the new angle between the needles from this. This is the code for the same :
case MotionEvent.ACTION_MOVE:
x = (int)event.getX();
y = (int)event.getY();
double dx = x - minuteRect.centerX();
double dy = -(y - minuteRect.centerY());
double inRads = Math.atan2(dy,dx);
if (inRads < 0)
inRads = Math.abs(inRads);
else
inRads = 2*Math.PI - inRads;
double newDegree = Math.toDegrees(inRads);
if(isMove()){
setAngle(newDegree);
invalidate();
}
I now want to set the time where the needle is being moved.
Is there any way I can calculate the time from the Coordinates or from the angle between the two needles?
I don't know the code, but the math is not hard:
Divide the angle of the hour hand by 2PI, multiply by 12 and truncate, and you have the hours.
Divide the angle of the minute hand by 2PI, multiply by 60 and truncate, and you have the minutes.
Example : 06:15:
The hour angle is a little bit more than PI. (PI / 2PI) * 12 = 6
The minute angle is PI/2. ((PI/2) / 2PI) * 60 = 15

Moving between co-ordinates, Java Algorithms

Ok this question is going to be a little abstract.
I have an icon moving along a line which is represented by a series of coordinates stored in a vector, and I am iterating through them. The distance between coordinates is variable. So sometimes the icon will move slowly and smoothly, and others it will jump several 100 pixels at a time.
I am having trouble coming up with an algorithm to split up each set of coordinates it must travel between into a set of relative coordinates where the number is based on size, so that transition is smooth no matter how many co-ords are on a single line.
Any ideas would be much appreciated. Thanks :)
Take a look at this discussion of the Main Game Loop.
And here's a quote from that page:
At this step, updates to all the
objects in the game world are
calculated and performed. Usually, a
time step value is passed to all of
the update methods indicating how much
time has passed since the last update
...
You need to know 3 things:
how much time has elapsed since you last updated the position of your object?
what is the rate of movement of your object?
what is the direction (usually represented as a Ray) your object is moving?
From these, you can calculate the current position of the object.
If you want the object to move at a constant speed, I'd suggest a time-based model, where your object is actually moving at a speed (pixels/second). You can still get it to hit every point(ish) if you spline along a curve (such as a catmull-rom curve).
So you want to move from a initial point (x0/y0) to a end point (x1/y1) along a line by a variable number of steps but with a maximum distance for each step?
This could be done by something like this:
int stepdist = 10; // max pixels per step
double xdiff = x1 - x0;
double ydiff = y1 - y0;
double dist = sqrt( xdiff * xdiff + ydiff * ydiff );
int steps = (int) ( ( dist - 1 ) / stepdist );
if( steps > 0 )
{
xdiff /= steps;
ydiff /= steps;
while( --steps >= 0 )
{
x0 += xdiff;
y0 += ydiff;
moveTo( (int) x0, (int) y0 );
}
}
moveTo( (int) x1, (int) y1 );

Categories