Java 2D-拖动鼠标以平滑旋转图像
作者:互联网
通过鼠标移动旋转图像背后的逻辑是什么?我知道如何使用graphics2d.rotate进行旋转…但是很难用鼠标作为旋转源.这是基本步骤:
>获得距锚点的鼠标x(dx)和鼠标y(dy)的距离(在这种情况下,
我们要旋转的图像的中心).
>在Math.arcTan2(dy,dx)中使用此点来获取角度或旋转.
>将step的值用于Graphics2D.rotate方法.
使用这种策略,每当我旋转图像时,图像都会从-pi开始旋转,旋转90度后,图像会回到-pi.我不明白我在做什么错,这应该是很基本的.
这是代码的一部分:
// 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( ) );
}
}
解决方法:
据我了解,您应该寻找初始角度(单击时为锚点和点击之间的线)和当前角度(拖动时为同一行).该角度(与当前距锚点的距离无关)将为您提供旋转角度.
因此,您必须:
rotate(anglenow - angle0)
如何找到它:
在这两种情况下(初始单击和鼠标移动事件),您都必须找到以锚点为原点的锚点和鼠标点之间的角度.
我会使用一种方法(getAngle(x1,y1,x2,y2).该方法(除了类似x或y的竞争条件,易于检测)应该计算arctan(dy / dx).
标志
但是,当您划分dy / dx时,它可以是:
+ / + -> +
+ / - -> -
- / + -> -
- / - -> +
就是说,四个可能性给您两种结果.因此,您必须查看一些条件才能检测到它们.
我应该查看arctan doc或源代码,以查看其给出的值(0和pi之间,或-pi / 2和pi / 2之间),然后检查dx或dy的符号(取决于arctan返回的范围)并使用它将pi添加/减少到最终角度.
然后,您将获得一个getAngle方法,该方法可以正确返回360º空间.
编辑
Javadoc说:
Math.atan调整角度的反正切,范围为-pi / 2到pi / 2.
因此,假设您的值0角是我假设的X轴,则它返回的范围是右半球.因此,您必须区分左半球的右半球.
如果计算dx = xtarget-xorigin(如除法运算),则正确的半球是正确的将为正,否则为负.
因此,如果dy< 0,则必须将pi添加到结果角度.介于-pi / 2和3pi / 2之间.您还可以通过将全部传递到(-pi,pi)范围或(0,2pi)范围来校正结果. 编辑:伪代码,请仔细检查!
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;
}
标签:image,mouseevent,java 来源: https://codeday.me/bug/20191106/2001455.html