views:

672

answers:

3

Hi everyone. 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!

+1  A: 

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
A: 

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.

Courtney de Lautour
Changed it but I still have the same issue :(
Gaax
Yes, you need to use Atan2 for this, otherwise your image won't be able to rotate in a full circle.
Gabe
+1  A: 

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
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
I set up a global variable called currentImage to store the original image: Image currentImage = picturebox1.ImageNow 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
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
Ha, yeah you're right. I feel kind of stupid for even posting that >< Thanks man it all works fine now!
Gaax