开发者

Java 2D - Drag Mouse to rotate Image Smoothly

开发者 https://www.devze.com 2022-12-19 07:32 出处:网络
What is the logic that goes behind rotating an image via开发者_高级运维 mouse movement.I know how to rotate using graphics2d.rotate...but having difficulty doing it with the mouse as the source for ro

What is the logic that goes behind rotating an image via开发者_高级运维 mouse movement. I know how to rotate using graphics2d.rotate...but having difficulty doing it with the mouse as the source for rotation. Here is basic steps:

  1. get mouse x(dx) and mouse y(dy) distances from anchoring point( in this case that would be the center of the image we want to rotate).
  2. use this point in Math.arcTan2(dy,dx) to obtain the angle or rotation.
  3. use the value from step to for Graphics2D.rotate method.

With that strategy, everytime i rotate the image, the image starts rotating from -pi and after 90 degrees of rotation it go goes back to -pi. I don't understand what I'm doing wrong here, it should be pretty basic.

Here is a part of the code :

// mouse dragged events get sent here.
public void mouseDragged( MouseEvent e ) {
    int mx = e.getX( ), my = e.getY( );
    // just checking if it falls within bounds of the image we 
    // want to rotate.
    if( mx > speedKX || mx < speedKX + speedK.getWidth( ) || my > speedKY || my < speedKY + speedK.getHeight( )/2 )
    {
        theta += getTheta( e.getX( ), e.getY( ) ); 
    }
} 


As I understand you should look for the initial angle (when you clicked, the line between the anchor and your click) and the current angle (when you are dragging, same line). That angle (independent from the current distance to anchor point) will give you the rotation.

So you have to:

rotate(anglenow - angle0)

How to find it:

In both cases (initial click and mouse move event) you have to find angle between anchor and mouse point thinking the anchor as the origin.

I would use a method (getAngle(x1,y1,x2,y2). That method (except for race conditions like same x or same y, easily detectable) should calculate arctan(dy/dx).

Sign

But when you are dividing dy/dx it can be:

+ / + -> +
+ / - -> -
- / + -> -
- / - -> +

It is, four posibilities give you two kind of results. So, you have to look some condition to detect them.

I should review arctan doc or source to see what values it gives (between 0 and pi, or -pi/2 and +pi/2) and check then sign of the dx or the dy (depending on what range arctan returns) and use it to add/decrement pi to then resulting angle.

Then you'll get a getAngle method that return correctly the 360º space.

Edit

Javadoc says:

Math.atan retuns the arc tangent of an angle, in the range of -pi/2 through pi/2.

So, assuming your angle of value 0 is for the X axis as I assumed, the range it returns is the right hemisphere. So you have to distiguish the right hemisphere from the left one.

If you calculate dx = xtarget - xorigin (as you did for the division) it will be positive if the correct hemisphere is the right one, and negative if it's not.

So if dy < 0 then you have to add pi to your resulting angle. It will be between -pi/2 and 3pi/2. You also can correct the result by passing all to (-pi,pi) range or (0,2pi) range.

Edit: pseudocode, please double check!

onmousedown {
    startpoint = (x,y);
    startangle = getAngle(origin, startpoint);
}

onmousemove {
    currentpoint = (x,y);
    currentangle = getAngle(origin, currentpoint);
    originalimage.rotate(currentangle - startangle);
}

getAngle(origin, other) {
    dy = other.y - origin.y;
    dx = other.x - origin.x;
    if (dx == 0) // special case
        angle = dy >= 0? PI/2: -PI/2;
    else
    {
        angle = Math.atan(dy/dx);
        if (dx < 0) // hemisphere correction
            angle += PI;
    }
    // all between 0 and 2PI
    if (angle < 0) // between -PI/2 and 0
        angle += 2*PI;
    return angle;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消