# mathematics – Quaternions distorting object in Metal

I’ve been trying to get rotations with quaternions to work for a while now, and I feel I am very close to it actually working but I just can’t get it to work.

I do not have a view matrix yet and am just working in 2D space to make this slightly easier to set at the moment. So I’m only rotating around the Z axis.

My model matrix is calculated like this

``````var modelMatrix: matrix_float4x4 {
var modelMatrix = matrix_identity_float4x4

modelMatrix.translate(_position)

modelMatrix.rotate(_orientation)

modelMatrix.scale(_scale)

return matrix_multiply(matrix_identity_float4x4, modelMatrix)
}
``````

_orientation is defined as

``````private var _orientation: quaternion = quaternion(angle: toRadians(0), axis: float3(0, 0, 1))
``````

quaternion is just a typedef of simd_quatf

my rotate function is

``````mutating func rotate(_ quat: quaternion) {
let quatMatrix = matrix_float4x4(simd_normalize(quat))

self = matrix_multiply(self, quatMatrix)
}
``````

I also tried to do it with the .act method

``````mutating func rotate(_ quat: quaternion, _ vec: float3) {
let rotatedVec = quat.act(vec)

self.translate(rotatedVec)
}
``````

This did the seemingly same thing as the first rotate function.

When I initialize _orientation with a rotation of 0, the program acts as normal But when I initialize it with 45, it warps the rectangle: and when I do it with 90, it produces the same result as with 0, which shouldn’t happen. I’m assuming the problem lies somewhere in the way I’m applying the rotation to the object, but I have no clue what it is.

Edit:

This is the quatMatrix when I put a break point on it if it helps at all: Also A thought, maybe it is because of the way I am applying the modelMatrix to the shader positions. I’m pretty sure this is the right way but it might be slightly wrong.

``````vertex RastData vertexShader(const VertexIn vIn [[stage_in]],
constant ModelMat &modelMatrix [[buffer(1)]]) {
RastData rd;

rd.position = modelMatrix.modelMatrix * float4(vIn.position, 1.0);
rd.color = vIn.color;

return rd;
}
``````

I tried storing the rotation as being around the rectangles current position like this

``````private var _orientation: quaternion { 