2017-03-02 239 views
1

如何获得两个单位向量之间的x,y和z旋转值?我不能使用点积,因为这只给了我一个值。我想使用旋转矩阵在每个轴上进行旋转,对于那些我需要每个轴上的角度差异的旋转矩阵。 我试过只有两个组件的点积,但我有点困惑。 有没有一个快速简单的方法来做到这一点?也许我对这两件事情做错了,但我不知道。 最好是,如果有人知道一个glsl方法来做这件事情!获取矢量之间的xyz角度?

回答

2

如果您想获得两个矢量之间的x,y和z角度,请将两个矢量的投影的点积乘积到所需轴的正交平面上。

也就是说,如果您需要两个矢量之间的z角,请创建原件的xy平面矢量。为此,创建一个忽略向量的z分量的向量。

vec3 u = vec3(...); // your input vector 
vec3 v = vec3(...); // your other input vector 
float x_angle = acos(dot(u.yz, v.yz)); 
float y_angle = acos(dot(u.xz, v.xz)); 
float z_angle = acos(dot(u.xy, v.xy)); 

请注意,如果您使用u.xzu.zx,因为你会使用点产品也没关系。只要确保在点积中使用相同的顺序即可。此外,此处代码的第3 - 5行假定单位矢量,因为表达式中没有提到矢量长度。

还应该注意的是,使用acos可能会导致参数值较小的错误。为避免这种情况,可以采用2D投影向量之间的差异,并与atan2函数一起使用。

编辑

在建议,最终目标是建立一个旋转矩阵重新定向与所述相同的变换的其它载体,我建议使用轴角的方法(也称为任意轴旋转)。该方法包括找出两个向量(点积)和该角度所对的适当的旋转轴之间的角度(叉积)。

第一步,您想要使用点积来找出两个向量之间的角度。

float angle = acos(dot(u, v)); // for unit vectors 

接下来,要找到旋转轴,请使用叉积。知道叉积将产生一个垂直于uv的矢量,以任一顺序交叉它们将给出合适的轴。

vec3 axis = cross(u, v); // again, for unit vectors 
// normalize this if need be 

你将要使用的矩阵的形式可以由轴和角度旋转矩阵的对这个Wikipedia article的标题下找到。我建议存储一些临时值以使计算运行更快。

float c = cos(angle); 
float s = sin(angle); 
float t = 1 - c; 

一旦您构建了该矩阵,只需将其乘以任何向量即可重新应用原始变换。

+0

这没什么用:我用u和v做了同样的矢量,我基本上得到了矢量(out =(0,0,1),in =(0,0,1)) 。它也没有与其他vectros工作 –

+0

你的整个过程得到一个新的载体是什么?我很想知道你的最终目标是什么。另外,如上所述,如果您使用的是acos,则向量可能会有些相同。例如,在Lua中,我不得不限制输入以避免产生NaN。 – Nathan

+0

好的。我的目标是获得树轴上的旋转差异,所以我可以将这些值插入到旋转矩阵中,并使用这些值旋转另一个向量。然后旋转的矢量Y轴将与我的其他矢量对齐。 –