Skip to content

Commit

Permalink
Axis calculation of quaternions from small angles (#272)
Browse files Browse the repository at this point in the history
* lower 0-angle rotation denominator threshold in
axis calculation to get axis from smaller rotations

* lower quaternion axis denominator threshold further for 64 bit implementation
  • Loading branch information
JKris95 committed May 30, 2023
1 parent 3762b25 commit cd87f57
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/src/vector_math/quaternion.dart
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ class Quaternion {
/// [axis] of rotation.
Vector3 get axis {
final den = 1.0 - (_qStorage[3] * _qStorage[3]);
if (den < 0.0005) {
if (den < 0.00002) {
// 0-angle rotation, so axis does not matter
return Vector3.zero();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/vector_math_64/quaternion.dart
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ class Quaternion {
/// [axis] of rotation.
Vector3 get axis {
final den = 1.0 - (_qStorage[3] * _qStorage[3]);
if (den < 0.0005) {
if (den < 1e-9) {
// 0-angle rotation, so axis does not matter
return Vector3.zero();
}
Expand Down
14 changes: 14 additions & 0 deletions test/quaternion_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:vector_math/vector_math.dart';
import 'package:vector_math/vector_math_64.dart' as v64;

import 'test_utils.dart';

Expand Down Expand Up @@ -212,6 +213,18 @@ void testFromTwoVectors() {
}
}

void testSmallAngleQuaternionAxis() {
final quaternion32 =
Quaternion.axisAngle(Vector3(0.0, 0.0, 1.0), 0.6 * degrees2Radians);
relativeTest(quaternion32.axis, Vector3(0.0, 0.0, 1.0));
relativeTest(quaternion32.radians, 0.6 * degrees2Radians);
final quaternion64 =
v64.Quaternion.axisAngle(v64.Vector3(0, 0, 1), 0.01 * degrees2Radians);
expect(
quaternion64.axis.relativeError(v64.Vector3(0, 0, 1)), closeTo(0, 1e-5));
expect(quaternion64.radians, closeTo(0.01 * degrees2Radians, 1e-5));
}

void main() {
group('Quaternion', () {
test('Float32List instacing', testQuaternionInstacinfFromFloat32List);
Expand All @@ -223,5 +236,6 @@ void main() {
test('Normalize', testQuaternionNormalize);
test('Axis-Angle', testQuaternionAxisAngle);
test('Construction from two vectors', testFromTwoVectors);
test('Axis of quaternion from small angle', testSmallAngleQuaternionAxis);
});
}

0 comments on commit cd87f57

Please sign in to comment.