Advanced vector math
Planes
The dot product has another interesting property with unit vectors.Imagine that perpendicular to that vector (and through the origin)passes a plane. Planes divide the entire space into positive(over the plane) and negative (under the plane), and (contrary topopular belief) you can also use their math in 2D:

Unit vectors that are perpendicular to a surface (so, they describe theorientation of the surface) are calledunit normal vectors. Though,usually they are just abbreviated asnormals. Normals appear inplanes, 3D geometry (to determine where each face or vertex is siding),etc. Anormalis aunit vector, but it's callednormalbecause of its usage. (Just like we call (0,0) the Origin!).
The plane passes by the origin and thesurface of it is perpendicular to the unit vector (ornormal). Theside the vector points to is the positive half-space, while theother side is the negative half-space. In 3D this is exactly the same,except that the plane is an infinite surface (imagine an infinite, flatsheet of paper that you can orient and is pinned to the origin) insteadof a line.
Distance to plane
Now that it's clear what a plane is, let's go back to the dot product.The dot product between aunit vector and anypoint in space(yes, this time we do dot product between vector and position), returnsthedistance from the point to the plane:
vardistance=normal.dot(point)
vardistance=normal.Dot(point);
But not just the absolute distance, if the point is in the negative halfspace the distance will be negative, too:

This allows us to tell which side of the plane a point is.
Away from the origin
I know what you are thinking! So far this is nice, butreal planes areeverywhere in space, not only passing through the origin. You want realplane action and you want itnow.
Remember that planes not only split space in two, but they also havepolarity. This means that it is possible to have perfectly overlappingplanes, but their negative and positive half-spaces are swapped.
With this in mind, let's describe a full plane as anormalN and adistance from the origin scalarD. Thus, our plane is representedby N and D. For example:

For 3D math, Godot provides aPlanebuilt-in type that handles this.
Basically, N and D can represent any plane in space, be it for 2D or 3D(depending on the amount of dimensions of N) and the math is the samefor both. It's the same as before, but D is the distance from the originto the plane, travelling in N direction. As an example, imagine you wantto reach a point in the plane, you will just do:
varpoint_in_plane=N*D
varpointInPlane=N*D;
This will stretch (resize) the normal vector and make it touch theplane. This math might seem confusing, but it's actually much simplerthan it seems. If we want to tell, again, the distance from the point tothe plane, we do the same but adjusting for distance:
vardistance=N.dot(point)-D
vardistance=N.Dot(point)-D;
The same thing, using a built-in function:
vardistance=plane.distance_to(point)
vardistance=plane.DistanceTo(point);
This will, again, return either a positive or negative distance.
Flipping the polarity of the plane can be done by negating bothN and D. This will result in a plane in the same position, but withinverted negative and positive half spaces:
N=-ND=-D
N=-N;D=-D;
Godot also implements this operator inPlane.So, using the format below will work as expected:
varinverted_plane=-plane
varinvertedPlane=-plane;
So, remember, the plane's main practical use is that we cancalculate the distance to it. So, when is it useful to calculate thedistance from a point to a plane? Let's see some examples.
Constructing a plane in 2D
Planes clearly don't come out of nowhere, so they must be built.Constructing them in 2D is easy, this can be done from either a normal(unit vector) and a point, or from two points in space.
In the case of a normal and a point, most of the work is done, as thenormal is already computed, so calculate D from the dot product ofthe normal and the point.
varN=normalvarD=normal.dot(point)
varN=normal;varD=normal.Dot(point);
For two points in space, there are actually two planes that pass throughthem, sharing the same space but with normal pointing to the oppositedirections. To compute the normal from the two points, the directionvector must be obtained first, and then it needs to be rotated 90degrees to either side:
# Calculate vector from `a` to `b`.vardvec=point_a.direction_to(point_b)# Rotate 90 degrees.varnormal=Vector2(dvec.y,-dvec.x)# Alternatively (depending the desired side of the normal):# var normal = Vector2(-dvec.y, dvec.x)
// Calculate vector from `a` to `b`.vardvec=pointA.DirectionTo(pointB);// Rotate 90 degrees.varnormal=newVector2(dvec.Y,-dvec.X);// Alternatively (depending the desired side of the normal):// var normal = new Vector2(-dvec.Y, dvec.X);
The rest is the same as the previous example. Either point_a orpoint_b will work, as they are in the same plane:
varN=normalvarD=normal.dot(point_a)# this works the same# var D = normal.dot(point_b)
varN=normal;varD=normal.Dot(pointA);// this works the same// var D = normal.Dot(pointB);
Doing the same in 3D is a little more complex and is explainedfurther down.
Some examples of planes
Here is an example of what planes are useful for. Imagine you haveaconvexpolygon. For example, a rectangle, a trapezoid, a triangle, or just anypolygon where no faces bend inwards.
For every segment of the polygon, we compute the plane that passes bythat segment. Once we have the list of planes, we can do neat things,for example checking if a point is inside the polygon.
We go through all planes, if we can find a plane where the distance tothe point is positive, then the point is outside the polygon. If wecan't, then the point is inside.

