Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Trivial Trivial
    • Resolution: Unresolved
    • Affects Version/s: current
    • Fix Version/s: not determined
    • Component/s: vecmath
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

    • Issuezilla Id:
      108
    • Status Whiteboard:
      Hide

      owner-needed

      Show
      owner-needed

      Description

      There is logic in javax.vecmath.Matrix4d and javax.media.j3d.Transform3D that
      sets a Quat4d from the angle in the matrix/transform. This logic sometimes
      results in the Quat4d being filled with 4 NaNs, due to taking the square root
      of a negative number. The logic in Quat4d to do the same thing seems to work.

      I am listing this as against vecmath since I suspect the broken code in
      j3d-core was copied from vecmath.

      1. QuatErrors.java
        0.7 kB
        divad27182
      2. QuatErrors2.java
        0.5 kB
        divad27182

        Activity

        Hide
        divad27182 added a comment -

        Created an attachment (id=75)
        Sample program that shows the NaN

        Show
        divad27182 added a comment - Created an attachment (id=75) Sample program that shows the NaN
        Hide
        divad27182 added a comment -

        I seem to have been premature in saying that the logic in Quat4d worked. It
        produced a unit Quaternion, but it has the wrong values.

        I will attach an updated test program....

        Show
        divad27182 added a comment - I seem to have been premature in saying that the logic in Quat4d worked. It produced a unit Quaternion, but it has the wrong values. I will attach an updated test program....
        Hide
        divad27182 added a comment -

        Created an attachment (id=76)
        Updated test program Quat4d -> Matrix4d -> Quat4d incorrectly

        Show
        divad27182 added a comment - Created an attachment (id=76) Updated test program Quat4d -> Matrix4d -> Quat4d incorrectly
        Hide
        kcr added a comment -

        Lowered to P5: no immediate plans to address this issue unless someone
        volunteers to fix it.

        Show
        kcr added a comment - Lowered to P5: no immediate plans to address this issue unless someone volunteers to fix it.
        Hide
        kcr added a comment -

        Updated status

        Show
        kcr added a comment - Updated status
        Hide
        nikolai added a comment -

        Wouldn't this do the trick for Transform3D:

        public final void get(Quat4d q1) {
        if ((dirtyBits & ROTATION_BIT) != 0)

        { computeScaleRotation(false); }

        double ww = 0.25*(1.0 + rot[0] + rot[4] + rot[8]);
        if (!((ww < 0 ? -ww : ww) < 1.0e-10)) {
        if(rot[0] + rot[4] + rot[8] > 0)

        { q1.w = Math.sqrt(ww); ww = 0.25/q1.w; q1.x = (rot[7] - rot[5])*ww; q1.y = (rot[2] - rot[6])*ww; q1.z = (rot[3] - rot[1])*ww; return; }

        else {
        // negative diagonal:
        if(rot[4] > rot[0])

        { ww = Math.sqrt(1.0+(rot[4]-rot[8]+rot[0])); q1.y=ww * 0.5; if (ww != 0.0) ww = 0.5 / ww; q1.w=(rot[2]-rot[6])*ww; q1.z=(rot[7]+rot[5])*ww; q1.x=(rot[1]+rot[3])*ww; }

        else if(rot[8] > rot[4])

        { ww = Math.sqrt(1.0+(rot[8]-rot[0]+rot[4])); q1.z=ww * 0.5; if (ww != 0.0) ww = 0.5 / ww; q1.w=(rot[3]-rot[1])*ww; q1.x=(rot[2]+rot[6])*ww; q1.y=(rot[5]+rot[7])*ww; }

        else

        { ww = Math.sqrt(1.0+(rot[0]-rot[4]+rot[8])); q1.x=ww * 0.5; if (ww != 0.0) ww = 0.5 / ww; q1.w=(rot[7]-rot[5])*ww; q1.y=(rot[3]+rot[1])*ww; q1.z=(rot[6]+rot[2])*ww; }

        return;
        }
        }

        q1.w = 0.0;
        ww = -0.5*(rot[4] + rot[8]);
        if (!((ww < 0 ? -ww : ww) < 1.0e-10))

        { q1.x = Math.sqrt(ww); ww = 0.5/q1.x; q1.y = rot[3]*ww; q1.z = rot[6]*ww; return; }

        q1.x = 0.0;
        ww = 0.5*(1.0 - rot[8]);
        if (!((ww < 0 ? -ww : ww) < 1.0e-10))

        { q1.y = Math.sqrt(ww); q1.z = rot[7]/(2.0*q1.y); return; }

        q1.y = 0.0;
        q1.z = 1.0;
        }

        Show
        nikolai added a comment - Wouldn't this do the trick for Transform3D: public final void get(Quat4d q1) { if ((dirtyBits & ROTATION_BIT) != 0) { computeScaleRotation(false); } double ww = 0.25*(1.0 + rot [0] + rot [4] + rot [8] ); if (!((ww < 0 ? -ww : ww) < 1.0e-10)) { if(rot [0] + rot [4] + rot [8] > 0) { q1.w = Math.sqrt(ww); ww = 0.25/q1.w; q1.x = (rot[7] - rot[5])*ww; q1.y = (rot[2] - rot[6])*ww; q1.z = (rot[3] - rot[1])*ww; return; } else { // negative diagonal: if(rot [4] > rot [0] ) { ww = Math.sqrt(1.0+(rot[4]-rot[8]+rot[0])); q1.y=ww * 0.5; if (ww != 0.0) ww = 0.5 / ww; q1.w=(rot[2]-rot[6])*ww; q1.z=(rot[7]+rot[5])*ww; q1.x=(rot[1]+rot[3])*ww; } else if(rot [8] > rot [4] ) { ww = Math.sqrt(1.0+(rot[8]-rot[0]+rot[4])); q1.z=ww * 0.5; if (ww != 0.0) ww = 0.5 / ww; q1.w=(rot[3]-rot[1])*ww; q1.x=(rot[2]+rot[6])*ww; q1.y=(rot[5]+rot[7])*ww; } else { ww = Math.sqrt(1.0+(rot[0]-rot[4]+rot[8])); q1.x=ww * 0.5; if (ww != 0.0) ww = 0.5 / ww; q1.w=(rot[7]-rot[5])*ww; q1.y=(rot[3]+rot[1])*ww; q1.z=(rot[6]+rot[2])*ww; } return; } } q1.w = 0.0; ww = -0.5*(rot [4] + rot [8] ); if (!((ww < 0 ? -ww : ww) < 1.0e-10)) { q1.x = Math.sqrt(ww); ww = 0.5/q1.x; q1.y = rot[3]*ww; q1.z = rot[6]*ww; return; } q1.x = 0.0; ww = 0.5*(1.0 - rot [8] ); if (!((ww < 0 ? -ww : ww) < 1.0e-10)) { q1.y = Math.sqrt(ww); q1.z = rot[7]/(2.0*q1.y); return; } q1.y = 0.0; q1.z = 1.0; }

          People

          • Assignee:
            java3d-issues
            Reporter:
            divad27182
          • Votes:
            2 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: