How to calculate pace with minute / km - java

Im developing an app that needs to calculate the avg pace according to the speed of the distance traveled.
I have this method that returns the distance while I'm walking
private float calculateDistance(LinkedList<LatLng> points) {
float totalDistance = 0f;
for (int i =0; i < points.size() -1; i++ ){
LatLng pointA = points.get(i);
LatLng pointB = points.get(i + 1);
float[] results = new float[3];
Location.distanceBetween (pointA.latitude, pointA.longitude, pointB.latitude, pointB.longitude, results);
totalDistance += results[0];
}
return totalDistance;
}
Now, I have the time traveled for that distance, so calculating speed would be like s = distance / time but now I have a concern.
How can I calculate the pace speed in order to be changing depending on the avg speed of the current trayectory.
What I mean is this, If I start an acticity lets say for walking, how can I get the information that Im making a kilometer every 10 minutes while Im walking
I saw runkeeper and they calculate it while you are walking, so if you walk a couple of blocks it will tell you that your pace is like 10 minutes/km
How can I accomplish something like this ? or what is the formula to calculate it ?
thanks

Its just the inverse. Time/distance.

you just 1/(Minute/Km)=Km/Minute

Related

Minecraft modding change direction of player gradually

For a Minecraft project, I wanted to make the player face (0, 60, 0) gradually. So far, everything I have tried seems to fail when the player moves more than 720° around (0, 60, 0).
Anyone have an idea on how to make the camera move seamlessly to (0, 60, 0)?
Thank you!
Here is my code so far (that runs in a loop when toggled):
int x = 0;
int y = 60;
int z = 0;
player = Minecraft.getMinecraft().thePlayer;
double dirx = player.posX - 0;
double diry = player.posY - 60;
double dirz = player.posZ - 0;
double len = Math.sqrt(dirx*dirx + diry*diry + dirz*dirz);
dirx /= len;
diry /= len;
dirz /= len;
double pitch = Math.asin(diry);
double yaw = Math.atan2(dirz, dirx);
//to degree
pitch = pitch * 180.0 / Math.PI;
yaw = yaw * 180.0 / Math.PI;
yaw += 90f;
if(yaw > player.rotationYaw) {
player.rotationYaw++;
} else if(yaw < player.rotationYaw) {
player.rotationYaw--;
}
This code without the if statement works properly. The yaw and pitch variables are in degrees.
What I am having trouble with is the fact that whenever I turn around (0, 60, 0) for a few times, the screen suddenly does a 360° turn, for no apparent reason.
This is a common problem. Or rather, the problem that people have commonly is they want to do "something across time" and don't know how to make it go "across time."
You need to lerp the camera a small distance each tick until the desired direction is achieved. You either need to:
a) create an event handler and subscribe to one of the TickEvents (pick an appropriate one, and then make sure to pick a phase, either Phase.START or Phase.END, or your code will run multiple times a frame).
b) in whatever method your code is already in (Note: this code must already be called once a tick) and do the lerping there.
Don't know how to calculate lerp? Stack Overflow already has that answered.

Char movement, getting x/y speeds from 2 points

