Java 2D-拖动鼠标以平滑地旋转图像
通过鼠标移动旋转图像背后的逻辑是什么。我知道如何使用graphics2d进行旋转。旋转…但在使用鼠标作为旋转源时有困难。以下是基本步骤:Java 2D-拖动鼠标以平滑地旋转图像,java,image,mouseevent,Java,Image,Mouseevent,通过鼠标移动旋转图像背后的逻辑是什么。我知道如何使用graphics2d进行旋转。旋转…但在使用鼠标作为旋转源时有困难。以下是基本步骤: 获取鼠标x(dx)和鼠标y(dy)距离锚定点的距离(在这种情况下,将是 要旋转的图像的中心) 在Math.arcTan2(dy,dx)中使用该点获得角度或旋转 对于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( ) );
}
}
//将鼠标拖动的事件发送到此处。
公共无效鼠标标记(鼠标事件e){
intmx=e.getX(),my=e.getY();
//只是检查它是否在我们看到的图像范围内
//要旋转。
如果(mx>speedKX | | mxspeedKY | | my
据我所知,您应该查找初始角度(单击时,锚点和单击之间的线)和当前角度(拖动时,相同的线)。该角度(与当前到锚定点的距离无关)将为您提供旋转
因此,你必须:
rotate(anglenow - angle0)
如何找到它:
在这两种情况下(初始单击和鼠标移动事件),您必须找到锚点和鼠标点之间的角度,将锚点视为原点
我会使用一种方法(getAngle(x1,y1,x2,y2),这种方法(除了像相同x或相同y这样的竞争条件,很容易检测)应该计算arctan(dy/dx)
符号
但当你除以dy/dx时,它可以是:
+ / + -> +
+ / - -> -
- / + -> -
- / - -> +
是的,四个可能性给了你两种结果。所以,你必须寻找一些条件来检测它们
我应该查看arctan doc或source,看看它给出了什么值(介于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;
}
onmousedown{
起始点=(x,y);
startangle=getAngle(原点,起始点);
}
移动{
电流点=(x,y);
currentangle=getAngle(原点,currentpoint);
原始图像。旋转(当前角度-星形缠结);
}
getAngle(原点,其他){
dy=其他.y-原点.y;
dx=其他.x-原点.x;
if(dx==0)//特殊情况
角度=dy>=0?π/2:-π/2;
其他的
{
角度=数学常数(dy/dx);
if(dx<0)//半球校正
角度+=π;
}
//都在0和2PI之间
如果(角度<0)//介于-PI/2和0之间
角度+=2*PI;
返回角;
}
有可能看到一些代码吗?看起来像是三角问题……是的,当然,这里://鼠标拖动的事件发送到这里。public void mouseDragged(MouseEvent e){int mx=e.getX(),my=e.getY();//只是检查它是否在我们想要旋转的图像的范围内//如果(mx>speedKX | | mx