Search code examples
c#graphicsdrawrectangle

Rotate and Scale rectangle as per user control


I have UserControl of Size 300*200. and rectangle of size 300*200.

graphics.DrawRectangle(Pens.Black, 0, 0, 300, 200);

When I rotate rectangle in userControl by 30 degree, I get rotated rectangle but it is outsized.

PointF center = new PointF(150,100);
graphics.FillRectangle(Brushes.Black, center.X, center.Y, 2, 2); // draw center point.

using (Matrix matrix = new Matrix())
{
      matrix.RotateAt(30, center);
      graphics.Transform = matrix;
      graphics.DrawRectangle(Pens.Black, 0, 0, 300, 200);
      graphics.ResetTransform();
}

I want to fit rectangle like actual result.Check Image here

Can anyone have solution about this.

Thanks.


Solution

  • It's more of a math question than programming one.

    Calculate bouning box of any rectangle rotated by any angle in radians.

    var newWidth= Math.Abs(height*Math.Sin(angle)) + Math.Abs(width*Math.Cos(angle))
    var newHeight= Math.Abs(width*Math.Sin(angle)) + Math.Abs(height*Math.Cos(angle))
    

    Calculate scale for x and y:

    scaleX = width/newWidth;
    scaleY = height/newHeight;
    

    Apply it to your rectangle.

    EDIT: Applied to your example:

        PointF center = new PointF(150, 100);
        graphics.FillRectangle(Brushes.Black, center.X, center.Y, 2, 2); // draw center point.
        var height = 200;
        var width = 300;
        var angle = 30;
        var radians = angle * Math.PI / 180;
        var boundingWidth = Math.Abs(height * Math.Sin(radians)) + Math.Abs(width * Math.Cos(radians));
        var boundingHeight = Math.Abs(width * Math.Sin(radians)) + Math.Abs(height * Math.Cos(radians));
        var scaleX = (float)(width / boundingWidth);
        var scaleY = (float)(height / boundingHeight);
        using (Matrix matrix = new Matrix())
        {
            matrix.Scale(scaleX, scaleY, MatrixOrder.Append);
            matrix.Translate(((float)boundingWidth - width) / 2, ((float)boundingHeight - height) / 2);
            matrix.RotateAt(angle, center);
            graphics.Transform = matrix;
            graphics.DrawRectangle(Pens.Black, 0, 0, width, height);
            graphics.ResetTransform();
        }