So i'm trying to make a program in java and i need to figure out how much I should add to x and y to make the player movement a constant speed at any angle. The information i have is 2 points, a starting point and an and and I need the char to move from a to b at a constant speed. I'm currently trying to figure out a bunch of different Math methods but I just cant get it right. Thanks in advance.
It's actually quite simple. You have points A (A.x, A.y) and B (B.x, B.y) and need the update for your character position.
Start by calculating the direction vector dir = B - A (subtract component-wise, such that dir.x = B.x - A.x; dir.y = B.y - A.y).
If you add this entire vector to your character's position, you will move it by sqrt(dir.x^2 + dir.y^2) (Pythagorean theorem). Hence, the speed will be: speed = sqrt(dir.x^2 + dir.y^2) / frameTime.
So if you want a constant speed, you have to find a multiple of the direction vector. This will be:
update = dir * speed / sqrt(dir.x^2 + dir.y^2) * frameTime
characterPosition = characterPosition + update
Don't bother with angle calculations. Vector arithmetic is usually way more robust and expressive.
Mathematically (I won't provide code, sorry), assuming you can move in any direction on a two dimensional plane, from the top of my head it could be something like this (taken from old school geometry):
Having a speed, let's say 20 pixels per second (it could also be any other unit you chose, including in-game distance)
Having a polling system, where you have 2 main variables: the last known coords for the char (point A: Ax, Ay), the time of the last known update.
Having the time of the current update.
Having the coords for the destination (point B: Bx, By).
Figure out the current position of your character, which could be done like this (without converting from cartesian to polar coord system):
Figure out angle of movement: find the deltas for X and Y (Dx=Bx-Ax and Dy=By-Ay respectively), and use tangent to find the angle where Angle = tan-1(Dy/Dx).
Figure out the travelled distance (TD) from last poll to current poll where TD = speed * elapsed time
Figure out the coords for the new position (Cx and Cy) using sine and cosine, where travelled X is Tx=TD*sin(Angle) and travelled Y is Ty=TD*cos(Angle).
Now add the travelled distances to your original coords, and you get the current position. Where Cx=Ax+Tx and Cy=Ay+Ty.
How "smooth" movement is depends highly on the quality of your polling and somehow also on rounding for small distances.
Since u didn't provide us code I can just guess what exactly you are trying.
So I'll start with some basics.
I guess you are not just trying to make a program
but the basic movement of an 2d based game engine.
However a constant moving is based of an update method
that reads the player input about 30 times while rendering.
Example from my Projects:
public void run() {
boolean isRunning = true;
long lastNanoTime = System.nanoTime(),nowNanoTime = System.nanoTime();
final double secondAsNano = 1000000000.0;
final double sixtiethOfSecondAsNano = secondAsNano / 30.0;
int delta = 1;
while(isRunning){
nowNanoTime = System.nanoTime();
if(delta * sixtiethOfSecondAsNano + lastNanoTime < nowNanoTime){
update();
delta++;
if(delta == 30){
delta = 1;
lastNanoTime = nowNanoTime;
}
}
render();
}
}
public update(){
if(Input.moveUP) setPlayerY(getPlayerY() - 0.2);
if(Input.moveDOWN) setPlayerY(getPlayerY() + 0.2);
if(Input.moveRIGHT) setPlayerX(getPlayerX() + 0.2);
if(Input.moveLEFT) setPlayerX(getPlayerX() - 0.2);
}
I just cut it down to be easy readable so it might not work correct but it should explain you how its basically done.
I ended up figuring this out almost an hour after posting this. Sorry that my question was so vague, what I was looking for was the math behind what i was trying to do not the code itself but thanks to people who answered. Here is the solution I came up with in code :
if (q.get(0)[0][0] > q.get(0)[1][0]) {
if(q.get(0)[0][0] == q.get(0)[1][0]) {
currentLocation[0] -= 5 * Math.cos((Math.atan(((double) q.get(0)[0][1] - (double) q.get(0)[1][1]) / ((double) q.get(0)[0][0] - (double) q.get(0)[1][0]))));
currentLocation[1] += 5 * Math.sin((Math.atan(((double) q.get(0)[0][1] - (double) q.get(0)[1][1]) / ((double) q.get(0)[0][0] - (double) q.get(0)[1][0]))));
}
else{
currentLocation[0] -= 5 * Math.cos((Math.atan(((double) q.get(0)[0][1] - (double) q.get(0)[1][1]) / ((double) q.get(0)[0][0] - (double) q.get(0)[1][0]))));
currentLocation[1] -= 5 * Math.sin((Math.atan(((double) q.get(0)[0][1] - (double) q.get(0)[1][1]) / ((double) q.get(0)[0][0] - (double) q.get(0)[1][0]))));
}
} else {
if(q.get(0)[0][0] == q.get(0)[1][0]) {
currentLocation[0] += 5 * Math.cos((Math.atan(((double) q.get(0)[0][1] - (double) q.get(0)[1][1]) / ((double) q.get(0)[0][0] - (double) q.get(0)[1][0]))));
currentLocation[1] -= 5 * Math.sin((Math.atan(((double) q.get(0)[0][1] - (double) q.get(0)[1][1]) / ((double) q.get(0)[0][0] - (double) q.get(0)[1][0]))));
}
else{
currentLocation[0] += 5 * Math.cos((Math.atan(((double) q.get(0)[0][1] - (double) q.get(0)[1][1]) / ((double) q.get(0)[0][0] - (double) q.get(0)[1][0]))));
currentLocation[1] += 5 * Math.sin((Math.atan(((double) q.get(0)[0][1] - (double) q.get(0)[1][1]) / ((double) q.get(0)[0][0] - (double) q.get(0)[1][0]))));
}
}
I figured out a way to get the result I wanted though I probably over complicated it. q is an ArrayList that holds 2d arrays that are 2x2 [a/b][x/y]. and currentLocation a 2 index array that's just [x/y]. The result is the affect I wanted where it draws a line in (X units) a pass from point a to b in any direction at the same speed. This question was poorly worded and i'm sorry for wasting peoples time.

Detect swipes algorithm?

I want to detect from some 2D points whenever a swipe is made.
The points are coming continuously, they come from a sensor. And are in 2D space, x and y.
Are there any algorithms for this?
I've tried something like this
float totalDistance = 0f;
float totalTime = 0f;
for (int i = points.size - 1; i > 0; i--) {
SwipePoint point1 = points.get(i); // last point added
SwipePoint point2 = points.get(i - 1); // second last point
totalDistance += point1.distance(point2);
if (totalDistance > MIN_SWIPE_DISTANCE
&& totalTime > MIN_SWIPE_TIME) {
// we have a swipe
listener.onSwipe(SwipeType.DOWM, 1f);
points.clear();
return;
}
}
Here i check if the length of the lines is bigger than a constant, and the same for the time, but is not showing anything.
Are there any algorithms for this?
Thanks.
Your algorithm does not seem to identify swipe, and one of the problems is in this line:
totalDistance += point1.distance(point2);
what it does it count total length traveled by a finger and will trigger a "swipe" even if finger travels for long enough with any trajectory.
What you should do is record x and y coordinates of a first point and when you encounter a point that is far enough from a start you can trigger a swipe.
The second problem in your algorithm is that you should check if swipe time is less than maximum swipe time. Also, you doesn't seem to update totalTime anywhere in your code.
The code should look like this (checking only vertical swipe):
SwipePoint startPoint = points.get(points.size - 1);
for (int i = points.size - 2; i > 0; i--) {
SwipePoint point = points.get(i); // last point added
int yDiff = Math.abs(startPoint.getY() - point.getY());
long totalTime = startPoint.getTime() - point.getTime();
if yDiff > MIN_SWIPE_DISTANCE
&& totalTime < MIN_SWIPE_TIME) {
// we have a swipe
listener.onSwipe(SwipeType.DOWM, 1f);
points.clear();
return;
}
}

