title: Re-size a rotated rectangle using mouse drag in c#
body: <p>It will seems to most of the guys here that it's a repeated question but it isn't. </p>
  
  <p>I am having a very hard problem. I have a rectangle which can be re-sized when it's not rotated and all work fine. But when it's rotated the algorithm is not working. The code is below:</p>
  
  <pre><code>internal void resizeToPoint(int tmpX, int tmpY, Rectangle limits)
  {
      Matrix m = new Matrix();
      m.Reset();
  
      m.Translate(mLayoutRectangle.X + mParent.getAbsXOffset(DEPTH_LEVEL.APA) + mLayoutRectangle.Width / 2, mLayoutRectangle.Y + mParent.getAbsYOffset(DEPTH_LEVEL.APA) + mLayoutRectangle.Height / 2);
      m.Rotate(-(int)mAngle);
      m.Translate(-(mLayoutRectangle.X + mParent.getAbsXOffset(DEPTH_LEVEL.APA) + mLayoutRectangle.Width / 2), -(mLayoutRectangle.Y + mParent.getAbsYOffset(DEPTH_LEVEL.APA) + mLayoutRectangle.Height / 2));
  
      Point pPrime = new Point();
      pPrime.X = (int)((m.Elements[0] * tmpX + m.Elements[2] * tmpY) + (int)m.Elements[4]);
      pPrime.Y = (int)((m.Elements[1] * tmpX + m.Elements[3] * tmpY) + (int)m.Elements[5]);
  
      Point BottomRight = new Point(mLayoutRectangle.Width + getAbsXOffset(), mLayoutRectangle.Height + getAbsYOffset());
      Point TopRight = new Point(mLayoutRectangle.Width + getAbsXOffset(), getAbsYOffset());
      Point TopLeft = new Point(getAbsXOffset(), getAbsYOffset());
      Point BottomLeft = new Point(getAbsXOffset(), mLayoutRectangle.Height + getAbsYOffset());
  
      Point TopMiddle = new Point((mLayoutRectangle.Width / 2) + getAbsXOffset(), getAbsYOffset());
      Point RightMiddle = new Point(mLayoutRectangle.Width + getAbsXOffset(), mLayoutRectangle.Height / 2 + getAbsYOffset());
      Point BottomMiddle = new Point(getAbsXOffset() + mLayoutRectangle.Width / 2, mLayoutRectangle.Height + getAbsYOffset());
      Point LeftMiddle = new Point(getAbsXOffset(), getAbsYOffset() + mLayoutRectangle.Width / 2);
  
      Rectangle newLocationRectangle = mLayoutRectangle;
      Double widthRatioHeight = 1;
  
      if (this is ImageDesignElement)
      {
          widthRatioHeight = (double)((ImageDesignElement)this).getMonochromeImage().Width / (double)((ImageDesignElement)this).getMonochromeImage().Height;
          //widthRatioHeight = (double)mLayoutRectangle.Width / (double)mLayoutRectangle.Height;
      }
  
      int rectangleOldWidth = newLocationRectangle.Width;
      int rectangleOldHeight = newLocationRectangle.Height;
      int rectangleOldX = newLocationRectangle.X;
      int rectangleOldY = newLocationRectangle.Y;
  
  
      switch (mSelectedHandleForScaling)
      {
          case HANDLE_TYPE.TOP_LEFT:
              if (newLocationRectangle.Height - (pPrime.Y - TopLeft.Y) &gt; 0)
              {
                  newLocationRectangle.Height -= (pPrime.Y - TopLeft.Y);
                  newLocationRectangle.Y += (pPrime.Y - TopLeft.Y);
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              if (newLocationRectangle.Width - (pPrime.X - TopLeft.X) &gt; 0)
              {
                  newLocationRectangle.Width -= (pPrime.X - TopLeft.X);
                  newLocationRectangle.X += (pPrime.X - TopLeft.X);
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              break;
  
          case HANDLE_TYPE.TOP_MIDDLE:
              if (newLocationRectangle.Height - (pPrime.Y - TopMiddle.Y) &gt; 0)
              {
                  newLocationRectangle.Height -= (pPrime.Y - TopMiddle.Y);
                  newLocationRectangle.Y += (pPrime.Y - TopMiddle.Y);
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              break;
  
          case HANDLE_TYPE.TOP_RIGHT:
              if (newLocationRectangle.Height - (pPrime.Y - TopRight.Y) &gt; 0)
              {
                  newLocationRectangle.Height -= (pPrime.Y - TopRight.Y);
                  newLocationRectangle.Y += (pPrime.Y - TopRight.Y);
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              if (newLocationRectangle.Width + pPrime.X - TopRight.X &gt; 0)
              {
                  newLocationRectangle.Width += pPrime.X - TopRight.X;
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              break;
  
          case HANDLE_TYPE.RIGHT_MIDDLE:
  
              if (newLocationRectangle.Width + pPrime.X - RightMiddle.X &gt; 0)
              {
                  newLocationRectangle.Width += pPrime.X - RightMiddle.X;
              }
              mInitialScalePoint.X = pPrime.X;
              mInitialScalePoint.Y = pPrime.Y;
              break;
  
          case HANDLE_TYPE.BOTTOM_RIGHT:
              if (newLocationRectangle.Height + pPrime.Y - BottomRight.Y &gt; 0)
              {
                  newLocationRectangle.Height += pPrime.Y - BottomRight.Y;
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              if (newLocationRectangle.Width + pPrime.X - BottomRight.X &gt; 0)
              {
                  newLocationRectangle.Width += pPrime.X - BottomRight.X;
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
  
              break;
  
          case HANDLE_TYPE.BOTTOM_MIDDLE:
              if (newLocationRectangle.Height + pPrime.Y - BottomMiddle.Y &gt; 0)
              {
                  newLocationRectangle.Height += pPrime.Y - BottomMiddle.Y;
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              break;
  
          case HANDLE_TYPE.BOTTOM_LEFT:
              if (newLocationRectangle.Height + pPrime.Y - BottomLeft.Y &gt; 0)
              {
                  newLocationRectangle.Height += pPrime.Y - BottomLeft.Y;
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              if (newLocationRectangle.Width - (pPrime.X - BottomLeft.X) &gt; 0)
              {
                  newLocationRectangle.Width -= (pPrime.X - BottomLeft.X);
                  newLocationRectangle.X += (pPrime.X - BottomLeft.X);
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              break;
  
          case HANDLE_TYPE.LEFT_MIDDLE:
              if (newLocationRectangle.Width - (pPrime.X - BottomLeft.X) &gt; 0)
              {
                  newLocationRectangle.Width -= (pPrime.X - BottomLeft.X);
                  newLocationRectangle.X += (pPrime.X - BottomLeft.X);
                  mInitialScalePoint.X = pPrime.X;
                  mInitialScalePoint.Y = pPrime.Y;
              }
              break;
      }
  
      if (((Control.ModifierKeys &amp; Keys.Shift) != Keys.Shift) &amp;&amp; this is ImageDesignElement)
      {
  
          int hightChange = newLocationRectangle.Height - rectangleOldHeight;
          int widthChange = newLocationRectangle.Width - rectangleOldWidth;
  
          newLocationRectangle.Width = rectangleOldWidth;//reset to the old Width before the call of this method
          newLocationRectangle.Width += (int)(((double)hightChange) * widthRatioHeight); //use the difference is width to adjust Width
  
          if (mSelectedHandleForScaling == HANDLE_TYPE.TOP_LEFT || mSelectedHandleForScaling == HANDLE_TYPE.BOTTOM_LEFT)
          {
              newLocationRectangle.X = rectangleOldX + (rectangleOldWidth - newLocationRectangle.Width);
          }
  
      }
  
      if (this is ImageDesignElement)
      {
          mLayoutRectangle = newLocationRectangle;
          //Console.WriteLine("* mLayoutRectangle.Width =" + mLayoutRectangle.Width + " mLayoutRectangle.Height =" + mLayoutRectangle.Height);
  
      }
      else
      {
          mLayoutRectangle = newLocationRectangle;
      }
  }
  </code></pre>
  
  <p>Now, here we have a <code>mLayoutRectangle</code> a rectangle object in which some corners can be dragged with new position <code>tmpX</code> and <code>tmpY</code> through mouse. <code>mAngle</code> is the angle in degree rotated.</p>
  
  <p>The problem is when <strong>angle is between 0 and 80</strong> it works fine but when the angle is greater than this its behavior is changed totally. I don't get what I am doing wrong here.</p>
  
  <p>I have used the following rectangle datatype: <a href="https://msdn.microsoft.com/en-us/library/system.drawing.rectangle(v=vs.110).aspx" rel="nofollow noreferrer">Rectangle Structure from MSDN</a>. I want to set the left, right, top and bottom values for this rectangle. Can i somehow extend it, so that i can set values for left, right, top and bottom???</p>
  
  <p>The problem is well explained here: but i have to do that in window form not WPF.
  <a href="https://stackoverflow.com/questions/16091137/scaling-of-a-rotated-element?rq=1">Exact explanation of the problem</a></p>