Unit 6 The Trig Example

  1. The working Applet
  2. The Global Variables, Beans and Init Method
  3. The Four Trigonometric Laws
  4. Checking for valid data
  5. Find all missing information
  6. Calculating the positions of the three Vertices and Draw the Triangle
  7. The action method


The working Applet Ass6p1.java        

You are to create an applet, that lets you enter 6 numbers representing the sides and angles of a triangle: Three of these numbers are positive, and three are 0. Your program should (using trigonometry) draw a properly scaled diagram of the triangle, and replace the zeroes with the calculated values.



The Global Variables, Beans and Init Method       

The Labels, TextFields and Buttons inside their Layout appear at the top of the Applet, the "North" end. The global variables are named for triangle ABC and use single letters: a,b,c for sides, A,B,C for angles. The local varables in contrast use the corresponding double names: aa, bb, cc, AA, BB, CC.

    Font f1 = new Font ("TimesRoman", Font.BOLD, 18);
    Font f2 = new Font ("TimesRoman", Font.PLAIN, 12);
    TextField sideA = new TextField (4);
    TextField sideB = new TextField (4);
    TextField sideC = new TextField (4);
    TextField angleA = new TextField (4);
    TextField angleB = new TextField (4);
    TextField angleC = new TextField (4);
    Label a_label = new Label ("side a ");
    Label b_label = new Label ("side b ");
    Label c_label = new Label ("side c ");
    Label A_label = new Label ("angle A");
    Label B_label = new Label ("angle B");
    Label C_label = new Label ("angle C");
    Button start = new Button ("start");
    Button clear = new Button ("clear");
    double a = 0;
    double b = 0;
    double c = 0;
    double A = 0;
    double B = 0;
    double C = 0;
    boolean ready = false;

    public void init ()
    {
      setBackground (Color.white);
      setLayout (new BorderLayout ());
      Panel p = new Panel ();
      add ("North", p);
      p.setLayout (new GridLayout (2, 7));
      p.add (a_label);
      p.add (b_label);
      p.add (c_label);
      p.add (A_label);
      p.add (B_label);
      p.add (C_label);
      p.add (clear);
      p.add (sideA);
      p.add (sideB);
      p.add (sideC);
      p.add (angleA);
      p.add (angleB);
      p.add (angleC);
      p.add (start);
      sideA.setText ("");
      sideB.setText ("");
      sideC.setText ("");
      angleA.setText ("");
      angleB.setText ("");
      angleC.setText ("");
      clear.addActionListener (this);
      start.addActionListener (this);
    } // end init
roundTo2



The Four Trigonometric Laws        

Given any combination of three data, the other three data may be found. There are three cautions:

  • There must be at least one side: Three angles are insufficient.
  • When all three sides are known, each side must be less than half the perimeter
  • An angle and one side will determine the height to the missing other side. If the third side is given, it must be larger than that height.
  • In the last case, there are two possibilities: One, where the other basis angle <90 and the other, where it is >90. This law should therefore be invokes only as a last resort, and then we will assume an angle <90.

  •     //returns angle A of of triangle ABC
        public double cosLawSSS (double bb, double aa, double cc)
        {
          double fraction = (bb * bb + cc * cc - aa * aa) / bb / cc / 2.0;
          return Math.acos (fraction) * 57.295828;
        } //end cosLawSSS
    
    
        // returns side a of triangle ABC
        public double cosLawSAS (double bb, double AA, double cc)
        {
          double aSquare = bb * bb + cc * cc - 2 * bb * cc * Math.cos (AA / 57.295828);
          return Math.sqrt (aSquare);
        } //end cosLawSAS
    
    
        //finds angle B of triangle ABC
        public double sinLawSSA (double aa, double bb, double AA)
        {
          double sinB = bb * Math.sin (AA / 57.295828) / aa;
          return Math.asin (sinB) * 57.295828;
        } //end sinLawSSA
    
    
        //finds side a of triangle ABC
        public double sinLawASA (double AA, double bb, double CC)
        {
          double BB = (180 - AA - CC) / 57.295828;
          return bb * Math.sin (AA / 57.295828) / Math.sin (BB);
        } //end sinLawASA
    
    
        //rounds off to 2 digits
        public String roundTo2 (double p)
        {
          return "" + Math.round (100 * p) / 100.0;
        } //end roundTo2
    
    


    Checking for valid data Ass5s3p1.java        

    1. If input data is blank or otherwise invalid, the appropriate variable becomes zero. Otherwise take the value.
    2. If all three angles are given, Z =0
    3. If all three sides are given, and they can't form a triangle, z=0
    4. If only two sides are given and a non-contained angle, which cannot form a triangle, the angle becomes 0.
    5. If more than 3 pieces of data is given, the extra pieces (angles) become 0.
    6. Update the text boxes.

    
    // read the contents of a textfield
    private double readTextBox (TextField text)
        {
           double val = -1;
           try
           {
               val = Double.valueOf (text.getText ()).doubleValue ();
           }
           catch (NumberFormatException e)
           {
               val = -1;
           }
           if (val < 0)
               val = 0;
           return val;
        } //end readTextBox
    
    
    //zero all inputs except the first 3 positive ones
    //false if there are not enough data
    public boolean readySetGo ()
        {
           double temp;
           a = readTextBox (sideA);
           b = readTextBox (sideB);
           c = readTextBox (sideC);
           A = readTextBox (angleA);
           if (A >= 180)
               A = 0;
           B = readTextBox (angleB);
           if (B >= 180)
               B = 0;
           C = readTextBox (angleC);
           if (C >= 180)
               C = 0;
    
           //check if all three angles are given, zero C
           if (A > 0 && B > 0 && C > 0)
               C = 0;
           //check if 3 sides are given: if inconsistent, zero c
           if (a > 0 && b > 0 && c > 0)
           {
               temp = (a + b + c) / 2.0;
               if (temp < a || temp < b || temp < c)
                  c = 0;
           }
    
           //check for two sides and a noncontained angle (6 cases)
           if (a == 0 && b * c * B > 0 && b < c * Math.sin (B / 57.295828))
               B = 0;
           if (a == 0 && b * c * C > 0 && c < b * Math.sin (C / 57.295828))
               C = 0;
           if (b == 0 && a * c * A > 0 && a < c * Math.sin (A / 57.295828))
               A = 0;
           if (b == 0 && a * c * C > 0 && c < a * Math.sin (C / 57.295828))
               C = 0;
           if (c == 0 && a * b * A > 0 && a < b * Math.sin (A / 57.295828))
               A = 0;
           if (c == 0 && a * b * B > 0 && b < a * Math.sin (B / 57.295828))
               B = 0;
           // discard more than 3 nonzero inputs
           int count = 0;
           if (a > 0)
               count++;
           if (b > 0)
               count++;
           if (c > 0)
               count++;
           if (A > 0 && count == 3)
               A = 0;
           if (A > 0)
               count++;
           if (B > 0 && count == 3)
               B = 0;
           if (B > 0)
               count++;
           if (C > 0 && count == 3)
               C = 0;
           if (C > 0)
               count++;
           sideA.setText (roundTo2 (a));
           sideB.setText (roundTo2 (b));
           sideC.setText (roundTo2 (c));
           angleA.setText (roundTo2 (A));
           angleB.setText (roundTo2 (B));
           angleC.setText (roundTo2 (C));
           if (count == 3)
               return true;
           return false;
        } //end readySetGo
    
    


    Find all missing information        

    For finding the first piece of data, there are 23 distinct possibilities. However, we can reduce it to 6, if we let the angles and sides rotate. Of the 4 laws, only sinLawSSA() is not symmetric and must be used twice.

    // rotate the values of a,b,c and of A,B,C
    public void rotate ()
        {
           double temp = a;
           a = b;
           b = c;
           c = temp;
           temp = A;
           A = B;
           B = C;
           C = temp;
        }
    
     public void findAll ()
        {
           while (a == 0 || b == 0 || c == 0 || A == 0 || B == 0 || C == 0)
           {
               boolean itemFound = false;
               for (int i = 0 ; i < 3 ; i++)
               {
                  if (A > 0 && B > 0 && C == 0)
                  {
                     itemFound = true;
                     C = 180 - A - B;
                  }
                  rotate ();
               }
               if (!itemFound)
                  for (int i = 0 ; i < 3 ; i++)
                  {
                      if (a > 0 && b > 0 && c > 0 && A == 0)
                      {
                         itemFound = true;
                         A = cosLawSSS (b, a, c);
                      }
                      rotate ();
                  }
               if (!itemFound)
                   for (int i = 0 ; i < 3 ; i++)
                   {
                      if (a > 0 && b > 0 && C > 0 && c == 0)
                      {
                         itemFound = true;
                         c = cosLawSAS (a, C, b);
                      }
                      rotate ();
                   }
               if (!itemFound)
                   for (int i = 0 ; i < 3 ; i++)
                   {
                      if (A > 0 && b > 0 && C > 0 && a == 0)
                      {
                          itemFound = true;
                          a = sinLawASA (A, b, C);
                      }
                      rotate ();
                   }
               if (!itemFound)
                   for (int i = 0 ; i < 3 ; i++)
                   {
                      if (a > 0 && b > 0 && A > 0 && B == 0 && C == 0)
                      {
                         itemFound = true;
                         B = sinLawSSA (a, b, A);
                      }
                      rotate ();
                   }
               if (!itemFound)
                  for (int i = 0 ; i < 3 ; i++)
                  {
                      if (a > 0 && b > 0 && B > 0 && A == 0 && C == 0)
                      {
                         itemFound = true;
                         A = sinLawSSA (b, a, B);
                      }
                      rotate ();
               }
    	   }
           sideA.setText (roundTo2 (a));
           sideB.setText (roundTo2 (b));
           sideC.setText (roundTo2 (c));
           angleA.setText (roundTo2 (A));
           angleB.setText (roundTo2 (B));
           angleC.setText (roundTo2 (C));
        } //end findAll
    
    


    Calculating the positions of the three Vertices and Draw the Triangle        

    We do this in two steps:

  • In the standard Cartesian Coordinate system, let X be at the origin and Y along the positive x-axis
  • Calculating the rectangle that is then needed, and finding the scale so that its largest side will fit in 300 pixels.
  • Translating and reducing the points to scale

  • public void paint (Graphics g)
      {
        if (ready)
        {
            findAll ();
            int xPts[] = new int [3];
            int yPts[] = new int [3];
            //in a Cartesian coordinate system:
            // let A(0,0)
            // let B along positive a-axis: B(c,0)
            // then C(b*cos(A),b*sin(A))
            // everything must fit inside box with diagonal (10,110) to (340,440)
            double maxRight = Math.max (c, b * Math.cos (A / 57.295828));
            double maxLeft = Math.min (0, b * Math.cos (A / 57.295828));
            double maxTop = b * Math.sin (A / 57.295828);
            double maxMin = 0;
            //finding the scale factor
            double scale = 300.0 / Math.max (maxRight - maxLeft, maxTop);
            //recalculating the ordered pairs:
            xPts [0] = (int) (-maxLeft * scale + 25);
            yPts [0] = 425;
            xPts [1] = (int) (xPts [0] + c * scale);
            yPts [1] = 425;
            xPts [2] = (int) (xPts [0] + b * Math.cos (A / 57.295828) * scale);
            yPts [2] = (int) (425 - maxTop * scale);
            g.setColor (Color.red);
            g.fillPolygon (xPts, yPts, 3);
            g.setFont (f1);
            g.setColor (Color.blue);
            g.drawString ("A", xPts [0] - 15, yPts [0] + 15);
            g.drawString ("B", xPts [1] + 5, yPts [1] + 15);
            g.drawString ("C", xPts [2] - 15, yPts [2] - 15);
            g.setFont (f2);
            g.setColor (Color.black);
            g.drawString (roundTo2 (c), (xPts [0] + xPts [1]) / 2 - 15, 440);
            g.drawString (roundTo2 (b), (xPts [0] + xPts [2]) / 2 - 24, (yPts [0] + yPts [2]) / 2);
            g.drawString (roundTo2 (a), (xPts [1] + xPts [2]) / 2, (yPts [1] + yPts [2]) / 2 + 2);
        }
        else
            g.drawString ("There is not enough data", 50, 300);
     }
    


    The actionPerformed method        

    The Applet will becomes active only when one of the two buttons is pressed. Since both the clear and start buttons have actionListener(), when they are pressed, the following method is executed.

    
        public void actionPerformed (ActionEvent event)
        {
    	if (event.getSource () == start)
    	    ready = readySetGo ();
    	else
    	{
    	    ready = false;
    	    sideA.setText ("");
    	    sideB.setText ("");
    	    sideC.setText ("");
    	    angleA.setText ("");
    	    angleB.setText ("");
    	    angleC.setText ("");
    	}
    	repaint ();
        }
    
    
    



    Sponsored by ECOO and SIG-Computer Science

    .