Frame rate independent gravity

I am having an issue with gravity varying severely with frame rate shifts. When I run at 160 fps, my player jumps a few meters in the air then falls, but at about 10 fps, my player jumps half a meter then falls. My code for gravity is as follows:
public void fall(long delta) {
float increase = acceleration * ((delta) / 1000000000); //changes delta time (nanoseconds) to seconds
if(player.y + velocity + increase < -1.15f) {
if(velocity + inc < terminal_velocity) {
velocity += inc;
}
player.y += velocity;
}else{
player.y = -1.15f;
velocity = 0;
}
}
And where I call it:
while(!close_request) {
now = getTime();
int delta = getDelta(now);
player.fall(delta);
........other functions.........
}
I thought implementing the delta would keep the player from changing velocity too fast or too slow, but it actually made it a bit worse. I think this is due to the fact that as the time between frames increases, so does the increase in velocity which causes the player to fall abnormally fast. This comes from the fact that as the FPS increases, the player jumps much, much higher. Any ideas?
Your problem is in this line:
player.y += velocity;
which fails to take into account that velocity is "distance divided by time".
You're correctly modelling acceleration:
v = u + a * t // v = current velocity, a = acceleration, t = time
but not distance, which for small enough delta is:
delta_s = v * delta_t
You need to multiply velocity by delta before adding it to to the position.
You are not modeling the physics correctly. Assuming dt is small enough this will provide a "good enough" approximation.
curV // current velocity
accel // global acceleration constant
terminal // terminal velocity for object
dt // delta time in seconds
fall(dt):
deltaV = accel * dt // Change in velocity in a vacuum
newV = curV + deltaV // New velocity
if (newV < terminal) newV = terminal // Don't exceed downwards terminal velocity
y = y + dt * (curV+newV)/2 // New position
curV = newV // Save new velocity as current
It ignores the complexities of things like acceleration decreasing as you approach terminal velocity. The big difference between this and yours is the appearance of dt twice, once in calculating deltaV and then again in calculating the new vertical position.

