Thread: Rotations, Radians and -1.#IND oh my

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    82

    Rotations, Radians and -1.#IND oh my

    Hello one and all.

    I've been tampering with rotation matrixes and the lot, and even though i can manage the more simpler rotation around the three axes. my attempts at trying it around an arbitrary fixed point (xyz) deson't work aswell as i would have hoped.

    It seems to work 80% of the time however, this seems only to be a result of the right combination of (xyz) vector for rotation and the angle chosen to rotate by. If its wrong i get a number which is > then 1 or < -1 and when used in conjunction with arcsin gives a -1.#IND output.

    my method was originall based around euler angles and quaternions found in http://en.wikipedia.org/wiki/Convers...d_Euler_angles

    essentailly computing q0-q3 and then using these to compute the euler angles

    Code:
     for (i = 0; i < PopSize; i++)
         {         
               angle = rand()%361+0.001;
               // convert to radian???
               angle =  angle * (PI / 180);
               
               cout << "Angle: " << angle << endl;
                  // convert to euler angles
                  q0 = cos(angle/2);
                  cout << "q0: " << q0 << endl;
                  q1 = sin(angle/2) * (cos(Pop[i][5][0])); // rotate around 5th atom
                  cout << "q1: " << q1 << endl;
                  q2 = sin(angle/2) * (cos(Pop[i][5][1]));
                  cout << "q2: " << q2 << endl;
                  q3 = sin(angle/2) * (cos(Pop[i][5][2]));
                  cout << "q3: " << q3 << endl;
                  cout << (q0*q2) << " - " << (q3*q1) << endl;
                  eX = atan(2*((q0*q1) + (q2*q3)) / (1 - (2*( (q1 * q1) + (q2 * q2) ) ) ) );
                  eY = asin(2*((q0*q2) - (q3*q1)));
                  eZ = atan(2*((q0*q3) + (q1*q2)) / (1 - (2*( (q2 * q2) + (q3 * q3) ) ) ) );
                  cout << "Euler X: " << eX << endl; cout << "Euler Y: " << eY << endl; cout << "Euler Z: " << eZ << endl;
                  cout << endl;
                  cout << "X " << Pop[i][5][0] << " Y " << Pop[i][5][1] << " Z " << Pop[i][5][2] << endl;
                //  cin.get();      
             for (j = 0; j < ShtResidue; j++)
             {
       //           cout << "Checking Distance Before Rotation..." << endl;
                  Xsqd = (Pop[i][j-1][0] - Pop[i][j][0]) * (Pop[i][j-1][0] - Pop[i][j][0]);
                  Ysqd = (Pop[i][j-1][1] - Pop[i][j][1]) * (Pop[i][j-1][1] - Pop[i][j][1]);
                  Zsqd = (Pop[i][j-1][2] - Pop[i][j][2]) * (Pop[i][j-1][2] - Pop[i][j][2]);
                  Sum = Xsqd + Ysqd + Zsqd;
                  Sum = sqrt (Sum);
         //         cout << "X Squared: " << Xsqd << endl; cout << "Y Squared: " << Ysqd << endl;      cout << "Z Squared: " << Zsqd << endl;
        //          cout << "Distance: " << Sum << endl;
       //           cin.get();
       //           cout << endl;
                
                  
             nX[0] = Pop[i][j][0]; // store for later use in z axis rotaion
             nY[0] = Pop[i][j][1];
             nZ[0] = Pop[i][j][2];
             
          // rotate around Z axis
        //     cout << "Rotate Z axis" << endl;
             Pop[i][j][0] = (nX[0] * (cos(eX))) - (nY[0] * (sin(eX)));
             Pop[i][j][1] = (nX[0] * (sin(eX))) + (nY[0] * (cos(eX)));
             Pop[i][j][2] = nZ[0];
        //     cout << "Atom: " << j << endl; cout << "X' = " << Pop[i][j][0] << endl; cout << "Y' = " << Pop[i][j][1] << endl; cout << "Z' = " << Pop[i][j][2] << endl;
       //      cin.get();
             oldnX[0] = Pop[i][j][0]; // store for later use in y axis rotaion
             oldnY[0] = Pop[i][j][1];
             oldnZ[0] = Pop[i][j][2];
    It's only a partial piece of the code however, and i can't seem to figure out why it works on some occassions and then not on others. To me it seems that the equations set out in the wiki correspond to what i have coded but i still occasionally get errors from this part:

    eY = asin(2*((q0*q2) - (q3*q1)));
    i.e. computing euler angle Y

    where if asin * anything greater then 1.0 or less then -1.0 it throws up the NaN -1.#IND

    Also i had originally thought i could use normal angles, but it seems that cmath uses radians instead so to be honest i don't know what effect that is having, as you can see i changed it to convert from angles to radians, but still keep getting the odd -1.#IND

    Can i use this method to calculate rotation around a vector (xyz) or i'am i out of luck.

    Any help is appreciated

    Regards Wolfe

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > angle = rand()%361+0.001;
    Stick to % 360 only.
    Valid integer angles would be 0 to 359 inclusive.

    > Xsqd = (Pop[i][j-1][0] - Pop[i][j][0]) * (Pop[i][j-1][0] - Pop[i][j][0]);
    Given that j starts at 0, you're stepping off the beginning of the array.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    82
    With regards to j-1 section it is ony there for me to check the distances remain valid nothing else omes from it once i can finally be certain it works i will get rid of it.

    Regards Wolfe

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    What you are looking for is an axis-angle rotation matrix. Google it.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You don't need quaternions for this. Euclidean Geometry will also work. Not meaning to imply one is a better choice here than the other. But anyway...
    See the rather controversial article: http://www.gamedev.net/reference/art...rticle1199.asp
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    82
    Quote Originally Posted by Bubba View Post
    What you are looking for is an axis-angle rotation matrix. Google it.
    I believe i already have that coded in elsewhere, if you mean by rotating around each axis. What i was trying to do know is, if oyu have a string of nodes connected as a chain in a 3D space, i want to rotate about a node ie its vector (xyz).

    thanks for the link imalc i'll have a look.

  7. #7
    Registered User
    Join Date
    Oct 2005
    Posts
    82
    Well turns out i had also tried out what was in that link aswell , though i couldn't get that to work either lol

    Here is a snippet

    Code:
            
             nX[0] = Pop[i][j][0]; // store for later use in z axis rotaion
             nY[0] = Pop[i][j][1];
             nZ[0] = Pop[i][j][2];
                  
          //   cout << "Rotate Z axis" << endl;
             Pop[i][j][0] = ((1 - cos(angle))*(nX[0] * nX[0]) + (cos(angle))) + (1 - cos(angle)*(nX[0]*nY[0]) - (sin(angle)*nZ[0])) + (1 - cos(angle)*(nX[0]*nZ[0]) + (sin(angle)*nY[0])); 
             Pop[i][j][1] = ((1 - cos(angle))*(nX[0] * nY[0]) + (sin(angle)*nZ[0])) + (1-cos(angle)*(nY[0] * nY[0]) + (cos(angle))) + (1 - cos(angle)*(nY[0]*nZ[0]) - (sin(angle)*nX[0]));
             Pop[i][j][2] = ((1 - cos(angle))*(nX[0] * nZ[0]) - (sin(angle)*nY[0])) + (1-cos(angle)*(nY[0] * nZ[0]) + (sin(angle)*nX[0])) + (1 - cos(angle)*(nZ[0] *nZ[0]) + cos(angle));
        //     cout << "Atom: " << j << endl; cout << "X' = " << Pop[i][j][0] << endl; cout << "Y' = " << Pop[i][j][1] << endl; cout << "Z' = " << Pop[i][j][2] << endl;
            // cin.get();

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. -1.#IND in output???
    By alyeska in forum C++ Programming
    Replies: 4
    Last Post: 01-19-2008, 01:32 AM
  2. Checking For 1.#INF and 1.#IND
    By Gokhan in forum C++ Programming
    Replies: 5
    Last Post: 05-15-2007, 02:48 PM
  3. Decimal problem -1.#IND
    By lynnluoll in forum C++ Programming
    Replies: 2
    Last Post: 05-23-2005, 04:23 PM