如何总是从一个特定的方向转动是从、方向

2023-09-08 10:46:28 作者:捂着心脏说疼

(道歉提前。我的数学技能和说明的权力似乎已经离开我的那一刻) 想象屏幕上的立方体具有两组对照。一组控制旋转立方体边到边(又名偏航或Y,甚至ž取决于一个人的数学倾向),另一套控制来上下转动(又名间距或X)。

我想要做的就是让这个两集SOF控制始终旋转立方体相对于浏览器/屏幕不论如何立方体正在旋转。

任一矩阵或基于四元数旋转的常规组合不会达到这样的效果,因为旋转得到以串行方式施加(与每个旋转从其中previous 1不放过开始)。

例如。随着伪code combinatedRotation = RotateYaw(90)* RotatePitch(45) 会给我,似乎是滚到一边,因为沥青旋转已旋转,以及一个立方体。 (或者一个更生动的例子 RotateYaw(180)* RotatePitch(45)将产生它出现在球场工作在反向屏幕立方体)

有人可以任意点我还是提供正确的方式,使两个旋转相互独立的作用,使不论如何立方体正在旋转偏航和变桨工作关系,预期到屏幕上的控制?

解决方案

修改3:这只是发生,我认为解决的下方,而正确的,是过于复杂。可以通过简单地通过方向矩阵乘以旋转矩阵来计算新取向达到相同的效果:

  M =  -  [R * M
 

虽然不相关的问题,这也将正确处理未由纯粹的旋转方向矩阵,也包含平移,倾斜等。

(编辑3完)

我们学习过 在平面内.将一个图形绕一个定点沿着某个方向转动一个角度.这样的图形运动叫做旋转.这个定点称为旋转中心.旋转的角度称为旋转角.如图. ABC经过旋转得到

您需要一个转换矩阵,包括你的对象的局部坐标系的当前旋转轴。然后应用旋转到矩阵。

在数学术语中,你开始与单位矩阵如下:

  M = [1 0 0 0]
    [0 1 0 0]
    [0 0 1 0]
    [0 0 0 1]
 

这矩阵包括三个矢量,U,V和W,即再present—在世界坐标—你的对象的局部坐标系的三个单位向量:

  M = [Vx的的Ux蜡质0]
    [UY Vy速度怀俄明州0]
    [乌斯VZ WZ 0]
    [0 0 0 1]
 

当您要旋转的对象,每个旋转向量的原位的。换言之,独立地应用旋转到每个U,V和W的基质中。

在渲染,简单地套用M用单一的变换,你的对象。 (如果你想知道,不适用的旋转本身;只是矩阵)

编辑2:(出现的第一个编辑之前,因为它提供上下文吧)

在长重温这个答案是最初发布后,我意识到,我可能没有拿起,你可能有关于如何从每个控制应用旋转而产生的误解。

的想法是不积累由每个控制所施加的旋转,并分别应用它们。相反,你应立即应用每个增量旋转(即每次你的滑块控件之一触发一个更改事件)到U,V和W的载体。

为了把这个更具体而言,不要说,总体而言,垂直控制已经移动47°,水平控制已经转移-21°,并将其应用于两个大旋转。这将显示出它促生你的问题同样的问题。相反,说,垂直滑块刚搬到0.23°,并旋转U,V和W绕X轴0.23°。

总之,90°偏转其次是45以下描述°间距可能不是你想要的。

编辑:按照要求,这里是如何的90°偏转的情况下接着45°俯仰盘子在实践中...

既然你开始与单位矩阵,在此基础载体将只是你的世界单位向量:

  U = [1] V = [0] W = [0]
    [0] [1] [0]
    [0] [0] [1]
 

要应用90°偏转,绕Z轴每个基矢量(反映我的数学斜塔),这几乎是微不足道的:

  U = [0] V = [-1] W = [0]
    [1] [0] [0]
    [0] [0] [1]
 

因此​​,90°偏转后,变换矩阵将是:

  M = [0 -1 0 0]
    [1 0 0 0]
    [0 0 1 0]
    [0 0 0 1]
 

应用这个矩阵的主题将实现绕Z轴所需的90°旋转。

要再经45°适用45°俯仰(我会好好待绕X轴),我们转动我们的新的基础载体,在YZ平面,这时候:

  U = [0] V = [-1] W = [0]
    [0.7] [0] [-0.7]
    [0.7] [0] [0.7]
 

因此​​,新的变换矩阵是:

  M = [0 -1 0 0]
    [0.7 0 -0.7 0]
    [0.7 0 0.7 0]
    [0 0 0 1]
 

如果你乘的两个旋转起来:

偏航(90)*间距(45)= [0 -1 0 0] * [1 0 0 0] = [0 -0.7 0.7 0]
                    [1 0 0 0] [0 0.7 -0.7 0] [1 0 0 0]
                    [0 0 1 0] [0 0.7 0.7 0] [0 0.7 0.7 0]
                    [0 0 0 1] [0 0 0 1] [0 0 0 1]

间距(45)*偏航(90)= [1 0 0 0] * [0 -1 0 0] = [0 -1 0 0]
                    [0 0.7 -0.7 0] [1 0 0 0] [0.7 0 -0.7 0]
                    [0 0.7 0.7 0] [0 0 1 0] [0.7 0 0.7 0]
                    [0 0 0 1] [0 0 0 1] [0 0 0 1]
 

您会发现,第二种形式是一样的通过操纵基向量生成的变换矩阵,但是这仅仅是一个巧合(和相当常见的一种混合了90°和45°旋转时)。在一般情况下,施用​​顺序既不将匹配的基础变换

我虎头蛇尾,所以我希望解释至今使事情变得更加清晰,没有泥泞。

(Apologies in advance. My math skills and powers of description seem to have left me for the moment) Imagine a cube on screen with a two sets of controls. One set of controls to rotate the cube side to side (aka yaw or Y or even Z depending on one's mathematical leanings) and another set of controls to rotate up and down (aka pitch or X).

What I would like to do is make it so that the two set sof controls always rotate the cube in relation to the viewer / screen irrespective of how the cube is currently rotated.

A regular combination of either matrix or quaternion based rotations doesn't achieve this effect because the rotations get applied in a serial fashion (with each rotation "starting" from where the previous one left off).

e.g. With the psuedo code of combinatedRotation = RotateYaw(90) * RotatePitch(45) will give me a cube that appears to be "rolling" to one side because the Pitch rotation has been rotated as well. (or for a more dramatic example RotateYaw(180) * RotatePitch(45) will produce a cube where it appears the the pitch is working in reverse to the screen)

Can somebody either point me to or supply the correct way to make the two rotations independant from each other in effect so that irrespective of how the cube is currently rotated Yaw and Pitch work "as expected" in relation to the on screen controls?

解决方案

EDIT 3: It just occurred to me that the solution below, while correct, is unnecessarily complicated. You can achieve the same effect by simply multiplying the rotation matrix by the orientation matrix to compute the new orientation:

M = R * M

Though not relevant to the question, this would also correctly handle orientation matrices that aren't made up of pure rotation, but also contain translation, skew, etc.

(End of edit 3)

You need a transform matrix comprising the current rotated axes of your object's local coordinate system. You then apply rotations to that matrix.

In mathematical terms, you start with an identity matrix as follows:

M = [1  0  0  0]
    [0  1  0  0]
    [0  0  1  0]
    [0  0  0  1]

This matrix comprises three vectors, U, V and W, that represent — in world coordinates — the three unit vectors of your object's local coordinate system:

M = [Ux Vx Wx 0]
    [Uy Vy Wy 0]
    [Uz Vz Wz 0]
    [0  0  0  1]

When you want to rotate the object, rotate each vector in situ. In other words, apply the rotation independently to each of U, V and W within the matrix.

When rendering, simply apply M as a single transform to your object. (In case you're wondering, don't apply the rotations themselves; just the matrix.)

EDIT 2: (Appears before the first edit, since it provides context for it.)

On revisiting this answer long after it was originally posted, I've realised that I might not have picked up on a misunderstanding that you might have about how to apply rotations from each control.

The idea is not to accumulate the rotation to be applied by each control and apply them separately. Rather, you should apply each incremental rotation (i.e., every time one of your slider controls fires a change event) immediately to the U, V and W vectors.

To put this in more concrete terms, don't say, "In total, the vertical control has moved 47° and the horizontal control has moved -21°" and apply them as two big rotations. That will exhibit the same problem that motivated your question. Instead, say, "The vertical slider just moved 0.23°", and rotate U, V and W about the X-axis by 0.23°.

In short, the 90° yaw followed by 45° pitch described below is probably not what you want.

EDIT: As requested, here's how the case of 90° yaw followed by 45° pitch pans out in practice...

Since you start with the identity matrix, the basis vectors will simply be your world unit vectors:

U = [1]  V = [0]  W = [0]
    [0]      [1]      [0]
    [0]      [0]      [1]

To apply the 90° yaw, rotate each basis vector around the Z-axis (reflecting my mathematical leaning), which is almost trivial:

U = [0]  V = [-1]  W = [0]
    [1]      [ 0]      [0]
    [0]      [ 0]      [1]

Thus, after the 90° yaw, the transform matrix will be:

M = [0 -1  0  0]
    [1  0  0  0]
    [0  0  1  0]
    [0  0  0  1]

Applying this matrix to the subject will achieve the desired 90° rotation around Z.

To then apply a 45° pitch (which I'll take to be around the X-axis), we rotate our new basis vectors in the YZ-plane, this time by 45°:

U = [0  ]  V = [-1]  W = [ 0  ]
    [0.7]      [ 0]      [-0.7]
    [0.7]      [ 0]      [ 0.7]

Thus, the new transform matrix is:

M = [0    -1   0    0]
    [0.7   0  -0.7  0]
    [0.7   0   0.7  0]
    [0     0   0    1]

If you multiply the two rotations together:

Yaw(90)*Pitch(45) = [0 -1 0 0]*[1  0    0    0] = [0  -0.7  0.7  0]
                    [1  0 0 0] [0  0.7 -0.7  0]   [1   0    0    0]
                    [0  0 1 0] [0  0.7  0.7  0]   [0   0.7  0.7  0]
                    [0  0 0 1] [0  0    0    1]   [0   0    0    1]

Pitch(45)*Yaw(90) = [1  0    0    0]*[0 -1 0 0] = [0    -1   0    0]
                    [0  0.7 -0.7  0] [1  0 0 0]   [0.7   0  -0.7  0]
                    [0  0.7  0.7  0] [0  0 1 0]   [0.7   0   0.7  0]
                    [0  0    0    1] [0  0 0 1]   [0     0   0    1]

You'll notice that the second form is the same as the transform matrix produced by manipulating the basis vectors, but this is just a coincidence (and quite a common one when mixing up 90° and 45° rotations). In the general case, neither order of application will match the basis-transform.

I've run out of steam, so I hope the explanation so far makes things clearer, not muddier.