Last time we learned how to use the trigonometric ratios to solve for a side in a right triangle. Now what if we want to discover the measure of an angle from the length of two sides? I found myself in this exact situation when making the examples for the previous blog post. I declared an array containing the triangle vertices in a sort of mock clipspace like so:

const rightTriangle = [
	{ x: -0.65, y: 0.65 },
	{ x: 0.8, y: -0.5 },
	{ x: 0.8, y: 0.65 },
];

While clipspace is normally a WebGL shader coordinate system, I have converted the canvas pixel space into an imitation so I can use a fluid width canvas. Regardless, I could determine the length of each side from the vertex locations, but how would I calculate the value of the acute angles once the user changed the length of a side? Inverse Trigonometric Functions to the rescue!

As with addition and subtraction, it's possible to invert the trigonometric functions sine, cosine, and tangent. The inverse of these functions are often referred to as arcsine, arccosine, and arctangent. In JavaScript these are Math.asin(), Math.acos(), and Math.atan(). JavaScript will return the angle measure in radians, so be sure to convert back to degrees or you'll get incorrect values. So how do we use the inverse functions to determine the measure of an angle? We use our old pal "SOH CAH TOA" with slightly different equations from before:

∠𝛳 = arcsin(opposite / hypotenuse)
∠𝛳 = arccos(adjacent / hypotenuse)
∠𝛳 = arctan(opposite / adjacent)

You can see in the example below, the steps for solving an angle are similar to solving for a side but simpler because we don't need to do rearrange the equation. We just divide one side by the other then run it through the chosen trig function:

  1. Determine which ratio we need to use. Because we know the lengths of the adjacent and hypotenuse, let's use arccos.
  2. Substitute the known values.
  3. Evaluate to determine ∠B.

Going back to our real world example, I had to get the measure of my acute angles in order to display them to the user when a side length was changed. My solution was to create a function which took the side lengths as an argument, then returned an object containing all the angle values. Since we have the value of ∠C baked into the rightTriangle constant, we can just return 90 all the time for it. For the values of ∠A and ∠B we use acos and asin on the side lengths:

getAngles = (sidesLengths) => {
  return {
    A : radToDeg(Math.acos(sidesLengths.AC / sidesLengths.AB)),
    B : radToDeg(Math.asin(sidesLengths.AC / sidesLengths.AB)),
    C : 90,
  };
}

So now we have the ability to solve all the sides and angles in a right triangle given only 2 values, be they angles or side lengths. This gives us an important building block we need to start rendering triangles in WebGL. There's a long way to go from calculating right triangles to rendering them in 3D but it's a good first step. Coming up next, I will be adding a bunch of 2D functions to NEWT which means hopping back into code instead of math.