Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Rotation

Rotation

Scheduled Pinned Locked Moved C / C++ / MFC
questionc++
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    Waldermort
    wrote on last edited by
    #1

    I would ask this question on the algorithms/maths board, but I feel it is more appropriate here. Lets say I have 2 points, { X1,Y1 } and { X2,Y2 }, I want to calculate the rotation of #2 around #1 given a number of degrees. What is the fasted possible way to do this in C++? Here is my method, which I find to be too slow. X2 = X1 * cosf(rotate) - Y1 * sinf(rotate); Y2 = X1 * sinf(rotate) + Y1 * cosf(rotate);

    S 1 Reply Last reply
    0
    • W Waldermort

      I would ask this question on the algorithms/maths board, but I feel it is more appropriate here. Lets say I have 2 points, { X1,Y1 } and { X2,Y2 }, I want to calculate the rotation of #2 around #1 given a number of degrees. What is the fasted possible way to do this in C++? Here is my method, which I find to be too slow. X2 = X1 * cosf(rotate) - Y1 * sinf(rotate); Y2 = X1 * sinf(rotate) + Y1 * cosf(rotate);

      S Offline
      S Offline
      softwaremonkey
      wrote on last edited by
      #2

      You code calculates cosf() and sinf() twice - you could probably speed things up by almost 2 x by only calculating cosf(rotate) and sinf(rotate) once and assigning the values to local variables. Hope this helps Tony

      N 1 Reply Last reply
      0
      • S softwaremonkey

        You code calculates cosf() and sinf() twice - you could probably speed things up by almost 2 x by only calculating cosf(rotate) and sinf(rotate) once and assigning the values to local variables. Hope this helps Tony

        N Offline
        N Offline
        nutkase
        wrote on last edited by
        #3

        As calculating cosines and sines is expensive, another optimization could be to just calculate them once and make a table for the values ( may in application startup ) this will considerably increase the speed :). If you are rotating these values multiple times. A question you might ask is but the value for the angle could be infinte and hence the table size. The catch here is every angle's cosine/sine is equal to an angle b/w 0-180 (0-pie).. so pratically you need only a table of 180 entries :). I hope this help! enjoy

        W S 2 Replies Last reply
        0
        • N nutkase

          As calculating cosines and sines is expensive, another optimization could be to just calculate them once and make a table for the values ( may in application startup ) this will considerably increase the speed :). If you are rotating these values multiple times. A question you might ask is but the value for the angle could be infinte and hence the table size. The catch here is every angle's cosine/sine is equal to an angle b/w 0-180 (0-pie).. so pratically you need only a table of 180 entries :). I hope this help! enjoy

          W Offline
          W Offline
          Waldermort
          wrote on last edited by
          #4

          Thats an excellent idea, thanks for that.

          N 1 Reply Last reply
          0
          • N nutkase

            As calculating cosines and sines is expensive, another optimization could be to just calculate them once and make a table for the values ( may in application startup ) this will considerably increase the speed :). If you are rotating these values multiple times. A question you might ask is but the value for the angle could be infinte and hence the table size. The catch here is every angle's cosine/sine is equal to an angle b/w 0-180 (0-pie).. so pratically you need only a table of 180 entries :). I hope this help! enjoy

            S Offline
            S Offline
            softwaremonkey
            wrote on last edited by
            #5

            Nutkase is right, this method can dramatically improve performance but is only suitable if you can live with integer angle values (every degree) since these will be used directly as indexes into the look-up tables. If you need finer resolution than 1 degree you could consider having table entries every 0.1 degree but you would need to scale the angles to ensure that you have integral values e.g. 15. degrees would be index 15 in the table. Naturally the tables would be 10 times bigger i.e. 1800 entries (actually you could get a way with storing values for only 90 degrees ;)

            W 1 Reply Last reply
            0
            • W Waldermort

              Thats an excellent idea, thanks for that.

              N Offline
              N Offline
              nutkase
              wrote on last edited by
              #6

              The pleasure is all mine :->

              1 Reply Last reply
              0
              • S softwaremonkey

                Nutkase is right, this method can dramatically improve performance but is only suitable if you can live with integer angle values (every degree) since these will be used directly as indexes into the look-up tables. If you need finer resolution than 1 degree you could consider having table entries every 0.1 degree but you would need to scale the angles to ensure that you have integral values e.g. 15. degrees would be index 15 in the table. Naturally the tables would be 10 times bigger i.e. 1800 entries (actually you could get a way with storing values for only 90 degrees ;)

                W Offline
                W Offline
                Waldermort
                wrote on last edited by
                #7

                softwaremonkey wrote:

                only suitable if you can live with integer angle values (every degree)

                Thats no problem in this instance. The major problem I am having at the moment is when placing the rotation code inside a loop, where the point being rotated is constantly being refreshed. Here is a slightly faster method I have tried to adapt.

                FPOINT Rotate( float px, float py, float ox, float oy, int a )
                {
                //////////////////////////////////////////////////////////////////////////
                // Rotate point 'p' about point 'o' given 'a' degrees
                //////////////////////////////////////////////////////////////////////////

                float s = ( PI \* a ) / 180;  // radians
                
                FPOINT q = { px, py };
                
                if ( px == ox && py == oy ) {
                    return q;
                }
                
                float r;
                
                if ( px == ox ) {
                    if ( py > oy ) {
                        r = PI / 2;
                    } else {
                        r = - PI / 2;
                    }
                } else {
                    if ( py == oy ) {
                        if ( px < ox ) {
                            r = PI;
                        } else {
                            r = 0;
                        }
                    } else { // finally the general case
                        if ( px < ox ) {
                            r = atan( (float)( py - oy ) / ( px - ox ) ) + PI;
                        } else {
                            r = atan( (float)( py - oy ) / ( px - ox ) );
                        }
                    }
                }
                
                float hyp = sqrt( (float)( (px - ox) \* (px - ox) ) + ( ( py - oy ) \* ( py - oy ) ) );
                q.x = ( ox + cos(s+r) \* hyp );
                q.y = ( oy + sin(s+r) \* hyp );
                
                return q;
                

                }

                It's faster, but doesn't work correctly. I have 4 points denoted by the corners of a rectangle. I calc the center of the mass and pass it is as point 'o', then for each of the 4 points 'p' A calc their new positions. The resulting rectangle appears to rotate about the top-right corner ( which itself is traveling up and down a 45 degree line ). I can't for the life of me see where it is going wrong.

                W 1 Reply Last reply
                0
                • W Waldermort

                  softwaremonkey wrote:

                  only suitable if you can live with integer angle values (every degree)

                  Thats no problem in this instance. The major problem I am having at the moment is when placing the rotation code inside a loop, where the point being rotated is constantly being refreshed. Here is a slightly faster method I have tried to adapt.

                  FPOINT Rotate( float px, float py, float ox, float oy, int a )
                  {
                  //////////////////////////////////////////////////////////////////////////
                  // Rotate point 'p' about point 'o' given 'a' degrees
                  //////////////////////////////////////////////////////////////////////////

                  float s = ( PI \* a ) / 180;  // radians
                  
                  FPOINT q = { px, py };
                  
                  if ( px == ox && py == oy ) {
                      return q;
                  }
                  
                  float r;
                  
                  if ( px == ox ) {
                      if ( py > oy ) {
                          r = PI / 2;
                      } else {
                          r = - PI / 2;
                      }
                  } else {
                      if ( py == oy ) {
                          if ( px < ox ) {
                              r = PI;
                          } else {
                              r = 0;
                          }
                      } else { // finally the general case
                          if ( px < ox ) {
                              r = atan( (float)( py - oy ) / ( px - ox ) ) + PI;
                          } else {
                              r = atan( (float)( py - oy ) / ( px - ox ) );
                          }
                      }
                  }
                  
                  float hyp = sqrt( (float)( (px - ox) \* (px - ox) ) + ( ( py - oy ) \* ( py - oy ) ) );
                  q.x = ( ox + cos(s+r) \* hyp );
                  q.y = ( oy + sin(s+r) \* hyp );
                  
                  return q;
                  

                  }

                  It's faster, but doesn't work correctly. I have 4 points denoted by the corners of a rectangle. I calc the center of the mass and pass it is as point 'o', then for each of the 4 points 'p' A calc their new positions. The resulting rectangle appears to rotate about the top-right corner ( which itself is traveling up and down a 45 degree line ). I can't for the life of me see where it is going wrong.

                  W Offline
                  W Offline
                  Waldermort
                  wrote on last edited by
                  #8

                  NM... It was a stupid error in calculating the center of the mass.

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups