When do I have to use Vector:dot() or Vektror:cross() and what exactly can I use them for in 3D space (workspace)?

1. What do you want to achieve? Keep it simple and clear!
Because :dot and :cross learn and understand how I can best use them.

2. What is the issue? Include screenshots / videos if possible!
I don’t know how to use it.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I look the explanation of Egomoose.

Here is the link for the Dot and the Cross

5 Likes

The dot product of two vectors A, and B given A:Dot(B) is the same as:

A.Magnitude * B.Magnitude * Cos( Theta ) 

Where Theta is the angle between the vectors A and B. This is very useful when used with knowledge of trig, or to get the angle between vectors. The case study in the Dot example is one use, another frequent use of the Dot product is to quickly get the angle between two vectors by doing:

math.acos(A:Dot(B) / (A.Magnitude * B.Magnitude))

Or using unit vectors (Vectors with a magnitude of 1) then the division is not necessary.

The Cross product of two Vectors will give you a new Vector which is perpendicular to both. i.e if you have two vectors Vector3.new(1,0,0) and Vector3.new(0,0,1) then the Cross product will give you ± Vector3.new(0,1,0)

An example use would be; to get the surface normal of a Triangle.

Case study: Rotating a turret to face in a direction, with a maximum turn rate

local GoalDirection = Vector3.new(1,1,0) 
local TurretCFrame = CFrame.new(Vector3.new(), Vector3.new(-1,0,1))
local TurnRateDegrees = 10 --Max turn rate 10 degrees per second

local LastBeat = tick()
game:GetService("RunService").Heartbeat:Connect(function()
    local dT = tick() - LastBeat
    --Distance = Speed * Time, Speed = TurnRateDegrees, Time = dT
    local StepTurnMax = TurnRateDegrees * dT

    local CurrentDirection = TurretCFrame.LookVector
    --Get the angle in radians between current direction and goal direction
    --unit vector magnitude is 1, therefore no division needed
    --Convert to degrees to match our StepTurnMax
    local TurnAngle = math.deg( math.acos(CurrentDirection.unit:Dot(GoalDirection.unit)) )
	print(TurnAngle)
    local TurnAxis = CurrentDirection:Cross(GoalDirection)
    --Limit the angle of turning to the maximum for the beat
    local TurnAmount = math.clamp(TurnAngle, -StepTurnMax, StepTurnMax)
    --Rotate the Turret CFrame to make it face by the Turn amount
    --It'll rotate about the cross product of the two vectors, imagine a 
    --pin through the crossproduct, that it turns about / hinges about
    --convert back to radians for the CFrame rotation
    TurretCFrame = CFrame.fromAxisAngle(TurnAxis,math.rad(TurnAmount)) * TurretCFrame
    LastBeat = tick()
end)

If you were to run this in studio, you would see the angle difference would decrease by 10 degrees per second, so it’d take 12 seconds for the turret to rotate to face it’s target direction (which was 120 angle diff between the two)

EgoMoose’s articles are extremely detailed, certainly more so than my answer so I don’t really know how to help you beyond an example use for both.

43 Likes

@fret13103, Very detailed and easily explained. Thank you! P.S.: What can I do with the dot product, I understood the cross but unfortunately not the dot and what does P.S. mean? I’m sorry for all these questions, but I’m not good at math and I haven’t learned these functions yet.

1 Like

You can use the dot product to find the cosine of the angle between two vectors, or the angle itself. You can then use that for any trig you want to do. Because it’s the cosine you can then project the hypotenuse onto the adjacent, which was EgoMoose’s case study point. It’s very useful in general. It’s very useful for working with trig identities, reflections, things like lighting or surface normals in engines and shaders.

4 Likes

is there a specific method to find the sin of an angle or would u just use cosine to find sine?

2 Likes

The magnitude of the cross product is:

A.Magnitude * B.Magnitude * sin(Theta)

2 Likes

Dot product is also useful for checking two things are pointing the same way or not.

If you had a car that drives over a sensor, and you only want the sensor to do something if the car drives over it forwards, but ignore it if the car drives over it in the opposite direction, you can do for product on its velocity and the lookvector of the sensor.

local sensor = game.Workspace.YourSensor

sensor.Touched:Connect( function ( carPart )
    if not carPart:IsDescendantOf( the car ) then
        return
    end

    if carPart.Velocity:Dot( sensor.CFrame.lookVector ) > 0 then
        -- car drove over the sensor in the correct direction
    else
        -- car drove over the sensor the wrong way (or isn't moving at all)
    end
end )

If the velocity and the sensor point in opposite directions, the dot value is negative, and if they are perfectly perpendicular, the dot value is 0.

7 Likes

Hey that’s cool.
Is it always positive?

1 Like

Consider the cos function, cos(90 deg) is 0 and cos(90 < theta < 270) is negative.Values between -90 and 90 will be positive in the same manner.

2 Likes

@BanTech,

if carPart.Velocity:Dot( sensor.CFrame.lookVector ) > 0 then
    -- car drove over the sensor in the correct direction
else
    -- car drove over the sensor the wrong way (or isn't moving at all)
end

??? If the Dot product is over 0, then the car drove in the correct direction, so he’s going forward (lookVector), right?

1 Like

Not necessarily. If you reverse over the sensor, but you’re moving in the right direction, this will treat it as travelling the correct way.

You could combine with a check against a forward-facing part’s lookVector on the car to make sure it’s also facing forwards.

Alternatively you can swap out the velocity for this forward-facing part’s lookVector if you want to allow the sensor to be triggered when facing the same way, regardless of direction of travel.

Generally velocity is the best idea as if you’re heading towards a gate that you want to open, you’ll need velocity.

1 Like

But I had thought that with the Dot product only the cosinus could get, how can you use it to watch two things looking in the same way or not?

As fret13103 has explained earlier, dot product is equivalent to A.Magnitude * B.Magnitude * Cos( Theta )

Cos( Theta ) is positive if -90 < Theta < 90 (in degrees).

A.Magnitude and B.Magnitude will always be positive, therefore the sign of the result of the dot product will be dependent on the sign of the cosine.

-90 < Theta < 90 means that the two vectors are not perpendicular and are closer to looking in the same direction than they are to looking in opposite directions. It’s not saying they are parallel, it’s just saying they are roughly pointing in the same direction.

If you look at the cosine graph posted by fret13103, at 0 the two are pointing in the same direction, and cos is at a maximum. There is a band of 90 degrees each side of this maximum where cos is still positive due to the vectors having an acute angle to each other. Hope that helps.

1 Like

Thanks, after a long time on the internet and on Youtube, I understand it better now, but I have one last question. If the dot product is above zero, then it’s more like 90 degrees or less, and if the dot product is below zero, then it’s less than 90 degrees or more?

dot > 0 - angle between the vectors is less than 90 degrees in magnitude
(-90 < a < 90).

dot == 0 - angle between the vectors is exactly 90 degrees in magnitude.

dot < 0 - angle between the vectors is greater than 90 degrees in magnitude
(90 < a <= 180 or -180 <= a < -90).

If you take the angle to be bound from -180 to 180 degrees.

3 Likes