How do I find the orientation relative to another orientation? (Maths)

How do I find the relative orientation degree?
So basically I want to find the y orientation of the red axis relative to the green axis


Because I want to make a car that goes to the point

local backwheelspeed = 5
local frontwheelspeed = 25
local base = script.Parent.Base
local function grrfp(e)
	local x,y,z = CFrame.new(base.Position-base.CFrame.LookVector.Unit/(base.Size.Z/2),e.Position):ToOrientation()
	local er = game.ReplicatedStorage.Arrow:Clone()
	er.Parent=workspace
	er.CanCollide = false
	er.Anchored=true
	game:GetService("Debris"):AddItem(er,.05)
	er.Position=base.Position-base.CFrame.LookVector.Unit/(base.Size.Z/2)
	er.Orientation=Vector3.new(0,math.deg(y),0)
	er.Size=Vector3.new(5,25,25)
	er.Transparency=.3
	er.Material=Enum.Material.Neon
	er.BrickColor=BrickColor.Red()
	local ers = game.ReplicatedStorage.Arrow:Clone()
	ers.Parent=workspace
	ers.CanCollide = false
	ers.Anchored=true
	game:GetService("Debris"):AddItem(ers,.05)
	ers.Position=base.Position-base.CFrame.LookVector.Unit/(base.Size.Z/2)
	ers.Orientation=Vector3.new(0,base.Orientation.Y+180,0)
	ers.Size=Vector3.new(5,25,25)
	ers.Transparency=.3
	ers.Material=Enum.Material.Neon
	ers.BrickColor=BrickColor.Green()
	return math.deg(y)-(base.Orientation.Y+180)
end
while wait() do
	for i,v in pairs(script.Parent:GetChildren()) do
		if v:IsA("BasePart") then
			if string.find(string.lower(v.Name),"bw") then
				if string.sub(string.lower(v.Name),1,1)=="l" then
					v.CylindricalConstraint.AngularVelocity=-backwheelspeed
				elseif string.sub(string.lower(v.Name),1,1)=="r" then
					v.CylindricalConstraint.AngularVelocity=backwheelspeed
				end
			elseif string.find(string.lower(v.Name),"fw") then
				local ordif = grrfp(workspace.Ve)
				if string.sub(string.lower(v.Name),1,1)=="l" then
					v.CylindricalConstraint.AngularVelocity=-frontwheelspeed
					v.Attachment.Orientation=Vector3.new(0,math.clamp(-ordif,-45,45),0)
				elseif string.sub(string.lower(v.Name),1,1)=="r" then
					v.CylindricalConstraint.AngularVelocity=frontwheelspeed
					v.Attachment.Orientation=Vector3.new(0,math.clamp(ordif,-45,45),0)
				end
			end
		end
	end
end

Thanks in advance

1 Like

a:Inverse()*b gets b’s CFrame relative to a
You can then use
local x,y,z = (a:Inverse()*b):ToEulerAnglesXYZ() to complete this

4 Likes

I believe that @PapaBreadd’s answer is correct. All I want to say is that CFrame usually comes with built-in support for these kind of problems. I have wasted a lot of time by trying to get into the maths for these types of problems in the past. CFrame itself is usually a lot easier to use than the raw maths.

What do you mean a:Inverse()*b?
What is a and what is b?
I’m trying to get an orientation y and using math.deg() to compare it to the orientation of the base, which is the main part of the car to see if it should go left or right.

a and b are both cframes

a would likely be the base
b would likely be the “degree”
You could create b using something like:
CFrame.new(0,math.rad(degrees),0)

Doesn’t that just make a new cframe with the y position of math.rad(degrees)?
Let me reiterate. If you look at my while loop, the attachment’s Y orientation is being set ordif or -ordif, with a minimum of -45 and maximum of 45. Ordif is the amount of degrees between the Y rotation of the base part, and the Y rotation of the CFrame which describes an orientation of the position of the front of the base part, to e, the part which the function is doing.


So, if the Y rotation of the base part was 15, and the Y rotation of a the front position of the base part facing the “e” part is 60, that would mean the relative Y orientation would be 45, which I would set as “ordif” for the Y orientation of my wheel attachments.
Likewise, if the Y rotation of a the front position of the base part facing the “e” part was -70, then the relative y orientation would be -55.
My equiation right now though, says that ordif is Y rotation of a the front position of the base part facing the “e” part MINUS the Y orientation of the base part, regardless if the Y rotation of a the front position of the base part facing the “e” part was in the negatives or not.

Oh I apologize I meant CFrame.Angles(0,math.rad(60),0)

A simple:
local y = (base.CFrame:Inverse()*CFrame.Angles(0,math.rad(60),0)):ToEulerAnglesYXZ()
Should work

Nope. Still doesn’t work. Not only do I not know where to put it, but I don’t even know how I would return it
Here, I’ve uploaded a roblox model for you to test out. It’s got the car and the part where the car is supposed to go to. CarModel.rbxm (8.9 KB)

Do me a favor and test it out and tell me when you’ve figured out a way to solve it, or applied what you already told me because I have not a single clue how to apply your equation into my code.

Can anyone help me? I’m a really stuck on this problem at the moment :sweat_smile:

Another method is to measure the angle between the vectors, or Angle between signed from this neat module. Basically measure the angle between the vehicles look vector and the direction vector from the position of the vehicle towards the target position, relative to the cars up axis which will make the angle + or - depending on which way to turn ex: +30 degrees turn right, -30 degrees turn left, I suggest print debugging to make sure the angle outputting makes sense.

