I'm trying to create a program in Java to calculate the inside angles of any triangle when the user inputs the side lengths. I've seen a few questions similar to this but I can`t get mine to work.
I want this to calculate the angle in degrees but it keeps giving me the wrong answer or not a number (NaN). I've tried putting it all in to one equation in case it was just rounding errors but it just gave the same answer. I've since put it back into this format to make it easier to read.
public class Triangles
{
// variables already declared and user inputs double sideOne, sideTwo, sideThree
threeSq=sideThree*sideThree;
twoSq=sideTwo*sideTwo;
oneSq=sideOne*sideOne;
public static double getAngleOne(double oneSq, double twoSq, double threeSq, double sideOne, double sideTwo, double sideThree)
{
double angOne;
angOne = (oneSq + twoSq - threeSq) / (2 * sideOne * sideTwo);
angOne = Math.toRadians(angOne);
angOne = Math.acos(angOne);
angOne = Math.toDegrees(angOne);
return angOne;
}
public static double getAngleTwo(double oneSq, double twoSq, double threeSq, double sideOne, double sideTwo, double sideThree)
{
double angTwo;
angTwo = (twoSq + threeSq - oneSq) / (2 * sideTwo * sideThree);
angTwo = Math.toRadians(angTwo);
angTwo = Math.acos(angTwo);
angTwo = Math.toDegrees(angTwo);
return angTwo;
}
public static double getAngleThree(double oneSq, double twoSq, double threeSq, double sideOne, double sideTwo, double sideThree)
{
double angThree;
angThree = (oneSq + threeSq - twoSq) / (2 * sideOne * sideThree);
angThree = Math.toRadians(angThree);
angThree = Math.acos(angThree);
angThree = Math.toDegrees(angThree);
return angThree;
}
}
I`m using the cosine law, but it is not giving me the correct answer. For example, when I input the side lengths as 3, 3 and 3 it gives me 71.68993312052173; when I input 5, 6 and 7 (sides 1, 2 and 3 respectively), I get NaN.
edit:
Thanks for the advice, I have changed all the ints to doubles and my math was the problem (forgot brackets around the oneSq + twoSq - threeSq)
I put up the full revised code but it is still giving the wrong answer, for a triangle with all sides the same, it should return 60 for all three but it`s returning 89.49999365358626.
After correcting the computation of the ratios there still remains one thing to do: Lose the lines
angOne = Math.toRadians(angOne);
at this point, angOne does not contain any angle. If the sides obey the triangle inequality, angOne should at that point contain a number between -1 and 1 that does not need converting.
The ratio of the areas for an equilateral triangle is 0.5. The operations convert-to-radians, acos, convert-to-degrees can be combined as
M*acos(x/M) = M*(pi/2-asin(x/M)),
with the multiplier M=180/pi. Since x/M is small, the result is approximately
M*(pi/2-x/M)=90-x,
resulting in a value close to 89.5, as obtained in your last trial.
Of course, the desired result is M*acos(0.5)=M*(pi/3)=60.
Apart from not using double values, your calculations are probably not correct.
According to cosine law
cosγ = (a^2 + b^2 - c^2)/2ab
so change ang = oneSq + threeSq - twoSq / (2 * sideOne * sideThree); to
double ang = (oneSq + twoSq - threeSq)*1.0 / (2 * sideOne * sideTwo);
Related
In Part 1 of a prompt, I am expected to integrate an equation into Java to get the value for a period (T). The equation is as follows: T = FS / (440 * (2 ^(h/12))
NOTE:
FS = sample rate, which is 44100 / 1.
h = halfstep, which is provided by the user.
An example of this equation is: 44100 / (440 * (2 ^(2/12)) = 89.3
The code I wrote is as follows:
public static double getPeriod(int halfstep) {
double T = 100; // TODO: Update this based on note
double FS = 44100 / 1;
double power = Math.pow(2, (halfstep / 12));
double denominator = 440 * (power);
double result = (FS) / (denominator);
T = Math.round(result);
return T;
}
// Equation test.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("halfstep is: ");
int halfstep = in.nextInt();
double period = getPeriod(halfstep);
System.out.print("Period: " + period + " ");
}
But when I run through this code with h = 2, T = 100.0 instead of the anticipated 89.3 and I am not sure what the issue is. Any thoughts on what's going on?
Because halfStep is an int, when you write
(halfstep / 12)
the calculation is done by taking halfStep / 12 and rounding down to the nearest integer. As a result, if you plug in 2 here, then halfStep / 12 will come back as 0 instead of 1/6. That's messing up the computation and is likely what's giving you the wrong answer.
You have a few options for how to proceed here. One would be to change halfStep to be a double rather than an int. Another would be to rewrite the division as
halfStep / 12.0
which, since 12.0 is a double literal, will perform the division in the way you intend.
One other potential issue - you declare the variable T as 100.0, but never use T anywhere in the calculation and ultimately overwrite it before returning it. I'm not sure whether this is intentional or whether that indicates that one of the formulas is incorrect.
Hope this helps!
In a problem that I am practicing, the goal is to write the quadratic expression, then round it to the thousandths place. Here is the desired output:
1(a variable) 6(b variable) 3(c variable)
4(a variable) 10(b variable) 6.1(c variable)
Output:
-0.551, -5.449 (answer for top line)
-1.056, -1.444 (answer for bottom line)
The question is not about how to solve the problem, but instead the answers that I am getting. When computing the quadratic equation as follows:
double a = scan.nextDouble();
double b = scan.nextDouble();
double c = scan.nextDouble();
//equation is correct
double answer1 = 0.001 * Math.floor((-b + Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a)* 1000.0) ;
double answer2 = 0.001 * Math.floor((-b - Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a) * 1000.0);
The answers I am getting are correct, except when I start the rounding to the thousandths place, some numbers are right and others are not even though it looks like they are rounding correctly just not according to the problem.
My Output:
-0.551, -5.45
-1.057, -1.444
Is this something to do with how I am rounding? Any help on understanding this rounding issue would be appreciated :)
https://floating-point-gui.de/languages/java/
How to Round
To get a String:
String.format("%.2f", 1.2399) // returns "1.24"
String.format("%.3f", 1.2399) // returns "1.240"
String.format("%.2f", 1.2) // returns "1.20"
To print to standard output (or any PrintStream):
System.out.printf("%.2f", 1.2399) // same syntax as String.format()
If you don’t want trailing zeroes:
new DecimalFormat("0.00").format(1.2)// returns "1.20"
new DecimalFormat("0.##").format(1.2)// returns "1.2"
If you need a specific rounding mode:
new BigDecimal("1.25").setScale(1, RoundingMode.HALF_EVEN); // returns 1.2
And if you do need to round the actual number not just the printed output:
double result = Math.round(value * scale) / scale;
where scale might be fixed at 1000 for three decimal places or calculated for an arbitrary number of decimal places:
int scale = (int) Math.pow(10, precision);
I am little bit lost with double decimal point at the moment.
I have basically two methods, which will set the values for double amount and double receive. Then another integer variable where I would like to set the (receive - amount) * 100.
For example if I have two double values and I want to set their difference to an int value, then would it be possible?
My problem is that if I try to find the difference between two values, then e.g. (10.0- 9.40), then it will be 0.599999999. How can I get 0.60 out of it inside the method and use it? I know how to use NumberFormat or DecimalFormat. Should I use one inside the method to set the number of decimal points?
you can round off the value im using a decimalformat to round off the number. You can pass a double variable inside the method and this will return a number rounded off to 2 decimal points.
double RoundTo2Decimals(double val) {
DecimalFormat df2 = new DecimalFormat("###.##");
return Double.valueOf(df2.format(val));
}
You can use BigDecimal to perform the rounding, or you can use maths like this. It basically multiplies by 100, rounds and divides by 100.
/**
* Performs a round which is accurate to within 1 ulp. i.e. for values very close to 0.5 it
* might be rounded up or down. This is a pragmatic choice for performance reasons as it is
* assumed you are not working on the edge of the precision of double.
*
* #param d value to round
* #return rounded value
*/
public static double round2(double d) {
final double factor = 1e2;
return d > WHOLE_NUMBER / factor || d < -WHOLE_NUMBER / factor ? d :
(long) (d < 0 ? d * factor - 0.5 : d * factor + 0.5) / factor;
}
Easiest solution could be below. Modifications and improvements are welcomed.
double x =10.0;
double y =9.40;
int xy =0;
DecimalFormat df = new DecimalFormat("#.##");
xy = (int) (Double.valueOf(df.format(x-y))*100);
System.out.println(xy);
I think I figured it out by using Math.round().
I will just ask whether my solution is a good or a bad idea to use? I am not just so familiar with BigDecimal. Long story short about the code. Example inputs are as: a = 9.40 and b = 10.0
private int difference;
private double amountDue;
private double receive;
public void setAmount(double a) {
amountDue = a;
}
public void receive(double b) {
receive = b;
difference = (int)Math.round(100 * (receive - amount));
I just needed to get int difference as 0.60 * 100 = 60, but as I mentioned before then just calculating the difference caused 0.59999999.
Just an extra question. Is it ok for me to initialize int balance variable inside one method as I have done?
This question already has answers here:
MySQL Great Circle Distance (Haversine formula)
(9 answers)
Closed 7 years ago.
I don't have all that much SQL experience and honestly don't have a clue where to go from here, most people that ask a question like this are using MS Server or something, and can use a bunch of parameters/values that I can't. I'm using MySQL.
Here's the code in Java I use to create a random location within X miles.
public static GeoPosition randomLocation(GeoPosition location, double radius) {
Random random = new Random();
// Convert radius from miles to meters
double meters = radius * 1609.34;
// Convert radius from meters to degrees
double radiusInDegrees = meters / 111300f;
double u = random.nextDouble();
double v = random.nextDouble();
double w = radiusInDegrees * Math.sqrt(u);
double t = 2 * Math.PI * v;
double x = w * Math.cos(t);
double y = w * Math.sin(t);
// Adjust the x-coordinate for the shrinking of the east-west distances
double new_x = x / Math.cos(location.latitude());
double foundLongitude = new_x + location.longitude();
double foundLatitude = y + location.latitude();
return new GeoPosition(foundLongitude, foundLatitude);
}
These GeoPositions (Groups of longitude/latitude) are stored in the database. However now I need to figure out how to get all of the rows in the database within a radius of X miles.
When writing this out in Java, the distanceBetween method looked like this:
public static double distanceBetween(GeoPosition a, GeoPosition b) {
double longDif = a.longitude() - b.longitude();
double distance =
Math.sin(deg2rad(a.latitude()))
*
Math.sin(deg2rad(b.latitude()))
+
Math.cos(deg2rad(a.latitude()))
*
Math.cos(deg2rad(b.latitude()))
*
Math.cos(deg2rad(longDif));
distance = Math.acos(distance);
distance = rad2deg(distance);
distance = distance * 60 * 1.1515; // Convert to meters
distance = distance * 0.8684; // Convert to miles.
return distance;
}
private static double rad2deg(double rad) {
return (rad * 180.0 / Math.PI);
}
private static double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
and I just had to loop through a collection to find all of the positions, where distanceBetween was true. However this seems like more work on the client that needs to be done.
Is there a proper way to handle returning all results within X miles of a latitude/longitude from the database? because returning every result from the server is going to become a bandwidth killer really fast.
Question marked as PHP as well, because that's what I'm going to be using to poll the database.
In your place I simply moved the distance calculation to the mysql side. Although your code is complex, the Haversine formula with it can be calculated, is not. Here you can see also mysql code examples for the calculation, it doesn't even need a stored function.
Unfortunately, this simple formula is already too complex to be indexable from mysql. This solution will solve your bandwidth killing problem, but maybe it will overload your mysql. It will depend on your query rate and the number of your positions.
In case of a mysql overload I suggest to ask this in a new question.
There is a stackexchange site for geographic information systems here.
This question is related to another stackoverflow discussion distance between long&lat points
Here is the code from the top voted answer:
/*
* Calculate distance between two points in latitude and longitude taking
* into account height difference. If you are not interested in height
* difference pass 0.0. Uses Haversine method as its base.
*
* lat1, lon1 Start point lat2, lon2 End point el1 Start altitude in meters
* el2 End altitude in meters
*/
private double distance(double lat1, double lat2, double lon1, double lon2,
double el1, double el2) {
final int R = 6371; // Radius of the earth
Double latDistance = deg2rad(lat2 - lat1);
Double lonDistance = deg2rad(lon2 - lon1);
Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
* Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double distance = R * c * 1000; // convert to meters
double height = el1 - el2;
distance = Math.pow(distance, 2) + Math.pow(height, 2);
return Math.sqrt(distance);
}
private double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
The top voted answer has the following comment:
"Why not Math.toRadians() instead of deg2rad()? It would be really self-containing."
I looked up the Math.toRadians() method in the documentation and noticed this:
"Converts an angle measured in degrees to an approximately equivalent angle measured in radians. The conversion from degrees to radians is generally inexact."
Is the top voted answer's deg2rad method more or less exact than the Math.toRadians() method?
Using the deg2rad method performs two arithmetic operations and one Math.Pi look up, its not clear how Math.toRadians() performs the convention. Assuming that this distance calculation may be performed frequently and quick response to user input is desired, which conversion method would scale more efficiently?
If the answer to question 1 is that the two methods have roughly the same inexactness/accuracy, I think that I would use Math.toRadians. Using Math.ToRadians makes the code more readable, and I assume that it would scale more efficiently as well.
Math.toRadians is implemented like this:
public static double toRadians(double angdeg) {
return angdeg / 180.0 * PI;
}
1) If there is a difference, it's negligible. Math.toRadians does the division first, while that answer does the multiplication first.
2) The only way to find out for sure is to test it, but I would expect that neither is faster since they both do the same thing.
In Java 9, the implementations of toRadians and toDegrees were changed to this:
public static double toRadians(double angdeg) {
return angdeg * DEGREES_TO_RADIANS;
}
public static double toDegrees(double angrad) {
return angrad * RADIANS_TO_DEGREES;
}
where DEGREES_TO_RADIANS and RADIANS_TO_DEGREES are literal constants. According to the following sources, this gives a 3-fold performance increase in a JMH micro-benchmark.
(We can also infer that the JIT compiler is not performing an optimization that is equivalent to the above. I presume that is because such an optimization could alter the computation's results. That would make it incorrect in general. The JIT compiler probably cannot make the judgement which way gives more accurate results, and it certainly cannot judge if accuracy ... or reproducibility ... is the most important criterion.)
The JDK bug database entries that relate to this are:
https://bugs.openjdk.java.net/browse/JDK-8051808
https://bugs.openjdk.java.net/browse/JDK-4477961
In summary, the answer for Java 9 and later is that the standard Math functions are faster than the alternative version. (Whether this was true in Java 8 and earlier is still untested ...)