Results 1 to 12 of 12
Like Tree2Likes
  • 1 Post By pbrockway2
  • 1 Post By 2by4

Thread: Trigonometric Functions Problem In Java

  1. #1
    javaBeaner is offline Member
    Join Date
    Dec 2011
    Posts
    5
    Rep Power
    0

    Default 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:

    Java 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); }
         }     
        }
       }
      );
     }
    }
    Last edited by pbrockway2; 12-12-2011 at 04:00 AM. Reason: code tags added

  2. #2
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Trigonometric Functions Problem In Java

    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.
    DarrylBurke likes this.

  3. #3
    2by4 is offline Banned
    Join Date
    Dec 2011
    Posts
    143
    Rep Power
    0

    Default 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. :-)
    Last edited by 2by4; 12-12-2011 at 12:50 PM.
    sunde887 likes this.

  4. #4
    javaBeaner is offline Member
    Join Date
    Dec 2011
    Posts
    5
    Rep Power
    0

    Default 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)
    at java.awt.EventDispatchThread.pumpOneEventForFilter s(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(U nknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarch y(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(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.

  5. #5
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Trigonometric Functions Problem In Java

    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.
    Last edited by pbrockway2; 12-13-2011 at 03:56 AM.

  6. #6
    javaBeaner is offline Member
    Join Date
    Dec 2011
    Posts
    5
    Rep Power
    0

    Default 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)?

  7. #7
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default 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.
    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

    Java 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.
    Last edited by pbrockway2; 12-13-2011 at 04:22 AM.

  8. #8
    2by4 is offline Banned
    Join Date
    Dec 2011
    Posts
    143
    Rep Power
    0

    Default Re: Trigonometric Functions Problem In Java

    Quote Originally Posted by javaBeaner View Post
    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 View Post
    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.
    Last edited by 2by4; 12-13-2011 at 09:00 AM.

  9. #9
    javaBeaner is offline Member
    Join Date
    Dec 2011
    Posts
    5
    Rep Power
    0

    Default 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){
    radB = (Math.asin(b*(Math.sin(radA))/a));
    B = Math.toDegrees(radB);
    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 ((b*(Math.sin(radA))/a)>1 || ((b*(Math.sin(radA))/a)<-1)){
    angleblabel.setText("Not a triangle.");
    angleclabel.setText("Not a triangle.");
    sideclabel.setText("Not a triangle."); }
    else {
    radB = (Math.asin(b*(Math.sin(radA))/a));
    B = Math.toDegrees(radB);
    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); } } }
    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."); }

  10. #10
    javaBeaner is offline Member
    Join Date
    Dec 2011
    Posts
    5
    Rep Power
    0

    Default Re: Trigonometric Functions Problem In Java

    @pbrockway2:

    Thanks for your suggestion, I have adjusted B to radB and set B equal to Math.toDegrees(radB);
    Any triangle that you input where A is obtuse and a<b, such as 100/4/7, causes the squares to appear.

  11. #11
    2by4 is offline Banned
    Join Date
    Dec 2011
    Posts
    143
    Rep Power
    0

    Default Re: Trigonometric Functions Problem In Java

    Quote Originally Posted by javaBeaner View Post
    @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){
    radB = (Math.asin(b*(Math.sin(radA))/a));
    B = Math.toDegrees(radB);
    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!!!

    int angle = b*(Math.sin(radA))/a

    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.
    Last edited by 2by4; 12-13-2011 at 07:08 PM.

  12. #12
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Trigonometric Functions Problem In Java

    Quote Originally Posted by javaBeaner View Post
    @pbrockway2:

    Thanks for your suggestion, I have adjusted B to radB and set B equal to Math.toDegrees(radB);
    Any triangle that you input where A is obtuse and a<b, such as 100/4/7, causes the squares to appear.
    I suggest you add some debugging code to that maths section. Specifically put a statement after each if() { to say which path you are following, and print the values of sides and angles both formatted and unformatted.

    I think 2x4 has addressed the logical issues, but it can't hurt to verify that the correct code path is being followed in each case.

    For instance 100/4/7 follows the "first" path: ie if(A<180) { and if(A>=90) {. This path does not include any "not a triangle" messages, so it is no wonder that the message doesn't appear. Since the numbers don't specify a real triangle my guess is that you are getting NaN as the values and they are getting formatted oddly. (Rereading this, I see 2x4 has already drawn attention to the NaN problem in this branch.)

Similar Threads

  1. Java functions
    By victorq in forum New To Java
    Replies: 5
    Last Post: 10-26-2011, 08:40 PM
  2. Calling java functions from c++
    By khajalid in forum New To Java
    Replies: 13
    Last Post: 10-12-2010, 10:50 PM
  3. Calculating trigonometric functions
    By Java Tip in forum java.lang
    Replies: 0
    Last Post: 04-16-2008, 10:56 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •