nothing1212's picture

Quaternion rotation bug

Project:The Open Toolkit library
Version:1.1-2014-01-02
Component:Code
Category:bug report
Priority:critical
Assigned:Unassigned
Status:closed
Description

This is a major bug... a simple quaternion multiplication can result in a NAN. Here is a test case that reproduces the bug.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using OpenTK;
 
namespace Cardio3D
{
  class Quaternion_Bug
  {
    public static void test()
    {
      Quaternion cameraQuaternion = Quaternion.Identity;
      float delta = 0.005f;
      for (float i = 0.0f; i <= Math.PI*2.1; i=i+delta)
      {
        Vector3 rotAxis = new Vector3(0.0f, 1.0f, 0.0f);
        Quaternion deltaQuat = Quaternion.FromAxisAngle(rotAxis, delta);
        cameraQuaternion = deltaQuat * cameraQuaternion;
 
        Vector3 axis = Vector3.Zero;
        float angle = 0.0f;
        System.Console.WriteLine("Cam quat: {0}", cameraQuaternion);
        //@tag Correction in a OpenTK bug?
        //if (cameraQuaternion.W < -1.0f)
        //{
        //  cameraQuaternion.W = -1.0f;
        //}
        cameraQuaternion.ToAxisAngle(out axis, out angle);
        axis.Normalize();
 
        //System.Diagnostics.Debug.Assert(!float.IsNaN(angle));
        if (float.IsNaN(angle))
        {
          throw new System.ApplicationException("Invalid rotation angle");
        }
 
        angle = OpenTK.MathHelper.RadiansToDegrees(angle);
 
        System.Console.WriteLine("Axis around: {0}", axis);
        System.Console.WriteLine("Axis rotation applied: {0}", angle); 
      }
    }
  }
}

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

#1

I am not able to reproduce this in svn trunk. Can you please check whether the issue is solved there?

the Fiddler's picture

#2

Status:open» need info
Arcane.Artist's picture

#3

I have recently just come across this issue myself.

The problem is that Quaternion.FromAxisAngle does not check if angle == 0.0f or angle smaller then float.Epsilon which is what causes the problem. If the value is 0.0 or close to zero, it should return Quaternion.Identity.

// current source for Quaternion.cs
public void Normalize()
{
float scale = 1.0f / this.Length;
Xyz *= scale;
W *= scale;
}

public static Quaternion FromAxisAngle(Vector3 axis, float angle)
{
if (axis.LengthSquared == 0.0f)
return Identity;

Quaternion result = Identity;

angle *= 0.5f;
axis.Normalize();
result.Xyz = axis * (float)System.Math.Sin(angle);
result.W = (float)System.Math.Cos(angle);

return Normalize(result);
}

The above source code is the issue. If the angle is Zero, the resulting XYZW components will be zero. Normalizing this will result in 1.0f / a length of zero (divide by zero error), creating NaN.

I hope this helps.

the Fiddler's picture

#4

Status:need info» fixed

Issue fixed in trunk r3070 and will be in the upcoming beta.

FromAxisAngle was actually correct. If angle = 0, Math.Cos() is 1 so Normalize() works correctly.

The issue was an invalid check in ToAxisAngle (W > 1.0 instead of Math.Abs(W) > 1.0).

Arcane.Artist's picture

#5

Ah! I must of hit the wrong button on my calculator. Then that should definitely work. My bad. Haha.

Arcane.Artist's picture

#6

[Mod edit: separate issue moved to #2585: Vector3.CalculateAngle() may return NaN]

the Fiddler's picture

#7

Version:1.0-2010-10-06» 1.1-2014-01-02
Status:fixed» closed

Closing bugs fixed in OpenTK 1.1.

If this is still an issue please file a new bug report at https://github.com/opentk/opentk/issues