# Trigonometric Functions Problem In Java

• 12-12-2011, 04:50 AM
javaBeaner
Trigonometric Functions Problem In Java
I have written a code that *should* solve an oblique triangle, meaning find all the remaining sides and angles, given two sides and an opposite. This is the ASS case, or the Ambiguous, and I tried to have this code solve triangles with none, one, or two solutions.

This program solves one-solution triangles well enough, but it encounters a slight error when no-solution triangles are presented and fails altogether when presented with two solution triangles. Also, for some reason, it appears that inputting decimal values seems to crash the program, even though all declared variables are doubles.

I use a simple GridBag organization system and tried to arrange the code in a simple arrangement for you guys to look at. If anyone could offer me any advice, I would be much obliged.

The code is below:

Code:

```/*This lab will find the area of any triangle, including oblique triangles, given the ambiguous case: two sides and an opposite angle.*/ import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.text.DecimalFormat; public class SolvingSSATriangles {         final static boolean shouldFill = true;         final static boolean shouldWeightX = true;         final static boolean RIGHT_TO_LEFT = false;                 static double A;         static double radA;         static double B;         static double B2;         static double radB;         static double radB2;         static String outputB;         static String outputB2;         static double C;         static double C2;         static double radC;         static double radC2;         static String outputC;         static String outputC2;         static double a;         static double b;         static double c;         static double c2;         static String outputc;         static String outputc2;         static double h;                 public static void main(String[] args) {                 String d1 = "#.0000";             final DecimalFormat df1 = new DecimalFormat(d1);                     JFrame frame = new JFrame("Solve the triangle SSA.");           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);           frame.setSize(1000, 200);           frame.setVisible(true);           frame.setLocationRelativeTo(null);                     JPanel panel = new JPanel();           panel.setLayout( new GridBagLayout ());           GridBagConstraints con = new GridBagConstraints();           if (shouldFill) {             con.fill = GridBagConstraints.HORIZONTAL;}           panel.setVisible(true);           frame.getContentPane().add(panel);                     final JTextField angleatext = new JTextField("Please enter one of the given angles (angle A) here.");           angleatext.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 0;           con.gridy = 1;           panel.add(angleatext, con);                     final JLabel anglealabel = new JLabel("Angle A:");           anglealabel.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 0;           con.gridy = 0;           panel.add(anglealabel, con);                     final JTextField sideatext = new JTextField("Please enter the given side (side a) opposite given angle here.");           sideatext.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 1;           con.gridy = 1;           panel.add(sideatext, con);                     final JLabel sidealabel = new JLabel("Side a:");           sidealabel.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 1;           con.gridy = 0;           panel.add(sidealabel, con);                     final JTextField sidebtext = new JTextField("Please enter the other given side (side b) here.");           sidebtext.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 2;           con.gridy = 1;           panel.add(sidebtext, con);                     final JLabel sideblabel = new JLabel("Side b:");           sideblabel.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 2;           con.gridy = 0;           panel.add(sideblabel, con);                     JButton button = new JButton("Press to solve the triangle.");           button.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 0;           con.gridy = 3;           panel.add(button, con);                     final JLabel angleblabel = new JLabel("Angle B.");           angleblabel.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 0;           con.gridy = 4;           panel.add(angleblabel, con);                     final JLabel angleclabel = new JLabel("Angle C.");           angleclabel.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 1;           con.gridy = 4;           panel.add(angleclabel, con);                     final JLabel sideclabel = new JLabel("Side c.");           sideclabel.setVisible(true);           con.fill = GridBagConstraints.HORIZONTAL;           con.weightx = 0.5;           con.gridx = 2;           con.gridy = 4;           panel.add(sideclabel, con);                     button.addActionListener(                 new ActionListener(){                 public void actionPerformed(ActionEvent arg0){                         A = Integer.parseInt(angleatext.getText());                     a = Integer.parseInt(sideatext.getText());                     b = Integer.parseInt(sidebtext.getText());                                         anglealabel.setText("Angle A: "+angleatext.getText()+" degrees.");                     sidealabel.setText("Side a: "+sideatext.getText());                     sideblabel.setText("Side b: "+sidebtext.getText());                                         radA = Math.toRadians(A);                     h = (Math.sin(radA))*b;                                         if (A>=90){                     B = (Math.asin(b*(Math.sin(radA))/a));                     outputB = df1.format(B);                     angleblabel.setText("Angle B: "+outputB);                                         C = 180-A-B;                     outputc = df1.format(C);                     angleclabel.setText("Angle C: "+outputc);                     radC = Math.toRadians(C);                                         c = a*(Math.sin(radC))/(Math.sin(radA));                     outputc = df1.format(c);                     sideclabel.setText("Side c: "+outputc); }                     else{                                                 if (a<h){                             angleblabel.setText("Not a triangle.");                             angleclabel.setText("Not a triangle.");                             sideclabel.setText("Not a triangle."); }                     else if (a==h){                             B = (Math.asin(b*(Math.sin(radA))/a));                             outputB = df1.format(B);                             angleblabel.setText("Angle B: "+outputB);                                                         C = 180-A-B;                             outputc = df1.format(C);                             angleclabel.setText("Angle C: "+outputc);                             radC = Math.toRadians(C);                                                         c = (a*(Math.sin(radC)))/(Math.sin(radA));                             outputc = df1.format(c);                             sideclabel.setText("Side c: "+outputc); }                     else {                             B = (Math.asin(b*(Math.sin(radA))/a));                             outputB = df1.format(B);                             B2 = 180-B;                             outputB2 = df1.format(B2);                             angleblabel.setText("Angle B: "+outputB+","+outputB2);                                                         C = 180-A-B;                             outputc = df1.format(C);                             radC = Math.toRadians(C);                             c2 = 180-A-B2;                             outputC2 = df1.format(C2);                             radC2 = Math.toRadians(C2);                             angleclabel.setText("Angle C: "+outputc+","+outputC2);                                                         c = a*(Math.sin(radC))/(Math.sin(radA));                             outputc = df1.format(c);                             c2 = a*(Math.sin(radC2))/(Math.sin(radA));                             sideclabel.setText("Side c: "+outputc+","+outputc2); }     }        }   }   );  } }```
• 12-12-2011, 05:08 AM
pbrockway2
Re: Trigonometric Functions Problem In Java
Quote:

