Tutorial #3 - Normals - Introduction
These tutorials try to solve basic problems using easy to understand solutions rather than optimized complex math. Basically, this is a simple way of getting to the answer, not an elegant collection of mathematical skill.
What a normal is
When any three points are connected to each other, a plane is formed that is perfectly flat and includes all the three points. A vector is 3 values - x, y, z which give the direction and velocity of any particular point. A normal is a vector which stands perpendicular from the plane. Any value on the plane has the same normal and using the normal, various calculations can be made. Lighting, reflections, decals and per polygon collisions are examples of used and in Tutorial #4, some of these will be explained in detail. A normal also is of length one, this is done by normalizing the vector which is explained a bit later.
How to calculate the normal
In the following examples all the images will show a four point object. This is just because my code uses mostly four point polygons and the points are parallel to each other. To make sure the normal is calculated properly it is best to use only triangles or quads that you know that exist in a plane. First we get two vectors from the triangle, this is done by taking one of the points and subtracting it from the other two (where x, y, z are properly subtracted):

vector1 = point2 - point1
vector2 = point3 - point1

We then do the cross product on the two vectors and come up with only one vector. The calculation for this is done as follows:

vector3.x = (vector1.y * vector2.z) - (vector1.z * vector2.y);
vector3.y = (vector1.z * vector2.x) - (vector1.x * vector2.z);
vector3.z = (vector1.x * vector2.y) - (vector1.y * vector2.x);

Now the only thing left to do is make sure the length is one, which is called normalizing. We first get the current length of the vector and then divide each axis by the length:

length = sqrt((vector3.x)² + (vector3.y)² + (vector3.z)²);

normal.x = vector3.x / length;
normal.y = vector3.y / length;
normal.z = vector3.z / length;

Basic idea of collision detection with normals
Using the normalized normal vector, distance can be calculated from the plane to a point in space. To do this, all that is needed is to get the dot product of the normal and the point. One thing to note is that the distance is looked at from the origin of (0, 0, 0) since the normal resides at that point. To do the calculation right, the point has to be in relation to the center of the triangle. In other words by subtracting the point to be checked by the center will allow the normal to be at the origin. For example, using one axis, if point.x = 20 and center.x = 10, then newPoint.x = point.x - center.x = 20 - 10 = 10. So in relation to the point, the normal is now at the center of the triangle.

As stated above, to calculate the distance of the point from the plane the dot product of the normal and the point have to be calculated using (normal.x * point.x) + (normal.y * point.y) + (normal.z * point.z).

The value will indicate the distance from the plane to the point. If the value is negative then the point is in front, while if negative it is behind and if zero - it is on the plane. It follows that to calculate if a collision occurs anywhere on the plane, a look at if the sign changes will provide the information needed.

This ends the tutorial. As indicated in the beginning, this tutorial is only to give an idea of how to get things going and because of that some cases and/or calculations may be missing or just skipped to simplify things. If anyone has any comments or questions, please feel free to email.
© 2023 Luigi Pino. All rights reserved.
Privacy | Links