目的
我正在使用Java AWT实现多边形旋转。
我已经能够在屏幕上绘制多边形,并且我想在多边形坐标上手动应用旋转矩阵(旋转是围绕用户的lookAt点进行的)。
我已经做了什么
为了旋转世界,用户首先在屏幕上单击,然后在周围拖动鼠标以执行旋转。
让我们将第一个单击点记为S,将拖动事件的下一个点记为L,将屏幕中心记为C。
为了计算旋转角度,在第一次单击屏幕时,我将向量从C保留到S:C-S。
然后,当发生拖动事件时,我计算从C到L的向量:C-L。
然后,我计算出C-S到C-L之间的弧度角,这就是我应用于世界的角度。
这很好用,并且多边形确实围绕lookAt点旋转。
我的问题
当用户完成PI的旋转,然后多边形向后旋转时,就会出现问题。
例如当用户开始旋转时,角度从0.1 ..... 0.2 ... 1 .. 2 .. 3 ..开始,并且在值?3.1(我假设为PI)中,值开始下降:3 .. 2 .. 1.直到0,反之亦然。
这是有道理的,因为弧度范围是[0,PI]。
我假设基本向量C-S位于X轴的右侧,并且当旋转下降到X轴以下时,多边形向后旋转。
但是,我不知道如何始终保持多边形在相同方向上旋转(当用户围绕多边形执行完整旋转时)。
编辑
角度功能为:
public final double angle(Vector2D v1)
{
double vDot = this.dot(v1) / ( this.length()*v1.length() );
if( vDot < -1.0) vDot = -1.0;
if( vDot > 1.0) vDot = 1.0;
return ((double) (Math.acos( vDot )));
}
您是否愿意使用反余弦进行角度计算? 然后切换到atan2方法。
"这是有道理的,因为弧度范围是[0,PI]。" 不,其0、2Pi。
你什么意思? 编辑并添加了角度功能。
@LutzL您的评论已解决此问题,请将其发布为答案,以便我批准。
这是反正弦余弦的一个问题,acos(cos(x))是一个周期性的帽子函数,在0到pi范围内上下移动。
在更高的尺寸中,由于没有首选的参照系,因此无法避免,因此没有办法说phi应该确实是-phi。在2维中,有一个首选的平面方向,以便人们可以说什么是第一个向量,什么是第二个向量,并在正方向上定义一个唯一的角度。旋转情况,使第一个向量位于正实半轴上,以从旋转的第二个向量的坐标获取角度并校正象限。
最容易重建的是复杂图片,通过乘以a的共轭来计算从a=a.x+i*a.y到b=b.x+i*b.y的角度,然后将b向后旋转b,以从零角度resp获得角度。正实轴,
arg((a.x-i*a.y)*(b.x+i*b.y))
=arg((a.x*b.x+a.y*b.y)+i*(a.x*b.y-a.y*b.x))
=atan2( a.x*b.y-a.y*b.x , a.x*b.x+a.y*b.y )
请注意,屏幕坐标使用与笛卡尔/复杂平面相反的方向,因此将atan2(y,x)更改为atan2(-y,x)可获得通常方向上的角度。
public Point rotate(Point original, Point vertex, double angle){
Point translated = new Point(original.x - vertex.x, original.y - vertex.y);
int x = (int)Math.round(translated.x * Math.cos(angle) - translated.y * Math.sin(angle));
int y = (int)Math.round(translated.x * Math.sin(angle) + translated.y * Math.cos(angle));
return new Point(vertex.x+x,vertex.y+y);
}
这是一种简单的旋转方法,可用于围绕给定顶点旋转点。
这不是我的问题,我有一个旋转矩阵,可以很好地工作。 该对象旋转良好,但是一旦完成一半旋转,它就会开始向后旋转,这取决于我的角度计算。