title: How can I perform clipping on rotated rectangles?
body: <p>So I have this Panel class.  It's a little like a Window where you can resize, close, add buttons, sliders, etc.  Much like the status screen in Morrowind if any of you remember.  The behavior I want is that when a sprite is outside of the panel's bounds it doesn't get drawn and if it's partially outside only the part inside gets drawn.
  So what it does right now is first get a rectangle that represents the bounds of the panel, and a rectangle for the sprite, it finds the rectangle of intersection between the two then translates that intersection to the local coordinates of the sprite rectangle and uses <em>that</em> for the source rectangle.  It works and as clever as I feel the code is I can't shake the feeling that there's a better way to do this.  Also, with this set up I cannot utilize a global transformation matrix for my 2D camera, everything in the "world" must be passed a camera argument to draw.  Anyway, here's the code I have:<br>
  for the Intersection: </p>
  
  <pre><code>     public static Rectangle? Intersection(Rectangle rectangle1, Rectangle rectangle2)
       {
          if (rectangle1.Intersects(rectangle2))
          {
              if (rectangle1.Contains(rectangle2))
              {
                  return rectangle2;
              }
              else if (rectangle2.Contains(rectangle1))
              {
                  return rectangle1;
              }
              else
              {
                  int x = Math.Max(rectangle1.Left, rectangle2.Left);
                  int y = Math.Max(rectangle1.Top, rectangle2.Top);
                  int height = Math.Min(rectangle1.Bottom, rectangle2.Bottom) - Math.Max(rectangle1.Top, rectangle2.Top);
                  int width = Math.Min(rectangle1.Right, rectangle2.Right) - Math.Max(rectangle1.Left, rectangle2.Left);
                  return new Rectangle(x, y, width, height);
              }
          }
          else
          {
              return null;
          }
       }
  </code></pre>
  
  <p>and for actually drawing on the panel: </p>
  
  <pre><code>    public void DrawOnPanel(IDraw sprite, SpriteBatch spriteBatch)
      {
          Rectangle panelRectangle = new Rectangle(
             (int)_position.X,
             (int)_position.Y,
             _width,
             _height);
          Rectangle drawRectangle = new Rectangle();
  
          drawRectangle.X = (int)sprite.Position.X;
          drawRectangle.Y = (int)sprite.Position.Y;
          drawRectangle.Width = sprite.Width;
          drawRectangle.Height = sprite.Height;
  
          if (panelRectangle.Contains(drawRectangle))
          {
              sprite.Draw(
                  spriteBatch,
                  drawRectangle,
                  null);
          }
          else if (Intersection(panelRectangle, drawRectangle) == null)
          {
              return;
          }
          else if (Intersection(panelRectangle, drawRectangle).HasValue)
          {
              Rectangle intersection = Intersection(panelRectangle, drawRectangle).Value;
  
              if (Intersection(panelRectangle, drawRectangle) == drawRectangle)
              {
                  sprite.Draw(spriteBatch, intersection, intersection);
              }
              else
              {
                  sprite.Draw(
                      spriteBatch,
                      intersection,
                      new Rectangle(
                          intersection.X - drawRectangle.X,
                          intersection.Y - drawRectangle.Y,
                          intersection.Width,
                          intersection.Height));
              }
          }
      }
  </code></pre>
  
  <p>So I guess my question is, is there a better way to do this?</p>
  
  <p>Update:  Just found out about the ScissorRectangle property.  This seems like a decent way to do this; it requires a RasterizerState object to be made and passed into the spritebatch.Begin overload that accepts it.  Seems like this might be the best bet though.  There's also the Viewport which I can apparently change around.  Thoughts? :)</p>