Skip to content

Commit 3ecd7b5

Browse files
authored
Merge pull request #10 from stackgl/quat-opt
Optimize transformQuat
2 parents 219dbe7 + ee24eda commit 3ecd7b5

3 files changed

Lines changed: 33 additions & 16 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ var scale = require('gl-vec3/scale')
217217

218218
## transformQuat(out:vec3, a:vec3, q:quat)
219219

220-
Transforms the vec3 with a quat
220+
Transforms the vec3 with a unit quat
221221

222222
## License
223223

test/index.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,15 @@ test('transformMat4', function (t) {
294294
})
295295

296296
test('transformQuat', function (t) {
297-
var result = vec3.transformQuat([], [3, 4, 5], [6, 7, 8, 9])
298-
t.deepEqual(result, [882, 824, 1090])
297+
// Construct unit quaternion q manually
298+
const l = Math.sqrt(1 * 1 + 2 * 2 + 2 * 2 + 4 * 4)
299+
const q = [1 / l, 2 / l, -2 / l, 4 / l]
300+
301+
var result = vec3.transformQuat([], [3, 4, 5], q)
302+
t.deepEqual(result, [
303+
6.6800000000000015,
304+
-2.2400000000000007,
305+
0.5999999999999992
306+
])
299307
t.end()
300308
})

transformQuat.js

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,35 @@ module.exports = transformQuat;
33
/**
44
* Transforms the vec3 with a quat
55
*
6+
* Note: the quaternion must be a unit quaternion (|q| = 1) in
7+
* order for this operation to be valid.
8+
*
69
* @param {vec3} out the receiving vector
710
* @param {vec3} a the vector to transform
8-
* @param {quat} q quaternion to transform with
11+
* @param {quat} q unit quaternion to transform with
912
* @returns {vec3} out
1013
*/
1114
function transformQuat(out, a, q) {
12-
// benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
15+
// Fast Vector Rotation using Quaternions by Robert Eisele
16+
// https://raw.org/proof/vector-rotation-using-quaternions/
1317

1418
var x = a[0], y = a[1], z = a[2],
15-
qx = q[0], qy = q[1], qz = q[2], qw = q[3],
19+
qx = q[0], qy = q[1], qz = q[2], qw = q[3]
20+
21+
// t = q x v
22+
var tx = qy * z - qz * y
23+
var ty = qz * x - qx * z
24+
var tz = qx * y - qy * x
25+
26+
// t = 2t
27+
tx *= 2
28+
ty *= 2
29+
tz *= 2
1630

17-
// calculate quat * vec
18-
ix = qw * x + qy * z - qz * y,
19-
iy = qw * y + qz * x - qx * z,
20-
iz = qw * z + qx * y - qy * x,
21-
iw = -qx * x - qy * y - qz * z
31+
// v + w t + q x t
32+
out[0] = x + qw * tx + qy * tz - qz * ty
33+
out[1] = y + qw * ty + qz * tx - qx * tz
34+
out[2] = z + qw * tz + qx * ty - qy * tx
2235

23-
// calculate result * inverse quat
24-
out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy
25-
out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz
26-
out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx
2736
return out
28-
}
37+
}

0 commit comments

Comments
 (0)