计算机图形学:旋转一个多边形 [英] Computer Graphics: Rotating a polygon

查看:148
本文介绍了计算机图形学:旋转一个多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目的



我正在使用Java AWT实现多边形轮换。



我已经能够在屏幕上绘制多边形,并且我想在我的多边形坐标上手动应用旋转矩阵(旋转在用户的lookAt点附近完成)。

我已经做了什么



为了旋转世界,用户首先点击屏幕,然后拖动鼠标执行旋转。



让我们将第一个点击点设置为S,将拖动事件中的下一个点设置为L,将屏幕中心设置为C

为了计算旋转角度,当第一次点击屏幕时,我保留了一个从C到S的向量:CS。

然后,当一个拖动事件发生,我计算从C到L的向量:CL。
然后我计算CS到CL之间的角度弧度,这就是我在我的世界中应用的。



这很好用,并且多边形的确在围绕lookAt点旋转。



我的问题



当用户完成PI的旋转,然后多边形向后旋转。



例如当用户开始旋转时,角度从0.1 ... 0.2 ... 1 .. 2 .. 3 ..开始,在值〜3.1(我假设为PI)时,数值开始下降:3 .. 。2 .. 1 ...直到0,反之亦然。

这是合理的,因为弧度范围是[0,PI]。



我假设基矢CS位于X轴的右侧,当旋转向下到X轴以下时,多边形向后旋转。

然而,我不知道如何始终保持多边形在相同的方向上旋转(当用户围绕多边形执行完整旋转时)。





角度函数是: 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)));


解决方案

这是一个问题arcus cosine,acos(cos(x))是一个周期性的帽子函数,在0到pi的范围内上下移动。在更高的维度上,这是无法避免的,因为没有参考的首选框架,所以没有办法说 phi 确实应该是 -phi 。在二维中,平面有一个首选的方向,以便人们可以说出什么是第一个矢量,什么是第二个矢量,并在正方向上定义一个独特的角度。旋转情况,以便第一个矢量位于正实半轴上,以便从旋转后的第二个矢量的坐标获得角度和正确的象限。



最简单重构是一个复杂的图像,计算角度从 a = a.x + i * ay b = b.x + i * / code>旋转 b 返回乘以 a 的共轭以得到零角度的角度RESP。正的实轴,

  arg((ax-i * ay)*(b.x + i * by))

= arg((ax * b.x + ay * by)+ i *(ax * by-ay * bx))

= atan2(ax * by-ay * bx,ax * b.x + ay * by)

请注意,屏幕坐标使用相反的方向到笛卡儿/复合平面,从而将 atan2(y,x)更改为 atan2(-y,x)到在通常的方向上获得一个角度。


Purpose

I'm implementing a polygon rotation with Java AWT.

I'm already able to draw polygons on the screen, and I'd like to apply a rotation matrix manually upon my polygons coordinates (rotation is done around the lookAt point of the user).

What I've already done

In order to rotate the world, the user first clicks on the screen and then drags the mouse around to perform the rotation.

Let's note the first click point as S, the following point from the drag event as L, and the center of the screen as C.

In order to calculate the rotation angle, when first clicking the screen, I keep a vector from C to S: C-S.

Then, when a drag event occurs, I calculate the vector from C to L: C-L. I then calculate the angle in radians between C-S to C-L, and that's what I apply on my world.

This works well, and the polygon is indeed rotation around the lookAt point.

My problem

The problem occurs when the user finishes a rotation of PI, and then the polygon is rotating backward.

e.g. When the user starts rotating, the angle starts from 0.1.... 0.2... 1.. 2.. 3.. and in value ~3.1 (I assume PI), the values are starting to go down: 3... 2.. 1.. until 0, and vice versa.

This makes sense since the radians range is [0, PI].

I assume the base vector C-S lies on the right side of X axis, and when the rotation goes down below the X axis the polygon is rotating backwards.

However, I have no idea how to keep the polygon rotating in the same direction all the time (when the user performs a full rotation around the polygon).

Edit

Angle function is:

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 )));
}

解决方案

This is a problem of the arcus cosine, acos(cos(x)) is a periodic hat function moving up and down in the range of 0 to pi.

In higher dimensions that can not be avoided, as there is no preferred frame of reference, so there is no way to say that phi should really be -phi. In 2 dimensions there is a prefered orientation of the plane so that one can say what is the first and what the second vector and define a unique angle in positive orientation. Rotate the situation so that the first vector comes to lay on the positive real half axis to get the angle and correct quadrant from the coordinates of the rotated second vector.

Easiest to reconstruct is the complex picture, to compute the angle from a=a.x+i*a.y to b=b.x+i*b.y rotate b back by multiplying with the conjugate of a to get an angle from the zero angle resp. the positive real axis,

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 )

Note that screen coordinates use the opposite orientation to the cartesian/complex plane, thus change atan2(y,x) to atan2(-y,x) to get an angle in the usual direction.

这篇关于计算机图形学:旋转一个多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