# [FUNC] Euler angles into quaternions

## Recommended Posts

Function to translate angles of Euler into quaternions.

• Arguments: RotX, RotY, RotZ
• Return: RotX, RotY, RotZ, RotW
```function math.quaternion(x, y, z)
local t = { c[2] * c[3], s[1] * s[2] * s[3] + c[1] * c[3], c[1] * c[2] }
return
math.drt(1.0 + t[1] - t[2] - t[3], (c[3] * s[1] - c[1] * s[2] * s[3]) - (-s[1] * c[2])),
math.drt(1.0 - t[1] + t[2] - t[3], s[2] + (c[1] * s[2] * c[3] + s[1] * s[3])),
math.drt(1.0 - t[1] - t[2] + t[3], (s[1] * s[2] * c[3] - c[1] * s[3]) - (c[2] * s[3])),
math.drt(1.0 + t[1] + t[2] + t[3])
end

function math.drt(a, b)
a = math.sqrt(math.max(0.0, a)) * 0.5
return (b and ((b < 0) and -math.abs(a) or math.abs(a)) or a)
end```

Edited by Essle
Updated function syntax
• 1
• 1

where to use it in a real situation? to calculate what? give a layman example... what did you used it for? thanks

This function is needed to convert .map to .ipl
In all converters rotation is not calculated correctly. But this function works perfectly.

Example

```local file = File.new("map-test.ipl")
file:write("inst\n")

for _, theSubject in ipairs(Element.getAllByType("object")) do

local rX, rY, rZ = getElementRotation(theSubject, "ZXY")
local rW = 0
rX, rY, rZ, rW = math.quaternion(rX, rY, rZ)

file:write(
theSubject.model..", "..engineGetModelNameFromID(theSubject.model)..", 0, "..
theSubject.position.x..", "..theSubject.position.y..", "..theSubject.position.z..", "..
rX..", "..rY..", "..rZ..", "..rW..", -1\n"
)

end

file:write("end")
file:flush()
file:close()```

• 1

```function math.quaternion(x, y, z)
local rx = math.rad( -x )
local ry = math.rad( -y )
local rz = math.rad( z )
local fCosX = math.cos(rx)
local fCosY = math.cos(ry)
local fCosZ = math.cos(rz)
local fSinX = math.sin(rx)
local fSinY = math.sin(ry)
local fSinZ = math.sin(rz)
local temp1 = fCosY * fCosZ
local temp2 = fSinX * fSinY * fSinZ + fCosX * fCosZ
local temp3 = fCosX * fCosY
local w = math.sqrt(math.max(0.0, 1.0 + temp1 + temp2 + temp3)) * 0.5
local x = math.sqrt(math.max(0.0, 1.0 + temp1 - temp2 - temp3)) * 0.5
local y = math.sqrt(math.max(0.0, 1.0 - temp1 + temp2 - temp3)) * 0.5
local z = math.sqrt(math.max(0.0, 1.0 - temp1 - temp2 + temp3)) * 0.5
x = math.sign(x, (fCosZ * fSinX - fCosX * fSinY * fSinZ) - (-fSinX * fCosY))
y = math.sign(y, fSinY + (fCosX * fSinY * fCosZ + fSinX * fSinZ))
z = math.sign(z, (fSinX * fSinY * fCosZ - fCosX * fSinZ) - (fCosY * fSinZ))
return x, y, z, w
end

function math.sign(x, a)
return (a < 0) and -math.abs(x) or math.abs(x)
end```

This will get a better performance, won't it?

Edited by thisdp

36 minutes ago, thisdp said:

This will get a better performance, won't it?

On tests you will not even notice difference.