GSmGpE6CwX2y9JjB25B8
We use cookies on this site to enhance your user experience

Cross product

Cross product

Aug 29 2019, 9:22 AM PST

The cross product, also commonly known as the vector product, is an operation preformed on two three-dimensional vectors and returns a third vector that is perpendicular to the other two. The mathematics behind the cross product can be a little scary at first, but this article aims to break it down so that you can use it in your games!

Prerequisites

This article will require a solid understanding of vectors. It is suggested that you read the Vector3 page. You are also highly recommended to read the dot product article as it will be used to prove certain aspects of the cross product.

The cross product

Believe it or not, the uses of the cross product are pretty straight forward. As mentioned in the introduction, the cross product will return a vector that is perpendicular to the other two. So what does this actually look like?

Cross1.png

The cross product is written mathematically as putting an “x” between two vectors: AxB

Now without even going into the math you may have already noticed that there are two possible vectors that are perpendicular to a and b. There is the one drawn in the image above (AxB), but there is also the vector completely opposite to that -(AxB). So can the cross product calculate -(AxB)? The answer: totally! Simply swap the order: (BxA

-(AxB) and AxB

-(BxA)).

The next question is how do we know which of the two directions the cross product is facing? It is one thing to know that swapping the order gives us the other direction, but trying to figure out exactly what this direction is by trial and error is never a good thing.

Right hand rule

Cross2.png

By using what we call the right hand rule we figure out which of the two directions our cross product is going in. Here’s how we do it:

  • Point all your fingers (excluding your thumb, keep that pointing out) in the direction of the first vector in the cross product.
  • If you can curl all those fingers towards the second vector then your cross product will be in the direction of your thumb.
  • If you couldn’t curl your fingers flip your hand over and try again.

If you did it correctly you will know which direction your cross product is going in.

This concept can be hard to grasp over text. As such, it’s recommended you watch this video by BraunVideos to get a better visualization.

How do we calculate the cross product?

Okay, so we have done enough beating around the bush. It is about time we actually talked about how to calculate this thing. This formula may seem daunting at first, but after we’ve had a look at it we’ll examine the pattern behind the formula.

So here’s a function to calculate the cross product:

code|
function cross(a, b)
return Vector3.new(
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x
)
end

So as mentioned above this seems like a pain to memorize, but in reality it’s not. You just have to memorize these steps.

  1. Take the like components of our two vectors and set them into columns (first vector on top, second on the bottom):

Cross3.png

  1. The next thing we are going to do is repeat the first two columns and place them right beside our current table:

Cross4.png

  1. Now starting with the first vector in the y-column we are going pick the value diagonally downward right (the second vector’s z-value) and multiply. We are then going to subtract from that value the first vector’s z column multiplied by what’s diagonally downward left of it (the second vector’s y-value). Here is this process visualized:

Cross5.gif

This is your new x-value

  1. Starting with the first vector in the original z-column we are going pick the value diagonally downward right (the second vector’s x-value) and multiply. We are then going to subtract from that value the first vector’s x column multiplied by what’s diagonally downward left of it (the second vector’s z-value). Here is this process visualized:

Cross6.gif

This is your new y-value

  1. Starting with the first vector in the original x-column we are going pick the value diagonally downward right (the second vector’s y-value) and multiply. We are then going to subtract from that value the first vector’s y column multiplied by what’s diagonally downward left of it (so the second vector’s x-value). Here is this process visualized:

Cross7.gif

This is your new z-value

So that’s it! We now know how to calculate the cross product!

Perpendicular proof?

Alright, so far I’ve mentioned a few times that the cross product of two vectors creates a new vector that has a direction perpendicular to the two vectors used to create it. Sometimes when initially learning something it’s useful to take what’s told to you for granted, but it is time to take the training wheels off, let’s prove it!

As we know when we take the dot product of two vectors that are perpendicular to each other the result is zero since the cosine of 90 degrees is 0. As such, if we take the dot product of our cross and either of the two vectors our result should be zero:

Cross10.png

You are encouraged to try the same thing with BxA

The magnitude of the cross product

So far we have only really been talking about the direction of the cross product, but what about the magnitude? It actually has a really awesome property to it, that is useful in some circumstances.

The magnitude of the cross product of two vectors is actually the area of the parallelogram that they create as seen in the image below again:

Cross1.png

That means that the area of our cross product is equal to ||A||*||B||*Sinθ

Now the proof for this can get very messy and making math equations that are visible on the wiki is no easy task. As a result it is suggested that you watch this video by Khan academy for the proof.

Conclusion

So we now understand what the cross product can do, but what can we use it for? Unlike the dot product the cross product has significantly less uses. That being said, here are two broad uses:

Cross11.png

An example of the cross product in use: rotated placement

Sometimes you may find yourself creating a studio plugin or tool where you want to place objects on a rotated surface. Without the cross product this can be a nightmare! Luckily with a little bit of application of axis-angle rotations and what we have just learned, it’s easy as can be!

So let’s say we have some surface we want to place an object on, and let’s assume we can get the surface’s normal with the FindPartOnRay method:

Cross8.png

If we get the cross product with the normal vector and Vector3.new(0, 1, 0) we can actually get two pieces of information. The first is the direction of the cross product which we can treat as our axis of rotation. The second is the angle between the two vectors.

Cross9.png

With these two pieces of information we can easily use the fromAxisAngle CFrame constructor to properly rotate our object!

local mouse = game.Players.LocalPlayer:GetMouse()
local moveModel = workspace:WaitForChild("Wood Crate")

-- don't detect the model we're moving
mouse.TargetFilter = moveModel

function placeAtMouse()
	-- make sure the mouse is pointing at something
	if mouse.Target then
		-- where we cast our ray from (shifted slightly up so the ray will hit the surface we're hovering)
		local origin = mouse.Hit.p + Vector3.new(0, 0.1, 0)
		
		-- cast our ray and get our normal, which is a unit vector
		local ray = Ray.new(origin, Vector3.new(0, -1, 0))
		local hit, pos, normal = workspace:FindPartOnRay(ray, moveModel)
		
		-- get the perpendicular vector and the angle between the two
		local cross = Vector3.new(0, 1, 0):Cross(normal)
		local angle = math.asin(cross.magnitude) -- division by 1 is redundant
		
		moveModel:SetPrimaryPartCFrame(
			CFrame.new(mouse.Hit.p + normal * moveModel:GetModelSize().y/2) -- position
			* CFrame.fromAxisAngle(cross.magnitude == 0 and Vector3.new(1) or cross.unit, angle) -- angle, cross must not be Vector3.new()
		)
	end
end

-- check every frame
game:GetService("RunService").RenderStepped:connect(function()
	placeAtMouse()
end)

See also