Pankaj
Pankaj

Reputation: 2754

Calculate angle while rotating rectangle

I have a program in C# (Windows Forms) which has a rectangle on a Picture Box. They can be drawn at an angle too (rotated). I want to rotate that rectangle using my mouse movements.

I have the code for moving that rectangle

Rectangle areaRect = new Rectangle(100,100, 300, 300);
Bool dragging = false;
Point ptOld = new Point(0, 0);

protected override void OnPaint(PaintEventArgs e)
{
  Graphics dcPaint = e.Graphics;
  dcPaint.DrawRectangle(rectPen, areaRect);
}

protected override void OnMouseDown(MouseEventArgs e)
{
  ptOld = new Point(e.X, e.Y);
  dragging = true;
}

protected override void OnMouseMove(MouseEventArgs e)
{
  if(dragging = true) 
  {
    Point ptNew = new Point(e.X, e.Y);
    int dx = ptNew.X - ptOld.X;
    int dy = ptNew.Y - ptOld.Y;
    areaRect.Offset(dx, dy); // This one moves the rectangle 
    ptOld = ptNew;
    this.Invalidate();
  }
}

protected override void OnMouseUp(MouseEventArgs e)
{
  dragging = false;
}

Now My requirement is to rotate this rectangle, Any idea, how that can be achieved.

Upvotes: 0

Views: 3379

Answers (3)

Ove
Ove

Reputation: 6317

You can calculate the angle using the difference between the old and the new x mouse coordinate (dx in your example). You can use the RotateTransform method of the Graphics object to rotate the rectangle.

I modified your code to do the rotation in addition to the translation. You can move the rectangle with the left mouse button and you can rotate it using the right mouse button.

Rectangle areaRect = new Rectangle(100, 100, 300, 300);
bool dragging = false;
bool rotating = false;
Point ptOld = new Point(0, 0);
float angle = 0;

protected override void OnPaint(PaintEventArgs e)
{
    Graphics dcPaint = e.Graphics;
    dcPaint.RotateTransform(angle);
    dcPaint.DrawRectangle(Pens.Black, areaRect);
    dcPaint.RotateTransform(-angle);
}

protected override void OnMouseDown(MouseEventArgs e)
{
    ptOld = new Point(e.X, e.Y);
    if (e.Button == MouseButtons.Left)
    {
        dragging = true;
    }
    if (e.Button == MouseButtons.Right)
    {
        rotating = true;
    }
}

protected override void OnMouseMove(MouseEventArgs e)
{
    if (dragging == true)
    {
        Point ptNew = new Point(e.X, e.Y);
        int dx = ptNew.X - ptOld.X;
        int dy = ptNew.Y - ptOld.Y;
        areaRect.Offset(dx, dy); // This one moves the rectangle 
        ptOld = ptNew;
        this.Invalidate();
    }
    if (rotating == true)
    {
        Point ptNew = new Point(e.X, e.Y);
        int dx = ptNew.X - ptOld.X;
        angle = angle + dx / 10f;
        ptOld = ptNew;
        this.Invalidate();
    }
}

protected override void OnMouseUp(MouseEventArgs e)
{
    dragging = false;
    rotating = false;
}

Right now, the rectangle is rotated around its top left corner. If you apply a translation before the rotation, you can get it to rotate around its middle.

Upvotes: 0

CharlesB
CharlesB

Reputation: 90456

When rotating rectangle with mouse, you define the center of rotation (centerXY), in you case it will be the center of the rectangle maybe.

On mouse down record mouse coordinates, mouse_downXY. These two points define a base line. When moving mouse you'll define another line, formed by current mouse coordinates and the rectangle center.

So you'll need to compute the angle between line (centerXY, mouse_downXY) and (centerXY, current_mouseXY). Computing angle between 2 lines with knowing 3 points coordinates is simple trigonometry, so I won't write code for you :) However this post has the answer.

Upvotes: 0

Habib
Habib

Reputation: 223372

I think you want to calculate angle between two points on X-axis. If so, try the following code:

const double Rad2Deg = 180.0 / Math.PI;

return Math.Atan2(ptOld.Y - e.Y, e.X - ptOld.X) * Rad2Deg;

Also check out this article on calculating angle between two points

Upvotes: 2

Related Questions