title: (Java) Rotate around Center while Preserving Orientation and Directional References
body: <p>I am designing a top-down game that has a "camera" used to pan around the playing area. The camera can be rotated and translated; translation is typical for most top-down games.</p>
  
  <p>To implement this I am using a class I created called "Center." Groups of objects are drawn around these centers (for instance, "Car" might extend Center, and Car has Parts "wheel" and "hood." In whatever position and orientation Car is drawn, so are wheel and hood).</p>
  
  <hr>
  
  <p>Things I want:</p>
  
  <p>(1) Centers always rotate around the center of the screen. EG, a center five pixels to the left of the center of the screen that is rotated 180 degrees will end up five pixels to the right of the center of the screen.</p>
  
  <p>(2) Centers maintain their orientation with respect to the center of the screen. So a Car "facing" the center of the screen continues to "face" the center as it is rotated, and vice versa.</p>
  
  <p>(3) Translates up, down, left, and right always move the "camera" up, down, left and right. For instance, pushing the "up" key should move the Car up, regardless of whether the car is facing up or down. Rotating the car 180 degrees (or <em>at all</em>) should not rotate the direction of translation (for instance, making the "up" key translate down).</p>
  
  <hr>
  
  <p>I can get one, sometimes two of these at a time, but haven't been able to get all three. Here is the main chunk of code I've played with, called before the <code>draw</code> function:</p>
  
  <pre><code>protected void setCanvas(Graphics2D g){
      at = g.getTransform();                        //Used to restore the original
      Point screenCenter = Grid.FRAME_CENTER;
                    //Grid is the abstract class maintaining all
                    //properties of the frame and game grid
      g.translate(xloc,yloc);
      g.translate(screenCenter.x+xloc,screenCenter.y+yloc);
      g.rotate(rotation);
      g.scale(scale, scale);
      g.translate(-screenCenter.x-xloc, -screenCenter.y-yloc);
  }
  </code></pre>
  
  <p>I know the transforms occur in "opposite" order so the order above <em>should</em> be correct, but I have tried every permutation possible because, you know, why not.</p>
  
  <p>I have also tried using my <code>rotate</code> function to alter the position at the same time:</p>
  
  <pre><code>public void addRotation(int rot){
      double pi = Math.PI;
  
      rotation = rotation + ((double) (rot))*pi/180;
  
      if(rotation &gt; 2*pi){
          rotation = rotation - 2*pi;
      }else if(rotation &lt; 0){
          rotation = rotation + 2*pi;
      }
      double hypoteneuse = Math.sqrt((double) (xloc*xloc+yloc*yloc));
      xloc = Math.cos(rotation)*hypoteneuse;
      yloc = Math.sin(rotation)*hypoteneuse;
  }
  </code></pre>
  
  <p>To no avail. Note that the input is in degrees and Center stores the current rotation in radians, which are required by the <code>Math</code> and transform functions. All variables stored by Center are doubles -- using ints led to some (occasionally hilarious) rounding errors over a lot of rotations.</p>
  
  <p>For the record, here are my <code>translate</code> and <code>rotate</code> functions:</p>
  
  <pre><code>public void translate(int dx, int dy){
      xloc = xloc + dx;
      yloc = yloc + dy;
  }
  
  public void addRotation(int rot){
      rotation = rotation + ((double) (rot))*Math.PI/180;
  }
  </code></pre>
  
  <p>Obviously <code>xloc</code> and `yloc are the x and y location of the object on the screen, and the translate function always works properly when there is no rotation.</p>
  
  <hr>
  
  <p>On another note (I can probably figure this out if I can figure out the above, but may as well), it doesn't want to preserve the shape of the triangle -- after rotating, the x and y distance from the center of the screen are always the same.</p>
  
  <p>Halp?</p>