Up until this point we've focused on right triangles, now it's time enter the wide world of triangular variety with the law of sines and the law of cosines. We can use these laws (sometimes also called rules or formulas) to help us solve triangles which might not have a 90 degree angle.

The Law Of Sines

Let's begin with the law of sines, it states that the ratio of an angle's sine to its opposite is constant for any angle in a triangle. Written as a formula it's something like sin(∠A)/BC = sin(∠B)/AC = sin(∠C)/AB. In the example below you can see that sin(∠A) divided by the length of its opposite BC is equal to sin(∠B) divided by the length of its opposite AC. Because the same is true for ∠C, we can solve an entire triangle given only two angles and one side length.

We know the angles will add up to 180° so we can infer the value of the last angle ∠A = 180 - (∠C + ∠B). Then we use the known values to create two equations, one to solve each of the remaining side lengths similar to the example below.

  1.  sin(93) / 10.5 = sin(38) / x
  2.  x * sin(93) / 10.5 = sin(38)
  3.  x = sin(38) / (sin(93) / 10.5)
  4.  x = 6.47

The Law Of Cosines

In my examples for this page, I didn't use the law of sines. This is because I keep the vertex coordinates in an array, then draw lines between them in canvas. It makes it easy to get the side lengths using the distance formula but I still need to solve the angles, so I use the law of cosines to measure the angles.

The law of cosines as displayed above is an adaptation of the Pythagorean theorem, given two side lengths and the angle between them we can use it to determine the length if the angle's opposite. It looks like this a² = b² + c² - 2⋆b⋆c⋆cos(Θ). For my examples I had the value of a, b, and c but needed the value of the angles. I rearranged the equation and created a function which returns the angle of Θ, then call it once for each angle.

  getAngles = (A, B, C) => {
    return {
      A : radToDeg(lawOfCosines(A, B, C)),
      B : radToDeg(lawOfCosines(C, A, B)),
      C : radToDeg(lawOfCosines(B, A, C)),
    };
  }

  lawOfCosines = (A, B, C) => Math.acos(
      (Math.pow(A, 2) - (Math.pow(B, 2) + Math.pow(C, 2))) / (-2*B*C)
  );

This way I can manipulate the position of the points directly while correctly recalculating all the side and angle values. I also implemented some sliders instead of inputs which makes it a lot easier to modify the triangle. Now I can integrate these functions into NEWT to help with some geometry generation classes.