0

Basically what I'm trying to do is have a picture rotate using mouse events. For example, while you hold down the left mouse button, the picture rotates when you move the mouse up and down. I found another question on here almost like mine (How do I rotate a picture in C#) but when mapping the angle parameter in the rotate method (method source code in link) to the calculated angle between the mouse and the center of the image I get an overflow exception thrown. The image I'm trying to rotate is in a picture box. Any ideas? Should I be doing this another way?

Thanks in advance!

---------EDIT 1-----------

Ok I think my trig was off, I changed it to...

Angle = Atan((mousePosY - imageCenterY)/(mousePosX - imageCenterX)

But now the image doesn't rotate, it just moves (I programmed the ability for it to move as well but that works fine). Here's the piece of code I'm dealing with.

    private void pictureBox_MouseDown(object sender, MouseEventArgs e)
    {
        isDragging = true;

        pbCurrentX = e.X;
        pbCurrentY = e.Y;

    }

    private void pictureBox_MouseMove(object sender, MouseEventArgs e)
    {
        // For moving the image
        if (isDragging)
        {
            this.pictureBox1.Top = this.pictureBox1.Top + (e.Y - pbCurrentY);
            this.pictureBox1.Left = this.pictureBox1.Left + (e.X - pbCurrentX);
        }

        // For rotating the image
        if (rotateMode  && isDragging)
        {
            y2 = e.Y;
            y1 = (this.pictureBox1.Location.Y + (this.pictureBox1.Height / 2));
            x2 = e.X;
            x1 = (this.pictureBox1.Location.X + (this.pictureBox1.Width / 2));

            angle = (float)Math.Atan((y2-y1)/(x2-x1));

            // RotateImage method from the other question linked above
            this.pictureBox1.Image = RotateImage(this.pictureBox1.Image, angle);
        }


    }

The rotateMode flag is set to true when the pictureBox is double clicked. Thanks all!

---------ANSWER-----------

Thanks to Gabe I found all of the little kinks in my code and it works fine now. Only thing is I had to make the size of the picture box larger to fit the rotated image. Here is the correct code for everyone who wants to know the answer.

private void pictureBox_MouseDown(object sender, MouseEventArgs e)
    {
        isDragging = true;

        pbCurrentX = e.X;
        pbCurrentY = e.Y;

    }

    private void pictureBox_MouseMove(object sender, MouseEventArgs e)
    {

        if (isDragging && !rotateMode)
        {
            this.pictureBox1.Top = this.pictureBox1.Top + (e.Y - pbCurrentY);
            this.pictureBox1.Left = this.pictureBox1.Left + (e.X - pbCurrentX);
        }

        if (rotateMode  && isDragging)
        {
            y2 = e.Y;
            y1 = (this.pictureBox1.Location.Y + (this.pictureBox1.Height / 2));
            x2 = e.X;
            x1 = (this.pictureBox1.Location.X + (this.pictureBox1.Width / 2));

            angle = (float)Math.Atan2((y1 - y2), (x1 - x2));

            pictureBox1.Image =  RotateImage(currentImage, (100*angle));
        } 

    }

    private void pictureBox_MouseUp(object sender, MouseEventArgs e)
    {
        isDragging = false;
    }

Thanks Gabe and everyone else!

Community
  • 1
  • 1
Gaax
  • 540
  • 8
  • 18
  • Could you please show the code which fails? – Vlad Feb 28 '10 at 00:20
  • 1
    You may have been trying to use an angle in degrees, while the rotation parameter is supposed to be in radians. – Gabe Feb 28 '10 at 00:55
  • Thank god there are still some people who have the courtesy to post their solutions for others to learn from! –  Aug 22 '10 at 04:51

4 Answers4

1

Without seeing your code, we can only guess. My guess is that you're doing some kind of trig calculation, such as:

theta = Math.Atan((y2 - y1) / (x2 - x1));

If your x2-x1 goes towards 0, your argument to Math.Atan goes towards infinity, and overflows.

mbeckish
  • 10,485
  • 5
  • 30
  • 55
1

Have you tried something along the lines of this.pictureBox1.Image = RotateImage(this.pictureBox1.Image, angle);? The RotateImage function you linked to returned a new rotated image rather than rotating it in-place as your code expects.

Unfortunately, doing that rotates an already-rotated image. What you need to do is have the original image stored somewhere, say originalImage. Then have this.pictureBox1.Image = RotateImage(originalImage, angle);. That way it always rotates a fresh version of the original.

Gabe
  • 84,912
  • 12
  • 139
  • 238
  • Aha! Didn't catch that and it works now, thank you! But now I have an entirely new problem... lol it distorts the image every time it rotates to the point where it's unrecognizable. Any ideas? – Gaax Feb 28 '10 at 17:49
  • I set up a global variable called currentImage to store the original image: Image currentImage = picturebox1.Image Now I get a NullReferenceException inside of the RotateImage method when it creates a new bitmap using the dimensions of the image: "Object reference not set to an instance of an object." – Gaax Feb 28 '10 at 19:28
  • If you are getting a NullReferenceException, it just means that you are not initializing `currentImage` at the right time or you are not calling `RotateImage(currentImage, angle)`. – Gabe Feb 28 '10 at 19:49
  • Ha, yeah you're right. I feel kind of stupid for even posting that >< Thanks man it all works fine now! – Gaax Feb 28 '10 at 20:44
0

Angle = Atan((mousePosY - imageCenterY)/(mousePosX - imageCenterY)

You are using imageCenterY twice there, (although its ok in the code you posted).

Anyway I would suggest using Atan2 rather than Atan.

0
     int  y2 = _cursory; // Cursor.Postion.Y

     int   y1 = (this.pictureBox1.Location.Y + (this.pictureBox1.Height / 2));
     int x2 = _cursorx; // Cursor.Postion.X
     int   x1 = (this.pictureBox1.Location.X + (this.pictureBox1.Width / 2));

      float  angle = (float)Math.Atan2((y1 - y2), (x1 - x2));
      float xDistance = x1 - this.pictureBox1.Location.X;
      float yDistance = y1 - this.pictureBox1.Location.Y;

      double deg = angle / Math.PI * 180 + 180;
      pictureBox1.Image = RotateImage(img, (int)deg);

// img == original image

this code worked for me

Ehsan KHAN
  • 141
  • 1
  • 6