Is it possible to calculate the angle between 3 points like this?:
http://gyazo.com/4c31ddabda4c10cc55e4397af102eb11
There exists a relationship between the angle theta between two vectors in any dimensional space and their inner product.
Assuming the function acos
is the inverse trigonometric function arc cosine, innerProduct
is the inner product for the dimensional space, the function magnitude
retrieves the length of the vector,a
is one vector, and b
is another vector, then the relationship between the angle theta and the inner product is...
theta = acos(innerProduct(a, b) / (magnitude(a) * magnitude(b)))
.
In words, the angle between two vectors is equal to the inner product between the vectors divided by the product of their magnitudes.
Knowing that we need the inner product is great, but we actually cannot pick the inner product of the system without a bit more information. We will be justifying that the dot product is a proper inner product that we can use.
Notice that ROBLOX uses a three dimensional orthogonal coordinate system. We know this because if we form a vector space basis for the coordinate system, we can form one with the column space of the 3x3 identity matrix.
The column space of identity matrices have this neat property where elements of the column space are linearly independent. In order words, all vectors in the column space are orthogonal.
Therefore, the dot product is compatible with this coordinate system.
If a
is one vector, b
is another vector, and x
, y
, and z
are dimensions in the three dimensional orthogonal coordinate system, then the dot product will be equivalent to...
dotProduct(a, b) = a.x*b.x + a.y*b.y + a.z*b.z
.
In words, the dot product between two vectors is equal to the sum of the product of their dimensions.
Since square magnitude of a vector is defined as the inner product between the vector and itself, the magnitude of a vector a
in our system is equivalent to...
magnitude(a) = sqrt(a.x*a.x + a.y*a.y + a.z*a.z)
.
This means that we can simplify the relationship into a function of dot products.
theta = acos(dotProduct(a, b) / (sqrt(dotProduct(a, a)) * sqrt(dotProduct(b, b))))
.
Simplified to elementary operations, the angle theta
can be calculated with...
theta = acos((a.x*b.x + a.y*b.y + a.z*b.z) / ( sqrt(a.x*a.x + a.y*a.y + a.z*a.z)*sqrt(b.x*b.x + b.y*b.y + b.z*b.z)))
.
ROBLOX has some nice native functions for visually simplifying this.
function angleBetweenVectors(a, b) return math.acos(a:Dot(b) / (a.magnitude*b.magnitude)) end
The ROBLOX implementation is nice, but if you are doing multiple calculations every frame this may not be optimal as your calculations may worsen user experience. You may want to vouch for using the elementary operations derivation above. Here is an example optimized function...
function angleBetweenVectors(a, b) return math.acos((a.x*b.x + a.y*b.y + a.z*b.z) / ( math.sqrt(a.x*a.x + a.y*a.y + a.z*a.z)*math.sqrt(b.x*b.x + b.y*b.y + b.z*b.z))) end