I’m not trying to get the angle between two vectors. I’m not even trying to work with vectors. I’m trying to work with DEGREES, not radians, not vectors, and I’m trying to find out the relative degree of a degree against another degree. So far example, if the base degree was 220, and the direction degree was 30, the relative direction degree would be 60.
If the base degree was 45, and the direction degree was 75, then the relative direction degree would be 30.
If the base degree was 350, and the direction degree was 180, then the relative direction degree would be -170.

Another thing I would like to point out is that if the negative relative degree needed to get to the absolute direction degree is higher than the positive relative degree needed to get to the absolute direction degree, the positive relative degree would be chosen.
For example, if the base degree was 0, and the absolute direction degree was 170, you could either go +170 or -190.
It would choose +170, making it go right.

you can measure the angle between two vectors, it’s right there in your diagram. See those two lines you drew, they are two vectors. Might wanna touch up your math.

Edit: The red vector represents the cars look vector.
The green vector represents the car to target position vector.
If you use the function VectorUtil.AngleBetweenSigned(vector1, vector2, axisVector)
It will output the angle in radians which you can convert to degrees.

They aren’t vectors. Vectors are like (1,-.2,.3), whereas what I want the DEGREE, is just a number from -360 to 360

And the thing he recommended you gives RADIANS, which you can convert to degrees by using either the math.deg(x) function from the math library, or by multiplying your result by 180/pi.

This should work, I’ve tested it within studio.

local VectorUtil = {}


function VectorUtil.ClampMagnitude(vector, maxMagnitude)
	return (vector.Magnitude > maxMagnitude and (vector.Unit * maxMagnitude) or vector)
end


function VectorUtil.AngleBetween(vector1, vector2)
	return math.acos(math.clamp(vector1.Unit:Dot(vector2.Unit), -1, 1))
end


function VectorUtil.AngleBetweenSigned(vector1, vector2, axisVector)
	local angle = VectorUtil.AngleBetween(vector1, vector2)
	return angle * math.sign(axisVector:Dot(vector1:Cross(vector2)))
end


local backwheelspeed = 5
local frontwheelspeed = 25
local base = script.Parent.Base
local function grrfp(e)
	local x,y,z = CFrame.new(base.Position-base.CFrame.LookVector.Unit/(base.Size.Z/2),e.Position):ToOrientation()
	local er = game.ReplicatedStorage.Arrow:Clone()
	er.Parent=workspace
	er.CanCollide = false
	er.Anchored=true
	game:GetService("Debris"):AddItem(er,.05)
	er.Position=base.Position-base.CFrame.LookVector.Unit/(base.Size.Z/2)
	er.Orientation=Vector3.new(0,math.deg(y),0)
	er.Size=Vector3.new(5,25,25)
	er.Transparency=.3
	er.Material=Enum.Material.Neon
	er.BrickColor=BrickColor.Red()
	local ers = game.ReplicatedStorage.Arrow:Clone()
	ers.Parent=workspace
	ers.CanCollide = false
	ers.Anchored=true
	game:GetService("Debris"):AddItem(ers,.05)
	ers.Position=base.Position-base.CFrame.LookVector.Unit/(base.Size.Z/2)
	ers.Orientation=Vector3.new(0,base.Orientation.Y+180,0)
	ers.Size=Vector3.new(5,25,25)
	ers.Transparency=.3
	ers.Material=Enum.Material.Neon
	ers.BrickColor=BrickColor.Green()
	local dir = e.Position - base.CFrame.Position
	return -math.deg(VectorUtil.AngleBetweenSigned(base.CFrame.LookVector,dir,base.CFrame.UpVector))
end
while wait() do
	for i,v in pairs(script.Parent:GetChildren()) do
		if v:IsA("BasePart") then
			if string.find(string.lower(v.Name),"bw") then
				if string.sub(string.lower(v.Name),1,1)=="l" then
					v.CylindricalConstraint.AngularVelocity=-backwheelspeed
				elseif string.sub(string.lower(v.Name),1,1)=="r" then
					v.CylindricalConstraint.AngularVelocity=backwheelspeed
				end
			elseif string.find(string.lower(v.Name),"fw") then
				local ordif = grrfp(workspace.Ve)
				if string.sub(string.lower(v.Name),1,1)=="l" then
					v.CylindricalConstraint.AngularVelocity=-frontwheelspeed
					v.Attachment.Orientation=Vector3.new(0,math.clamp(-ordif,-45,45),0)
				elseif string.sub(string.lower(v.Name),1,1)=="r" then
					v.CylindricalConstraint.AngularVelocity=frontwheelspeed
					v.Attachment.Orientation=Vector3.new(0,math.clamp(ordif,-45,45),0)
				end
			end
		end
	end
end
1 Like

Thank you for this. How do I make the ordif closer to 0 when the target part is in front of the base part and closer to 180 or -180 when the target part is in the back of the base part? The reason I want to do this is because I want to stress the importance of steering if the target is in the back of you, rather than putting on full force if you can see the target right in front of you, and also the car moves right and left and right and left and right if the target part is in front of the base part and not to the sides of it, causing a weird movement

Use PID to adjust the steering the issue is the force being applied is not balanced which causes the car to overshoot the goal and hence cause oscillation which is the fancy term for what you call the “weird movement”. The goal angle trying to be achieved is an angle of 0 degrees, and the current angle is the one being inputted by the grrfp function.

1 Like