Re-size a rotated rectangle using mouse drag in c#
<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>