I'm trying to learn the quaternions and I decided to set up my own quaternion class.

To test it, I created two vertex shaders, one that gets a template matrix (calculated from the quaternion) and the other that gets the quaternion of rotation directly and rotates the vertices in the shader.

I then feed these quaternion which revolves around the Y axis `t / 10000`

radians:

```
const rotation = Quat.fromAxisAngle (new Vec3 ([0, 1, 0]), t / 10000)
```

The result surprises me because my model turns counterclockwise, but I expected it to turn clockwise, because the Angle increases. The rotation around the X or Z axes is also reversed.

I suspect that my formulas are wrong and I guess + Z is ahead. If I transpose my model matrix (or post-multiply it), it runs as expected (except Z, which is now reversed).

Where are my false formulas and how can I understand the calculation behind this?

### Details

- My matrices are important columns in memory (to match the GLSL
`mat4`

).
- My coordinate system is + X right, + Y up, -Z forward.

## My code

### Quaternion of axis + angle

```
function fromAxisAngle (axis: Vec3, angle: number, dest = new Quat ()): Quat {
angle * = 0.5
const sin = Math.sin (angle)
dest.x = axis.x * sin
dest.y = axis.y * sin
dest.z = axis.z * sin
dest.w = Math.cos (angle)
return dest
}
```

**Note:** I've noticed that if I deny the x, y, and z of this quaternion, everything works as expected. Is this the primary cause? I thought the quaternions did not have the hand!

As it is actually about inverting the quaternion (and thus its rotation), I am afraid to simply correct the root cause. I do not want to fix the problem, I want to fix my calculations!

### Matrix of quaternion

```
toMat4 (dest = new Mat4 ()): Mat4 {
const {x, y, z, w} = this
const x2 = x + x
const y2 = y + y
const z2 = z + z
const xx = x * x2
const xy = x * y2
const xz = x * z2
const yy = y * y2
const yz = y * z2
const zz = z * z2
const wx = w * x2
const wy = w * y2
const wz = w * z2
dest.init ([
1 - (yy + zz), xy - wz, xz + wy, 0,
xy + wz, 1 - (xx + zz), yz - wx, 0,
xz - wy, yz + wx, 1 - (xx + yy), 0,
0, 0, 0, 1,
])
return dest
}
```

### Matrix vertex shader

```
float mediump precision;
attribute vec3 aVertexPosition;
attribute vec2 aVertexUV;
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;
variant vec2 vUV;
main void (empty) {
vUV = aVertexUV;
gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4 (aVertexPosition.xyz, 1.0);
}
```

### Quaternion vertex shader

```
float mediump precision;
attribute vec3 aVertexPosition;
attribute vec2 aVertexUV;
struct Transform {
float scale;
translation vec3;
rotation vec4;
};
uniform Transformer uModel;
uniform Transformer uView;
uniform mat4 uProjection;
variant vec2 vUV;
vec3 rotateVector (vec4 quat, vec3 vec) {
return vec + 2.0 * cross (cross (vec, quat.xyz) + quat.w * vec, quat.xyz);
}
main void (empty) {
vUV = aVertexUV;
vec3 world = rotateVector (uModel.rotation, aVertexPosition * uModel.scale) + uModel.translation;
vec3 view = rotateVector (uView.rotation, world * uView.scale) + uView.translation;
gl_Position = uProjection * vec4 (view, 1.0);
}
```