When are oblique triangles used in game development?

I'm working on a project that explains how trigonometry is used in video games, and I need to mention oblique triangles.

However, as far as I know, only right triangle diagrams are used in video games to perform calculations such as distance and angle.

Are right triangles always used, or are there some cases where oblique triangles are used, in which the Law of Sines and Law of Cosines are also used?

Trigonometry is rarely applied directly in video game development. Allow me to explain what I mean by that: We will approach problems from a vector algebra standpoint first. And if you are struggling to solve something in video game development with linear algebra or trigonometry, we are going to tell you to use vectors instead.

That does not mean we never use trigonometry directly. Which would be the case of the famous atan2 to figure out the angle of a vector in the plane. However, often, this trigonometry is hidden by libraries. We don't use it directly.

That trigonometry is in the service of vector algebra. To make rotation matrices, library will use sin and cos, similarly to convert axis-angle to a quaternion.

You will also find trigonometric functions in effects and animation. Anything cyclic or oscillating is probably using sin.

As Philipp answer mentions, there is some trigonometry in a perspective projection matrix. In particular, we use tan when creating a projection matrix based on camera field of view angle. See GluPerspective code.

If we also want to position a virtual camera, we will create a view matrix composing a rotation matrix (which, as mentioned above, uses sin and cos), among others.

It is possible to combine projection and view matrices before sending them to a shader. However they should not be confused. See The view matrix finally explained.

With that said, we do use the cosine rule. Well, we use a consequence of it: the relationship between the cosine rule and the dot product. We would also use sine with the cross product, however that is used less often.

Let us say we have two vectors a and b. When placed at the origin, they point to points A and B respectively. The vector that goes from A to B is b - a. Let us call it c: c = b - a. Thus, a, b and c are the vectors of the sides of the triangle AOB (where O is the origin).

Cosine law tells us that:

|c|^2 = |a|^2 + |b|^2 - 2|a||b|*cos(theta)


Where theta is the angle between the vectors a and b.

Now look what happens with the dot product of c with itself:

c·c = (b - a)·(b - a)

=>

c·c = a·a - a·b - b·a + b·b

=>

c·c = a·a + b·b - 2(a·b)



I remind you that the dot product of two vectors is the sum of the products of the components. That means that the dot product of a vector with itself is the sum of the components squared. Thus, the dot product of a vector with itself is the magnitud (length) of the vector squared (i.e. apply the Pythagoras theorem, but don't do the square root).

This holds regardless of the number of dimensions.

Thus, we have:

|c|^2 = |a|^2 + |b|^2 - 2(a·b)


And we can equate it to what we got from the cosine rule:

|a|^2 + |b|^2 - 2(a·b) = |a|^2 + |b|^2 - 2|a||b|*cos(theta)

=>

-2(a·b) = -2|a||b|*cos(theta)

=>

a·b = |a||b|*cos(theta)

=>

a·b/|a||b| = cos(theta)

=>

theta = acos(a·b/|a||b|)


And that way you can get the angle between two vectors regardless of the number of dimensions. This will work in 2D, this will work in 3D, and if you are doing a fancy 4D or whatever game, it will still work.

About the cross product… We all know that the result is perpendicular to the two inputs. Well, the magnitud (length) of the result is proportional to the sine of the angle:

|a x b| = |a||b||sin(tetha)|


This means that we can also get the angle between two vectors in space from the cross product. However, as you would know this approach would have to be adapted to work in 2D, since the cross product is defined in 3D but not 2D. We can compute a wedge product in 2D whose result is the magnitud of the cross product of the inputs.

Wedge product:

wedge(a,b) = a.x*b.y - a.y*b.x = |a||b|sin(tetha)

=>

tetha = asin(wedge(a,b)/|a||b|)


While the atan2 gives you the angle of a vector in the plane. And the dot product can be used to get the angle between two vectors (regardless of the number of dimensions). However, note that with the wedge product is signed, and with it we get a signed angle, unlike the one we get with the dot product.

If you have a polygon as a list of points that represent a loop (so you treat the last and first as consecutive too), take consecutive triplets form it, compute the angle with the wedge product approach… If all the results you get are the same sign, your polygon is convex. If the sign changes, you have a concave polygon. This is useful in convex hull and polygon triangulation algorithms.

The magnitud of the cross product is also the area of the parallelogram (twice the triangle area). Thus we can use the cross product to compute the area of a polygon. See Cross Product Parallelogram Theorem: A Direct Proof.

For the computation of the area of the polygon, when you find a change of sign when going around the loop, it means you will be subtracting an area (remember that this happens where the shape is concave). See Algorithm for Area of a closed polygon.

Triangulation is useful in 3D modelling software, used to create models used in games. And also in the creation and use of navigation meshes for path-finding.

Oblique triangles appear extensively in (almost*) every game which uses 3d rendering. Every 3d object in a game is basically a collection of oblique triangles. We usually call them "polygons" but in practice they are all triangles.

Each triangle ("polygon") is defined by its three corners ("vertices") which are in turn defined by their x, y and z coordinate in 3d space. We then use a program which runs on the GPU called a "vertex shader" to convert vertex positions in 3d space to positions on the player's 2d screen. This program usually uses a projection matrix to do so, and the creation of that matrix involves quite a lot of trigonometry.

The GPU then calculates which screen pixels are covered by that triangle on the screen and uses another program we wrote called a "pixel shader" to determine the color of each pixel of that triangle.

* 3d rendering techniques which do not use triangles are voxel rendering (which uses cubes) and raytracing (which can use triangles, but really shines when it can show off its ability to work directly with volumetric 3d shapes like spheres and prisms). But voxel renderers became very rare since 3d hardware acceleration became a thing and raytracing was pretty niche until very recently.