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
So, right now I am trying to calculate the angles of a right triangle using the inverse of Cosine. However, I don't really know how to do it. I know the equation, just not how to convert into code. The equation would be:: Cos-1(A/C); However, that does not seem to work in Java. I also tried
angleX = (int) Math.acos(sideC / sideA);
If sideC and sideA were integers, one would have integer division (2 / 3 == 0).
If you do not expect a result in radians, but degrees, a conversion is needed.
As double is an approximation, use round too.
if (sideA == 0) { ... }
angleX = (int) Math.round(
Math.toDegrees(Math.acos(((double)sideC) / sideA)));
Apollonian gaskets = They are planar fractals generated from triples of circles, where each circle is tangent to the other two. In his drawing of the gasket, we start with two externally tangent circles which diameter is D1 and D2. Then we add a third circle which diameter is D1+D2 and to which the two original circles are internally tangent. This is the first generation of circles.
Each subsequent generation of circles is constructed by applying the following scheme:
For any three circles A, B C of any previous generations which are tangent to each other a new circle is constructed which is tangent to A,B,C. The new circle must differ from all circles constructed so far. When a generation is complete, i.e no other circle can be added, then the next generation of circles can start being constructed.
There is an additional stopping rule which prevents from generating infinitesimally small circles. A circle can be added to the gasket if and only if the lenght of its diameter is least minD which is a fixed positive value.
Input consists of one line with three decimal numbers D1, D2 and minD. The number are separated by spaces. The format is usual decimal format (see also the examples bellow) with no exponent part.
It holds that 1.0 ≤ D1, D2 ≤ 1000.0, 0.001 ≤ minD ≤ D1+D2.
Ouput consists of one text line containing two decimal numbers L1 and L2. L1 represents the sum of areas of all circles in the gasket except for the bigggest circle. L2 represents the sum of perimeters of all circles in tin the gasket except for the bigggest circle. Both output values are rounded to 6 decimal digits. Decimal digits must be always present in the output even if some of them are zeros.
Maximim output value is less than 107.
Input
17.000000 40.000000 1.000000
Output
2439.258588 835.263228
2
For given D1 and D2, I create this two circles like this (first iteration):
double D1 = 17.00;
double D2 = 40.00;
double minD = 1.00;
int i = 250, j = 350;
comp.addCircle(i, j, (int) D2, randomColor);
comp.addCircle(i + (int) D2 / 2 + (int) D1 / 2, j, (int) D1, randomColor);
comp.addCircle(i + (int) D1 / 2, j, (int) (D1 + D2), randomColor);
UPDATE:
So, solution is based on Descartes' theorem. We well work with radius, not diameter, and Curvature, with is 1/r.
We will use double for all calculation, but if you work with significantly small numbers, I would prefer BigDecimal. It will slow algorithm, and you should use external method for finding square root, because BigDecimal doesn't have any.
For given D1, D2, minD we modify code above for efficiency:
Some preparation:
double D1 = sc.nextDouble() / 2;
double D2 = sc.nextDouble() / 2;
minD = sc.nextDouble() / 2;
double D3 = D1 + D2;
So, first step looks like this:
Next step looks a little bit more complicated.
Assume we want to write a recursion to solve this problem, and according to Descartes' theorem, for given curvatures of three circles, tangent to each other, (pic. below)
, we could find curvatures of two circles, but for our purposes, we need only small one, so, we can simplify formula to
this.curve = a.curve + b.curve + c.curve + 2 * Math.sqrt(Math.abs(a.curve * b.curve + a.curve * c.curve + b.curve * c.curve));
Lets take a look at Apollonian gaskets again: try to play with it.
See? It is same gaskets, but with different start condition. And whats more important for us, is that it is symmetrical! So, we will calculate just a half, and then multiply result by two!
Lets write a recursion! Inputs will be curvatures of three circles. No output, we will use change our global variables.
double radius_sum = 0.0;
double square_radius_sum = 0.0;
void createAG(double a, double b, double c){
double n = a + b + c + Math.sqrt(a*b + a*c + b*c + 4.0);
if ((minD * n) < 1){
radius_sum += 2. / n; //Remember about symmetry?
square_radius_sum += 2. * (1. / n) * (1. / n); //Remember about symmetry?
createAG(a, b, n);
createAG(a, c, n);
createAG(b, c, n);
}
}
To find the result, we will use formulas to calculate area and perimeter of circle.
Perimeter is length of circumference and equal to .
Area is equal to , as you already know, because we already calculated it in previous step, otherwise we had to store every radius and do more calculations.
radius_sum = 2 * Math.Pi * radius_sum;
square_radius_sum = Math.Pi * square_radius_sum;
But we forget about our first two circles! Let's fix it!
radius_sum += D1*2 + D2*2;
square_radius_sum += D1*D1 + D2*D2;
radius_sum = 2 * Math.Pi * radius_sum;
square_radius_sum = Math.Pi * square_radius_sum;
And there is always a room for improvement. For example, to use IEEE 754 in better way, I assume you will use 1. / x instead of 1 / x.
Thank you!
P.S. Copyright! This task (text and first picture of Apollonian gasket) is created by teachers at CTU, for course ALG. Picture of formulas is from Wikipedia. Everything else is public domain, if not patented, registered e.t.c.
So, solution is based on Descartes' theorem. We well work with radius, not diameter, and Curvature, with is 1/r.
We will use double for all calculation, but if you work with significantly small numbers, I would prefer BigDecimal. It will slow algorithm, and you should use external method for finding square root, because BigDecimal doesn't have any.
For given D1, D2, minD we modify code above for efficiency:
Some preparation:
double D1 = sc.nextDouble() / 2;
double D2 = sc.nextDouble() / 2;
minD = sc.nextDouble() / 2;
double D3 = D1 + D2;
So, first step looks like this:
Next step looks a little bit more complicated.
Assume we want to write a recursion to solve this problem, and according to Descartes' theorem, for given curvatures of three circles, tangent to each other, (pic. below)
, we could find curvatures of two circles, but for our purposes, we need only small one, so, we can simplify formula to
this.curve = a.curve + b.curve + c.curve + 2 * Math.sqrt(Math.abs(a.curve * b.curve + a.curve * c.curve + b.curve * c.curve));
Lets take a look at Apollonian gaskets again: try to play with it.
See? It is same gaskets, but with different start condition. And whats more important for us, is that it is symmetrical! So, we will calculate just a half, and then multiply result by two!
Lets write a recursion! Inputs will be curvatures of three circles. No output, we will use change our global variables.
double radius_sum = 0.0;
double square_radius_sum = 0.0;
void createAG(double a, double b, double c){
double n = a + b + c + Math.sqrt(a*b + a*c + b*c + 4.0);
if ((minD * n) < 1){
radius_sum += 2. / n; //Remember about symmetry?
square_radius_sum += 2. * (1. / n) * (1. / n); //Remember about symmetry?
createAG(a, b, n);
createAG(a, c, n);
createAG(b, c, n);
}
}
To find the result, we will use formulas to calculate area and perimeter of circle.
Perimeter is length of circumference and equal to .
Area is equal to , as you already know, because we already calculated it in previous step, otherwise we had to store every radius and do more calculations.
radius_sum = 2 * Math.Pi * radius_sum;
square_radius_sum = Math.Pi * square_radius_sum;
But we forget about our first two circles! Let's fix it!
radius_sum += D1*2 + D2*2;
square_radius_sum += D1*D1 + D2*D2;
radius_sum = 2 * Math.Pi * radius_sum;
square_radius_sum = Math.Pi * square_radius_sum;
And there is always a room for improvement. For example, to use IEEE 754 in better way, I assume you will use 1. / x instead of 1 / x.
Thank you!
P.S. Copyright! This task (text and first picture of Apollonian gasket) is created by teachers at CTU, for course ALG. Picture of formulas is from Wikipedia. Everything else is public domain, if not patented, registered e.t.c.
I have tried to convert a calculation from an app I made using MIT AppInventor which uses Kawa to Android using Java.The problem I'm facing is that the trigonometric parts of the calculation in Kawa are using degress.My question is how do I translate this calculation to Java and get the same output?
This is how I do the calculation is Kawa,all variables are of type double:
Tri 1=atan(Offset Depth/Offset Length)
Mark 1=sqrt(Offset Length^2+Offset Depth^2)
Tri 2=(180-Tri1)/2
Mark 2=Duct Depth/(tan(Tri 2))
Then I did my best to translate it to Java code,the variables are double also as above,depth,length and duct depth are user input values.
tri1 = Math.atan(offsetDepth / offsetLength);
marking1 = Math.sqrt(Math.pow(offsetLength,2) + Math.pow(offsetDepth,2));
tri2 = (180 - tri1) / 2;
marking2 = ductDepth / Math.tan(tri2);
Screenshot of what the inputs and outputs look like:
You can use Math.toRadians() to convert degrees to radians.
You can convert the angles to radians yourself.
As we know:
180 degrees = PI radians
So:
1 degree = PI / 180 radians
So wherever you have X degrees,
they are equal to (X * PI / 180) radians.
In Java you have
Math.PI
which defines the value of the PI number.
Just change your Java code to this:
tri11 = Math.atan(1.0 * offsetDepth / offsetLength); // tri11 is radians
tri1 = tri11 * 180.0 / Math.PI; // tri1 is degrees
marking1 = Math.sqrt(Math.pow(1.0 * offsetLength,2) + Math.pow(1.0 * offsetDepth,2));
tri2 = (180.0 - tri1) / 2.0; // tri2 is degrees
tri22 = tri2 * Math.PI / 180.0; // tri22 is radians
marking2 = 1.0 * ductDepth / Math.tan(tri22);
// output whatever you like now
So I'm trying to calculate my bmi using the following method.
double bmi = weight / ((height * 100) * (height * 100));
bmi = Math.round(bmi * 100.0) / 100.0;
From the first line I get an answer that looks like this:
2.3457310760477412E-7
which is why I want to round this to one or two decimals. But this results in bmi being 0.0 instead.
I have also tried decimalformat which also returns 0. What am I doing wrong?
EDIT - SOLUTION
The problem was my formula! Centimeter should be divided by 10 not multiplied!
Thanks!
//André
The number you are getting from your first line, 2.3457310760477412E-7 is already kinda small. It is roughly equal to 2.345/10000000 or 0.00000023457. And this is very close to zero. Math works as expected, rounding the number to the closest integer - 0.
The error is either in the input variables or in the fomula you are using. Maybe you have your height given in centimeters instead of meters?
double weight = 89.0;
double height = 169.0;
double bmi = (weight / ((height * height) / 100)) * 100;
To clarify, weight and height are metric (KG/CM) - you need to convert the height in CM to meters (so you divide by 100) then the output is multiplied by 100 to give the BMI.