but it encounters a slight error when no-solution triangles are presented and fails altogether when presented with two solution triangles. Also, for some reason, it appears that inputting decimal values seems to crash the program
Could you elaborate on "slight error" and "fails altogether"? Ie say what you do when you run the program (what you input and where etc) and what you observe. Presumably these terms refer to a mismatch between observed and intended behaviour.

Also if you get a runtime error when you enter decimal strings post the entire runtime stack trace, and say which line of your code it is referring to.
• 12-12-2011, 01:45 PM
2by4
Re: Trigonometric Functions Problem In Java
You have applied formulae that assume you have a right-angled triangle, so all your calculations are wrong.

The formula you need is the sine formula ~ (sinA)/a = (sinB)/b = (sinC)/c, where x is the angle opposite side length X.

You know (sinX)/x for one pair of sides. It is easy to find the others.

But first you must validate your input completely.

Why not check straight away that the range of your input angle is (0, 180)?

You then need to find the second angle. Validate that its sine is in the range (-1, 0) or (0, 1).

Third angle by sum of angles, and corresponding side by sine formula..

Enjoy. :-)
• 12-13-2011, 04:50 AM
javaBeaner
Re: Trigonometric Functions Problem In Java
The "slight error" that occurs when no-solution triangles are entered is that the three "answer labels", for lack of a better term, that should read "not a triangle" instead just display a small square.

"Fails altogether" means that when two-solution triangles or decimal values are entered, a run-time error occurs and Eclipse displays a runtime stack trace, and the answer labels do not change at all.

