Angles don't work as intended when axis and Z axis are combined (cfame math)

I’m trying to make a foot rotate to the ground below it, as if it is planted on the ground. But when I combine the X and Z “normal” angles together and they are both higher than 0, they aren’t that accurate. I cancel out the Y axis since I want that angle to be set manualy.

here it is rotating the Z axis:

but when Z and X are both higher than 0, it doesn’t rotate accurately:
Capture_2021_01_02_15_51_25_85

here is the script:

function findmatrix(a,b,c)	
	local oriZ = Vector3.new(CFrame.new((a+c)/2,b):ToOrientation())
	local oriX = Vector3.new(CFrame.new((a+c)/2,a):ToOrientation())
	
	local signRightZ = math.sign(math.cos(oriZ.Y))
	local signUpZ = math.sign(math.sin(oriZ.Y))
	
	local signRightX = math.sign(math.sin(oriX.Y))
	local signUpX = math.sign(math.cos(oriX.Y))

	if signRightX == 0 then signRightX = 1 end
	if signRightZ == 0 then signRightZ = 1 end
	
	local signZ = signUpZ*signRightZ
	local signX = signUpX*signRightX

	local finalOriZ = -(math.rad(180)*((signRightZ+1)/2))-(math.atan(oriZ.X))*signZ*signRightZ+math.rad(180*(((signZ)-1)/2))
	local finalOriX = (math.rad(180)*((signRightX-1)/2))-(math.atan(oriX.X))*-signRightX*signX+math.rad(180*(((signX)-1)/2))
	
	return CFrame.new((a+b*2+c)/4)*CFrame.Angles(finalOriX,0,finalOriZ)
end

(sorry if its a little messy)

a, b and c are the 3 positions from 3 rays casted down from the foot:
Capture_2021_01_02_16_21_57_486

any ideas on how to fix?

I barely looked at that code, but if you’re already raycasting, then you have the normal vector and can use CFrame.fromMatrix to do that without any painful euler angles fiddling (which already suffers from gimbal lock and similar)

The raycast result has a hit surface normal, which faces away from the surface. This will be the top direction of your foot.
You seem to already know the front direction.
The side direction can be derived with a simple Vector3:Cross(Vector3).
Thus, you might want to do this:

local front -- you know the angle/where this is supposed to point
local top -- this is the surface normal of the ground
return CFrame.fromMatrix(front:Cross(top), top)

Swap front with top in that function as needed, I don’t know the 3-finger rule well enough yet.