Code should be something like this:
varinside=trueforpinplanes:# check if distance to plane is positiveif(p.distance_to(point)>0):inside=falsebreak# with one that fails, it's enough
varinside=true;foreach(varpinplanes){// check if distance to plane is positiveif(p.DistanceTo(point)>0){inside=false;break;// with one that fails, it's enough}}
Pretty cool, huh? But this gets much better! With a little more effort,similar logic will let us know when two convex polygons are overlappingtoo. This is called the Separating Axis Theorem (or SAT) and mostphysics engines use this to detect collision.
With a point, just checking if a planereturns a positive distance is enough to tell if the point is outside.With another polygon, we must find a plane wherealltheotherpolygonpoints return a positive distance to it. This check isperformed with the planes of A against the points of B, and then withthe planes of B against the points of A:

Code should be something like this:
varoverlapping=trueforpinplanes_of_A:varall_out=trueforvinpoints_of_B:if(p.distance_to(v)<0):all_out=falsebreakif(all_out):# a separating plane was found# do not continue testingoverlapping=falsebreakif(overlapping):# only do this check if no separating plane# was found in planes of Aforpinplanes_of_B:varall_out=trueforvinpoints_of_A:if(p.distance_to(v)<0):all_out=falsebreakif(all_out):overlapping=falsebreakif(overlapping):print("Polygons Collided!")
varoverlapping=true;foreach(PlaneplaneinplanesOfA){varallOut=true;foreach(Vector3pointinpointsOfB){if(plane.DistanceTo(point)<0){allOut=false;break;}}if(allOut){// a separating plane was found// do not continue testingoverlapping=false;break;}}if(overlapping){// only do this check if no separating plane// was found in planes of Aforeach(PlaneplaneinplanesOfB){varallOut=true;foreach(Vector3pointinpointsOfA){if(plane.DistanceTo(point)<0){allOut=false;break;}}if(allOut){overlapping=false;break;}}}if(overlapping){GD.Print("Polygons Collided!");}
As you can see, planes are quite useful, and this is the tip of theiceberg. You might be wondering what happens with non convex polygons.This is usually just handled by splitting the concave polygon intosmaller convex polygons, or using a technique such as BSP (which is notused much nowadays).
Collision detection in 3D
This is another bonus bit, a reward for being patient and keeping upwith this long tutorial. Here is another piece of wisdom. This mightnot be something with a direct use case (Godot already does collisiondetection pretty well) but it's used by almost all physics engines and collisiondetection libraries :)
Remember that converting a convex shape in 2D to an array of 2D planeswas useful for collision detection? You could detect if a point wasinside any convex shape, or if two 2D convex shapes were overlapping.
Well, this works in 3D too, if two 3D polyhedral shapes are colliding,you won't be able to find a separating plane. If a separating plane isfound, then the shapes are definitely not colliding.
To refresh a bit a separating plane means that all vertices of polygon Aare in one side of the plane, and all vertices of polygon B are in theother side. This plane is always one of the face-planes of eitherpolygon A or polygon B.
In 3D though, there is a problem to this approach, because it ispossible that, in some cases a separating plane can't be found. This isan example of such situation:

To avoid it, some extra planes need to be tested as separators, theseplanes are the cross product between the edges of polygon A and theedges of polygon B

So the final algorithm is something like:
varoverlapping=trueforpinplanes_of_A:varall_out=trueforvinpoints_of_B:if(p.distance_to(v)<0):all_out=falsebreakif(all_out):# a separating plane was found# do not continue testingoverlapping=falsebreakif(overlapping):# only do this check if no separating plane# was found in planes of Aforpinplanes_of_B:varall_out=trueforvinpoints_of_A:if(p.distance_to(v)<0):all_out=falsebreakif(all_out):overlapping=falsebreakif(overlapping):foreainedges_of_A:forebinedges_of_B:varn=ea.cross(eb)if(n.length()==0):continuevarmax_A=-1e20# tiny numbervarmin_A=1e20# huge number# we are using the dot product directly# so we can map a maximum and minimum range# for each polygon, then check if they# overlap.forvinpoints_of_A:vard=n.dot(v)max_A=max(max_A,d)min_A=min(min_A,d)varmax_B=-1e20# tiny numbervarmin_B=1e20# huge numberforvinpoints_of_B:vard=n.dot(v)max_B=max(max_B,d)min_B=min(min_B,d)if(min_A>max_Bormin_B>max_A):# not overlapping!overlapping=falsebreakif(notoverlapping):breakif(overlapping):print("Polygons collided!")
varoverlapping=true;foreach(PlaneplaneinplanesOfA){varallOut=true;foreach(Vector3pointinpointsOfB){if(plane.DistanceTo(point)<0){allOut=false;break;}}if(allOut){// a separating plane was found// do not continue testingoverlapping=false;break;}}if(overlapping){// only do this check if no separating plane// was found in planes of Aforeach(PlaneplaneinplanesOfB){varallOut=true;foreach(Vector3pointinpointsOfA){if(plane.DistanceTo(point)<0){allOut=false;break;}}if(allOut){overlapping=false;break;}}}if(overlapping){foreach(Vector3edgeAinedgesOfA){foreach(Vector3edgeBinedgesOfB){varnormal=edgeA.Cross(edgeB);if(normal.Length()==0){continue;}varmaxA=float.MinValue;// tiny numbervarminA=float.MaxValue;// huge number// we are using the dot product directly// so we can map a maximum and minimum range// for each polygon, then check if they// overlap.foreach(Vector3pointinpointsOfA){vardistance=normal.Dot(point);maxA=Mathf.Max(maxA,distance);minA=Mathf.Min(minA,distance);}varmaxB=float.MinValue;// tiny numbervarminB=float.MaxValue;// huge numberforeach(Vector3pointinpointsOfB){vardistance=normal.Dot(point);maxB=Mathf.Max(maxB,distance);minB=Mathf.Min(minB,distance);}if(minA>maxB||minB>maxA){// not overlapping!overlapping=false;break;}}if(!overlapping){break;}}}if(overlapping){GD.Print("Polygons Collided!");}
More information
For more information on using vector math in Godot, see the following article:
If you would like additional explanation, you should check out3Blue1Brown's excellent video seriesEssence of Linear Algebra.