Get the angle between 2 parts parallel to the ground on X axis

This would be the starting point:

And this is what I want to achieve:

So I need to get an angle between A and B, parallel to the ground. No clue how to do it though. I tried raycasting from both sides of the model to the ground but that would only give me the distance from the ground on each side, no clue how I’d convert that to the angle I showed in the second image.

Looking at your pictures … to get from 1 to 2 you would lower B to where A’s z value is.
Then set both to the same orientation. Very simple stuff.

I cannot do that because it’s a model and it has more parts, the ones I’ve shown are the ones closest to the ground.

This looks like 2 parts in one model, welded together. and you want the model to sit flat on the ground? I’d just turn on collision and unanchor it. Both parts will try to touch the ground which is the intended final spot.

Otherwise, the angle is based on basic trig. I think it goes like this:

tan(theta) = opposite side (Y difference) / adjacent side (sqrt (X difference^2 + Z difference^2))

I managed to get the angle by raycasting from both sides of the model. I’m gonna give an example of how I’ve calculated the angle in case anybody else may need it, keep in mind it’s not tested too much so it may fail at certain situations.

local function AllignToGround(model)
	local partA = model['Part A']
	local partB = model['Part B']
	local oldAngle = model.Body.Orientation.X
	local angleIncrement = 0
	local offGroundA
	local offGroundB
	local biggerDifference
	local smallerDifference
	local smallerDifferencePart

    --[[ sets the current difference, checks which side of the model is closer to the ground
         and then sets the angleIncrement accordingly so the model rotates to the correct side ]]--
	
	local function CalculateDifference()
		offGroundA = FloorCheck(partA) -- raycasting, function returns the distance between the part and the ground
		offGroundB = FloorCheck(partB)
		if offGroundA < offGroundB then 
			angleIncrement = 1 
			biggerDifference = offGroundB
			smallerDifference = offGroundA
			smallerDifferencePart = partA
		elseif offGroundA > offGroundB then 
			angleIncrement = -1
			biggerDifference = offGroundA
			smallerDifference = offGroundB
			smallerDifferencePart = partB
		end 
	end

    -- rotates the model until both sides are parallel to the ground (not 100% accurate) --
	
	while task.wait() do 
		CalculateDifference() 
		if (biggerDifference - smallerDifference) <= 0.1 then break end 
		model:SetPrimaryPartCFrame(model.Center.CFrame * CFrame.Angles(math.rad(angleIncrement), 0, 0)) 
	end
	model:SetPrimaryPartCFrame(model.Center.CFrame * CFrame.new(0, -FloorCheck(smallerDifferencePart, 0))
	return oldAngle, oldAngle - bike.Center.Orientation.X -- how you get the angle
end

There’s probably some formula that would shorten this code by a lot but I’m not very good at math…