raysect / source

The main source repository for the Raysect project.
http://www.raysect.org
BSD 3-Clause "New" or "Revised" License
88 stars 23 forks source link

Suspected bug in Quaternion.to_matrix() #270

Closed mattngc closed 5 years ago

mattngc commented 5 years ago

I have seen some suspicious behavior in the new Quaternion objects when generating rotation matrices. I've noticed very small changes in the Quaternion can produce very large changes in the transformed vector.

Every other part of the Quaternion I've worked with so far appears to be working. There are unit tests implemented for this function so I think there might be a gap in my test coverage. More work required.

mattngc commented 5 years ago

Here is an example of a suspicious case.

vector = Vector3D(1, 0, 0) orientation = Quaternion(0.7071067811865476, 0.0, 0.0, -0.7071067811865475) transformed_vector => Vector3D(0.0, -1.0, -1.1102230246251565e-16)

new_orientation = Quaternion(0.6731265316174981, 0.02371918119564304, -0.0074266863424779506, -0.739109543441279) transformed_vector => Vector3D(0.018625673666602283, 0.5757300372634384, 0.8174276778242251)

The amount of change in the vector for a small change in the quaternion is suspicious. I suspect the transform matrix mathematics in incorrect.

mattngc commented 5 years ago

Turns out there isn't a bug. There was a misdirection in my test case that was leading to the bogus result. I've now independently verified this method with an alternative calculation.

Quaternion.transform_vector()

This vector performs the transformation directly using the equation q v q_star, where q_star is the complex conjugate. I will add this alternative calculation as its potentially more computationally efficient.

mattngc commented 5 years ago

As proof, here is the corrected test case:

>>> new_orientation = Quaternion(0.6731265316174981, 0.02371918119564304, -0.0074266863424779506, -0.739109543441279)
>>> new_orientation.transform_vector(Vector3D(1, 0, 0))
Vector3D(-0.09267614575201093, -0.9953807967621223, -0.02506394713037894)