Divide a 2D path created from points XY into equal chunks Java

I have an array of points A,B,C,D,E...N which when connected make a path.
How can i divide this path to equal chunks and get position of each chunk XY ?
EDIT : As user Hedja suggested i have created function to process this problem, but i cannot detect situation where chunk is splitted on two subpaths
public ArrayList<PointF> getPositions(ArrayList<PointF> mInput,float mChunkSize){
ArrayList<PointF> mResult = new ArrayList<PointF>();
float mModulo = 0f;
for (int i = 0;i<mInput.size()-1;i++){
//distance to next
float mDistanceAB = MyGameMath.distance(mInput.get(i).x, mInput.get(i).y,mInput.get(i+1).x,mInput.get(i+1).y);
//how many parts will fit
float mCountParts = (float) (mDistanceAB/mChunkSize); //how much parts will fit
//if distance is greater than chunk size
if (Math.abs(mDistanceAB)>=mChunkSize) {
Log.i("Chunk","Index "+(i)+" -> "+(i+1)+" = "+mCountParts+", rest="+mModulo);
float dx = mInput.get(i+1).x-mInput.get(i).x;
float dy = mInput.get(i+1).y-mInput.get(i).y;
float ux = dx/mDistanceAB;
float uy = dy/mDistanceAB;
for (int y=0;y<=mCountParts;y++){
//for every part
float nx = mInput.get(i).x+ux*mChunkSize*y;
float ny = mInput.get(i).y+uy*mChunkSize*y;
//Log.i("Chunk","at:"+nx+","+ny);
mResult.add(new PointF(nx, ny));
}
}
mModulo = mDistanceAB%mChunkSize; //how much left from previous subpath
}
return mResult;
}
So I assume you have something similar to this where Point is an object with attributes x and y.
Point[] points = new Points[]{ //Your Points }
List<Point> chunkedPoints = new ArrayList<Point>();
I also assume by "equal chunks" you mean the distance of each path.
First you'll iterate through the array, as you won't need to calculate the "next point" after the last point, you can add it at the end.:
for(int i = 0; i < points.length-1; i++) { //Skip the last element
//chunking here
}
chunkedPoints.add(points[points.length-1]); //Add the last element
You'll need to find the Unit Vector, that is, the direction you travel to get to the next point. So first you need to get the difference in x and y from one point and the next:
double dx = point[i].x - point[i+1].x;
double dy = point[i].y - point[i+1].y;
Then the distance from that point to the next (simple Pythagoras):
double distance = Math.sqrt(dx*dx+dy*dy);
The unit vector can now be calculated
double ux = dx/distance;
double uy = dy/distance;
So now you know where to travel, you need to specify how far you want to travel along it, I'll call this CHUNK_SIZE.
double nx = point[i].x + ux*CHUNK_SIZE;
double ny = point[i].y + uy*CHUNK_SIZE;
nx and ny is the co-ordinate of your new point. However, you need to check if you've passed the next point so that you can stop. Your problem doesn't specify what you do when you reach an end of a subpath without travelling the chunk size so I'll assume you simply stop at it, so the code becomes:
double nx = point[i].x;
double ny = point[i].y;
for(
//This part can be tidier
int count = 0;
count < CHUNK_SIZE && nx+ux != points[i+1].x && ny+uy != points[i+1].y;
count++
) {
nx += ux;
ny += uy;
}
Point newPoint = new Point(nx, ny);
Now you have your new Point, you can start from there, aim for the same point as before or if it's the same as the next point, start from the point after that. So your loop is now something like
chunkedPoints.add(points[0]);
for(int i = 0; i < points.length-1; i++) { //Skip the last element
Point newPoint;
do {
//chunking
newPoint = new Point(nx, ny);
chunkedPoints.add(newPoint);
} while(!newPoint.equals(points[i+1]));
}
chunkedPoints.add(points[points.length-1]); //Add the last element
Hope that helped.
I haven't tested this, but I've done something very similar in the past, so it should work.
EDIT: Okay, I've seen your edit and honestly have no idea what your question is asking. Sorry.

Categories

Resources