Hear is the runtime error message in its entirety:

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "74.5" -----This is a random input I chose for Angle A.
at java.lang.NumberFormatException.forInputString(Unk nown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at SolvingSSATriangles\$1.actionPerformed(SolvingSSATr iangles.java:140) ----- This refers to the line " A = Integer.parseInt(angleatext.getText()); ", for some reason...
at javax.swing.AbstractButton.fireActionPerformed(Unk nown Source)
at javax.swing.AbstractButton\$Handler.actionPerformed (Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed (Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseRe leased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent( Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(U nknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unkno wn Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access\$000(Unknown Source)
at java.awt.EventQueue\$1.run(Unknown Source)
at java.awt.EventQueue\$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext\$1.doIntersectio nPrivilege(Unknown Source)
at java.security.AccessControlContext\$1.doIntersectio nPrivilege(Unknown Source)
at java.awt.EventQueue\$2.run(Unknown Source)
at java.awt.EventQueue\$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext\$1.doIntersectio nPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)

In the runtime error the "Native Method"s link to a screen telling me that my JAR file has no source attachment. Quite frankly, I have no idea what this means.
• 12-13-2011, 04:53 AM
pbrockway2
Re: Trigonometric Functions Problem In Java
Code:

```Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "74.5" -----This is a random input I chose for Angle A. at java.lang.NumberFormatException.forInputString(Unk nown Source) at java.lang.Integer.parseInt(Unknown Source) at java.lang.Integer.parseInt(Unknown Source) at SolvingSSATriangles\$1.actionPerformed(SolvingSSATr iangles.java:140) ----- This refers to the line " A = Integer.parseInt(angleatext.getText()); ", for some reason...```
OK, the NumberFormatException is occurring because the string "74.5" cannot be interpreted as an integer value by Integer.parseInt(). Try Double.parseDouble() instead.

Typically you read these stack traces down to where your code is mentioned, since almost always that is the locus of the problem.

The moral here is the fact that A is declared as double doesn't matter. What matters is what Integer.parseInt() does.
• 12-13-2011, 05:02 AM
javaBeaner
Re: Trigonometric Functions Problem In Java
To answer 2by4's question about my math, the mathematical process you described is the one I tried to follow.
Does B = (Math.asin(b*(Math.sin(radA))/a)); , or B = arcsin((b*sinA)/a) in the vernacular, not derive directly from the Law of Sines?

And thanks, I have added an extra if-statement to confirm that A is within the range of 0-180.

Isn't validating that the range of the second angle's sine is in the range of (-1, 0) or (0, 1) redundant? As long as the angle is not 0 or 180, which it cannot be in a triangle, is its sine not be definition in the range of (-1, 0) or (0, 1)?
• 12-13-2011, 05:13 AM
pbrockway2
Re: Trigonometric Functions Problem In Java
Quote:

The "slight error" that occurs when no-solution triangles are entered is that the three "answer labels", for lack of a better term, that should read "not a triangle" instead just display a small square.
Can you give an example of such a no-solution triangle? (that displays the square)

I just tried with 120/1/1 and it gave me a bogus result - Angle B: 1.0472

Code:

```if (A>=90){             B = (Math.asin(b*(Math.sin(radA))/a));```
It's radB which is equal to that expression. I think you may be doing this elsewhere as well.
• 12-13-2011, 09:58 AM
2by4
Re: Trigonometric Functions Problem In Java
Quote:

Originally Posted by javaBeaner
To answer 2by4's question about my math, the mathematical process you described is the one I tried to follow.
Does B = (Math.asin(b*(Math.sin(radA))/a)); , or B = arcsin((b*sinA)/a) in the vernacular, not derive directly from the Law of Sines?

You are correct. It does. I am just not sure why you have evaluated h, which is part of a right-angled triangle. Perhaps the answer to this question is in the answer to the second half of this post.

Quote:

Originally Posted by javaBeaner
Isn't validating that the range of the second angle's sine is in the range of (-1, 0) or (0, 1) redundant? As long as the angle is not 0 or 180, which it cannot be in a triangle, is its sine not be definition in the range of (-1, 0) or (0, 1)?

Mathematically correct. But the whole point is that you do not yet know that you have a valid sine.

i.e before you apply Math.asin() how do you know that b*(Math.sin(radA))/a (your putative sine) is valid?

You should check first that it is in the range given. Maybe your use of h is a roundabout way of achieving the same thing by using the fact that the opposite side is shortest when you have a right-angled triangle? But the method I illustrated is simpler, more direct and more efficient. It would condense your calculation by at least 60 per cent.
• 12-13-2011, 03:17 PM
javaBeaner
Re: Trigonometric Functions Problem In Java
@2by4:
I understand what you're saying, and I adjusted my code accordingly. The math section of embedded if statements of my code now reads like this:

if (A<180){

if (A>=90){
outputB = df1.format(B);
angleblabel.setText("Angle B: "+outputB);

C = 180-A-B;
outputc = df1.format(C);
angleclabel.setText("Angle C: "+outputc);

outputc = df1.format(c);
sideclabel.setText("Side c: "+outputc); }
else{

angleblabel.setText("Not a triangle.");
angleclabel.setText("Not a triangle.");
sideclabel.setText("Not a triangle."); }
else {
outputB = df1.format(B);
B2 = 180-B;
outputB2 = df1.format(B2);
angleblabel.setText("Angle B: "+outputB+","+outputB2);

C = 180-A-B;
outputc = df1.format(C);
c2 = 180-A-B2;
outputC2 = df1.format(C2);
angleclabel.setText("Angle C: "+outputc+","+outputC2);

outputc = df1.format(c);
sideclabel.setText("Side c: "+outputc+","+outputc2); } } }
else if(A<0){
angleblabel.setText("Not a triangle.");
angleclabel.setText("Not a triangle.");
sideclabel.setText("Not a triangle."); }
else{
angleblabel.setText("Not a triangle.");
angleclabel.setText("Not a triangle.");
sideclabel.setText("Not a triangle."); }
• 12-13-2011, 03:42 PM
javaBeaner
Re: Trigonometric Functions Problem In Java
@pbrockway2:

Any triangle that you input where A is obtuse and a<b, such as 100/4/7, causes the squares to appear.
• 12-13-2011, 07:56 PM
2by4
Re: Trigonometric Functions Problem In Java
Quote:

Originally Posted by javaBeaner
@2by4:
I understand what you're saying, and I adjusted my code accordingly. The math section of embedded if statements of my code now reads like this:

if (A<180){

if (A>=90){
outputB = df1.format(B);
angleblabel.setText("Angle B: "+outputB);

Initial validation should check A < 180 AND A > 0. Program should give an error and terminate if not.

Then you have your cases A >= 90 or A < 90. The first gives 1 possibility and the second 2.

Break the highlighted line into 2!!!

You must check that "angle" is in the correct range, otherwise Math.asin will fail and return Double.NaN (not a number).

If "angle is not in the correct range", you don't have a triangle. The program should put out a message and terminate.

What does your program do if A is 90, a is 5 and b is 6? I know this won't be a triangle because the largest side must be opposite the largest angle. But b can't be opposite an angle of 90+ otherwise you'd have a triangle of more than 180 degrees. What does your program do?

P.S,

To simplify your program it is better to collect your data and do all the display work once at the end instead of repeating it.

1. Check 0 < A <180 else terminate with message.

2. Evaluate "sin B". Is it in range? Message and terminate if not. If it is in range, you must have a valid triangle.

3. Evaluate the 2 values of B (B1, ?B2?). If one of them takes the total angle > 180, discard it. DON'T display anything yet.

4. Evaluate b (b1, ?b2?). DON'T display anything yet.

5. Evaluate C (C1, ?C2?). DON'T display anything yet.

6. Evaluate c (c1, ?c2?).

7. Now you have all your data. Do your display in one hit.

You will find this much cleaner code.
• 12-13-2011, 08:33 PM
pbrockway2
Re: Trigonometric Functions Problem In Java
Quote:

Originally Posted by javaBeaner
@pbrockway2: