Need help with calculating vector proportions

Hello guys. Today, I tried to do some vector math. But I got 1 problem which IDK how to solve myself:
image
There’s 3 vectors: Right, Up, Look, and black dot resembles another UNIT vector - Result, which is combination of Right Up and Look vectors by some amount XYZ. How I can calculate how much each vector “contributed” to resulting vector, knowing:
RightVector
UpVector
LookVector
Result vector
(Result vector is grabbed by random)

Note: Vectors can be rotated like so:
image

1 Like

For this, you’d just find the average of the 3 vectors (so sum all 3 vectors then divide by 3), then get the unit vector of said summed up vector (so just index it for .Unit or divide the vector by its own magnitude)

local directionPart = Instance.new('Part')
directionPart.Size = Vector3.new(0.25, 0.25, 0.25)
directionPart.Anchored = true
directionPart.CanCollide = false

local targetPart = workspace:WaitForChild('Part')

directionPart.Parent = workspace

while true do
	local targetCFrame = targetPart.CFrame
	
	local right = targetCFrame.RightVector
	local up = targetCFrame.UpVector
	local look = targetCFrame.LookVector
	
	directionPart.Position = targetPart.Position + ((right + look + up) / 3).Unit -- if you are working with arbitrary vectors you'd probably need to implement a nan check in the case of all 3 vectors being the same but for orthagonal vectors you'd be fine
	
	task.wait()
end

Won’t work if ResultVector is something like this(0.5, 0.75, 0.1).Unit, and Right, Up, Look vectors are regular XYZ ones for example

1 Like

I misread your question entirely. I thought you meant you were trying to generate the black dot from each of the 3 axes, that’s my bad entirely.

You can check how much each axis “contributed” to the resulting vector by using the dot product, in this case what the dot product will do is tell you how similar a vector is to another vector on a scale of -1 to positive 1.

Do note though, that this isn’t really contribution since the vectors didn’t really contribute to the resulting vector, it’s more so finding out how similar the vectors are.

When two vectors’ dot products is -1, the two vectors face away from one another.
When two vectors’ dot products is 0, the two vectors are perpendicular.
When two vectors’ dot products is +1, the two vectors are the same.

So what we can do to find how similar each vector is to the other is simply:

local contribution = vec:Dot(resultVector)

For a test:

local directionPart = Instance.new('Part')
directionPart.Size = Vector3.new(0.25, 0.25, 0.25)
directionPart.Anchored = true
directionPart.CanCollide = false

local function visualizeVector(origin, vector, colour)
	local directionPartClone = directionPart:Clone()
	directionPartClone.Color = colour
	directionPartClone.Position = origin + vector
	directionPartClone.CFrame = CFrame.lookAt((origin * 2 + vector) / 2, origin + vector)
	directionPartClone.Size = Vector3.new(0.1, 0.1, vector.Magnitude)
	directionPartClone.Parent = workspace
	
	local billboard = Instance.new('BillboardGui')
	billboard.Size = UDim2.fromScale(1, 1)
	billboard.AlwaysOnTop = true
	billboard.Adornee = directionPartClone
	billboard.Parent = directionPartClone
	
	local label = Instance.new('TextLabel')
	label.Size = UDim2.fromScale(1, 1)
	label.BackgroundTransparency = 1
	label.TextScaled = true
	label.Parent = billboard
	
	directionPartClone.Changed:Connect(function()
		label.Text = directionPartClone.Name
	end)
	
	return directionPartClone
end

local vecs = {}

for i = 1, 3 do
	local dir = Random.new():NextUnitVector()
	
	table.insert(vecs, dir)
	
	visualizeVector(Vector3.zero, dir, Color3.fromHSV(i / 3, 1, 1)).Name = i
end

local final = Random.new():NextUnitVector()

visualizeVector(Vector3.zero, final, Color3.new()).Name = 'ResultVector'

for i, vec in vecs do
	local dot = vec:Dot(final)
	print(i, '"contributed" to ResultVector by', dot)
end

When each direction is far from the ResultVector results in:

When a direction (2, blue) is close, we get a larger dot product:

And finally, when the point is at 1, 1, -1 and each axis is axis-parallel to the world, we see that all of the dot products are the same because each axis “contributed” an equal amount.

local cf = workspace.Origin.CFrame
local vecs = {
	cf.RightVector;
	cf.UpVector;
	cf.LookVector;
}

local final = workspace.Part.Position.Unit

visualizeVector(Vector3.zero, final, Color3.new()).Name = 'ResultVector'

for i, vec in vecs do
	local dot = vec:Dot(final)
	print(i, '"contributed" to ResultVector by', dot)
end
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.