Changeset 2939


Ignore:
Timestamp:
Sep 16, 2013, 2:27:29 PM (6 years ago)
Author:
sam
Message:

math: last pass (hopefully) at the quaternion/euler conversions.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/math/vector.cpp

    r2938 r2939  
    543543    vec3 ret;
    544544
    545     if (i != k)
     545    /* k == i means X-Y-X style Euler angles; otherwise we’re
     546     * actually handling X-Y-Z style Tait-Bryan angles. */
     547    if (k == i)
     548    {
     549        k = 3 - i - j;
     550
     551        ret[0] = atan2(q[1 + i] * q[1 + j] + sign * (q.w * q[1 + k]),
     552                       q.w * q[1 + j] - sign * (q[1 + i] * q[1 + k]));
     553        ret[1] = acos(2.f * (sq(q.w) + sq(q[1 + i])) - 1.f);
     554        ret[2] = atan2(q[1 + i] * q[1 + j] - sign * (q.w * q[1 + k]),
     555                       q.w * q[1 + j] + sign * (q[1 + i] * q[1 + k]));
     556    }
     557    else
    546558    {
    547559        ret[0] = atan2(2.f * (q.w * q[1 + i] - sign * (q[1 + j] * q[1 + k])),
     
    550562        ret[2] = atan2(2.f * (q.w * q[1 + k] - sign * (q[1 + j] * q[1 + i])),
    551563                       1.f - 2.f * (sq(q[1 + k]) + sq(q[1 + j])));
    552     }
    553     else
    554     {
    555         /* FIXME: TODO */
    556         ret[0] = rand(360.f);
    557         ret[1] = rand(360.f);
    558         ret[2] = rand(360.f);
    559564    }
    560565
  • trunk/test/unit/quat.cpp

    r2938 r2939  
    236236    }
    237237
     238    LOLUNIT_TEST(FirstTwoEulerAngles)
     239    {
     240        for (int i = 0; i < 100; ++i)
     241        {
     242            /* We check that fromeuler_xyx and fromeuler_xyz give the
     243             * same result if the 3rd angle is zero. */
     244            vec3 angles(rand(360.f), rand(360.f), 0.f);
     245            quat q1, q2;
     246
     247            q1 = quat::fromeuler_xyz(angles);
     248            q2 = quat::fromeuler_xyx(angles);
     249
     250            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     251            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     252            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     253            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     254
     255            q1 = quat::fromeuler_yzx(angles);
     256            q2 = quat::fromeuler_yzy(angles);
     257
     258            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     259            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     260            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     261            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     262
     263            q1 = quat::fromeuler_zxy(angles);
     264            q2 = quat::fromeuler_zxz(angles);
     265
     266            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     267            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     268            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     269            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     270
     271            q1 = quat::fromeuler_xzy(angles);
     272            q2 = quat::fromeuler_xzx(angles);
     273
     274            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     275            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     276            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     277            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     278
     279            q1 = quat::fromeuler_zyx(angles);
     280            q2 = quat::fromeuler_zyz(angles);
     281
     282            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     283            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     284            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     285            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     286
     287            q1 = quat::fromeuler_yxz(angles);
     288            q2 = quat::fromeuler_yxy(angles);
     289
     290            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     291            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     292            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     293            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     294        }
     295    }
     296
     297    LOLUNIT_TEST(LastTwoEulerAngles)
     298    {
     299        for (int i = 0; i < 100; ++i)
     300        {
     301            /* We check that fromeuler_zyz and fromeuler_xyz give the
     302             * same result if the 1st angle is zero. */
     303            vec3 angles(0.f, rand(360.f), rand(360.f));
     304            quat q1, q2;
     305
     306            q1 = quat::fromeuler_xyz(angles);
     307            q2 = quat::fromeuler_zyz(angles);
     308
     309            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     310            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     311            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     312            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     313
     314            q1 = quat::fromeuler_yzx(angles);
     315            q2 = quat::fromeuler_xzx(angles);
     316
     317            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     318            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     319            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     320            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     321
     322            q1 = quat::fromeuler_zxy(angles);
     323            q2 = quat::fromeuler_yxy(angles);
     324
     325            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     326            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     327            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     328            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     329
     330            q1 = quat::fromeuler_xzy(angles);
     331            q2 = quat::fromeuler_yzy(angles);
     332
     333            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     334            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     335            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     336            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     337
     338            q1 = quat::fromeuler_zyx(angles);
     339            q2 = quat::fromeuler_xyx(angles);
     340
     341            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     342            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     343            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     344            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     345
     346            q1 = quat::fromeuler_yxz(angles);
     347            q2 = quat::fromeuler_zxz(angles);
     348
     349            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.w, q2.w, 1e-5);
     350            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.x, q2.x, 1e-5);
     351            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.y, q2.y, 1e-5);
     352            LOLUNIT_ASSERT_DOUBLES_EQUAL(q1.z, q2.z, 1e-5);
     353        }
     354    }
     355
    238356    LOLUNIT_TEST(TaitBryanAngles)
    239357    {
     
    244362             * quaternion creates the same transform. */
    245363            vec3 p(rand(1.f, 2.f), rand(1.f, 2.f), rand(1.f, 2.f));
    246             quat q = normalize(quat(rand(-1.f, 1.f), rand(-1.f, 1.f),
    247                                     rand(-1.f, 1.f), rand(-1.f, 1.f)));
    248             vec3 p0 = q.transform(p);
     364            quat q0 = normalize(quat(rand(-1.f, 1.f), rand(-1.f, 1.f),
     365                                     rand(-1.f, 1.f), rand(-1.f, 1.f)));
     366            vec3 p0 = q0.transform(p);
    249367
    250368            /* x-y-z */
    251             quat q1 = quat::fromeuler_xyz(vec3::toeuler_xyz(q));
     369            quat q1 = quat::fromeuler_xyz(vec3::toeuler_xyz(q0));
    252370            vec3 p1 = q1.transform(p);
    253371
     
    257375
    258376            /* y-z-x */
    259             quat q2 = quat::fromeuler_yzx(vec3::toeuler_yzx(q));
    260             vec3 p2 = q2.transform(p);
    261 
    262             LOLUNIT_ASSERT_DOUBLES_EQUAL(p2.x, p0.x, 1e-4);
    263             LOLUNIT_ASSERT_DOUBLES_EQUAL(p2.y, p0.y, 1e-4);
    264             LOLUNIT_ASSERT_DOUBLES_EQUAL(p2.z, p0.z, 1e-4);
     377            q1 = quat::fromeuler_yzx(vec3::toeuler_yzx(q0));
     378            p1 = q1.transform(p);
     379
     380            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     381            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     382            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
    265383
    266384            /* z-x-y */
    267             quat q3 = quat::fromeuler_zxy(vec3::toeuler_zxy(q));
    268             vec3 p3 = q3.transform(p);
    269 
    270             LOLUNIT_ASSERT_DOUBLES_EQUAL(p3.x, p0.x, 1e-4);
    271             LOLUNIT_ASSERT_DOUBLES_EQUAL(p3.y, p0.y, 1e-4);
    272             LOLUNIT_ASSERT_DOUBLES_EQUAL(p3.z, p0.z, 1e-4);
     385            q1 = quat::fromeuler_zxy(vec3::toeuler_zxy(q0));
     386            p1 = q1.transform(p);
     387
     388            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     389            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     390            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
    273391
    274392            /* x-z-y */
    275             quat q4 = quat::fromeuler_xzy(vec3::toeuler_xzy(q));
    276             vec3 p4 = q4.transform(p);
    277 
    278             LOLUNIT_ASSERT_DOUBLES_EQUAL(p4.x, p0.x, 1e-4);
    279             LOLUNIT_ASSERT_DOUBLES_EQUAL(p4.y, p0.y, 1e-4);
    280             LOLUNIT_ASSERT_DOUBLES_EQUAL(p4.z, p0.z, 1e-4);
     393            q1 = quat::fromeuler_xzy(vec3::toeuler_xzy(q0));
     394            p1 = q1.transform(p);
     395
     396            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     397            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     398            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
    281399
    282400            /* z-y-x */
    283             quat q5 = quat::fromeuler_zyx(vec3::toeuler_zyx(q));
    284             vec3 p5 = q5.transform(p);
    285 
    286             LOLUNIT_ASSERT_DOUBLES_EQUAL(p5.x, p0.x, 1e-4);
    287             LOLUNIT_ASSERT_DOUBLES_EQUAL(p5.y, p0.y, 1e-4);
    288             LOLUNIT_ASSERT_DOUBLES_EQUAL(p5.z, p0.z, 1e-4);
     401            q1 = quat::fromeuler_zyx(vec3::toeuler_zyx(q0));
     402            p1 = q1.transform(p);
     403
     404            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     405            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     406            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
    289407
    290408            /* y-x-z */
    291             quat q6 = quat::fromeuler_yxz(vec3::toeuler_yxz(q));
    292             vec3 p6 = q6.transform(p);
    293 
    294             LOLUNIT_ASSERT_DOUBLES_EQUAL(p6.x, p0.x, 1e-4);
    295             LOLUNIT_ASSERT_DOUBLES_EQUAL(p6.y, p0.y, 1e-4);
    296             LOLUNIT_ASSERT_DOUBLES_EQUAL(p6.z, p0.z, 1e-4);
     409            q1 = quat::fromeuler_yxz(vec3::toeuler_yxz(q0));
     410            p1 = q1.transform(p);
     411
     412            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     413            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     414            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
    297415        }
    298416    }
     
    306424             * quaternion creates the same transform. */
    307425            vec3 p(rand(1.f, 2.f), rand(1.f, 2.f), rand(1.f, 2.f));
    308             quat q = normalize(quat(rand(-1.f, 1.f), rand(-1.f, 1.f),
    309                                     rand(-1.f, 1.f), rand(-1.f, 1.f)));
    310             vec3 p0 = q.transform(p);
    311 
    312             /* x-y-z */
    313             quat q1 = quat::fromeuler_xyx(vec3::toeuler_xyx(q));
     426            quat q0 = normalize(quat(rand(-1.f, 1.f), rand(-1.f, 1.f),
     427                                     rand(-1.f, 1.f), rand(-1.f, 1.f)));
     428            vec3 p0 = q0.transform(p);
     429
     430            /* x-y-x */
     431            quat q1 = quat::fromeuler_xyx(vec3::toeuler_xyx(q0));
    314432            vec3 p1 = q1.transform(p);
    315433
    316 //            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
    317 //            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
    318 //            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
     434            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     435            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     436            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
     437
     438            /* y-z-y */
     439            q1 = quat::fromeuler_yzy(vec3::toeuler_yzy(q0));
     440            p1 = q1.transform(p);
     441
     442            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     443            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     444            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
     445
     446            /* z-x-z */
     447            q1 = quat::fromeuler_zxz(vec3::toeuler_zxz(q0));
     448            p1 = q1.transform(p);
     449
     450            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     451            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     452            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
     453
     454            /* x-z-x */
     455            q1 = quat::fromeuler_xzx(vec3::toeuler_xzx(q0));
     456            p1 = q1.transform(p);
     457
     458            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     459            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     460            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
     461
     462            /* z-y-z */
     463            q1 = quat::fromeuler_zyz(vec3::toeuler_zyz(q0));
     464            p1 = q1.transform(p);
     465
     466            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     467            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     468            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
     469
     470            /* y-x-y */
     471            q1 = quat::fromeuler_yxy(vec3::toeuler_yxy(q0));
     472            p1 = q1.transform(p);
     473
     474            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.x, p0.x, 1e-4);
     475            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.y, p0.y, 1e-4);
     476            LOLUNIT_ASSERT_DOUBLES_EQUAL(p1.z, p0.z, 1e-4);
    319477        }
    320478    }
Note: See TracChangeset for help on using the changeset viewer.