如何对齐面对世界空间中的位置? [英] How to align a face to a position in world space?

查看:250
本文介绍了如何对齐面对世界空间中的位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数学问题。比方说,我有一个面(用3个或4个顶点),在一些世界上的地位。我想要翻译/旋转网格使面部是面对和居中(0,Y 0)。什么是退出这个功能所需要的式(S)?

I have a mathematical problem. Let's say I have a face (with 3 or 4 vertices) at some world position. I want to translate/rotate the mesh so that the face is "facing" up and is centered (0,y,0). What is the formula(s) needed to pull this off?

我可以使用GUI做到这一点(这个例子只是APPX的X轴旋转-90度),但是,我需要通过一个脚本来做到这一点,所以我需要知道如何进行数学做。

I can do this with a gui (this example was simply an x rotation of appx -90 degrees), however I need to do this via a script so I need to know how this can be done mathematically.

编辑: 我还应该注意到,这些载体是该我想(在(0,0,0原点))转动,直到V1为位置V2网格的一部分。

I should also note that these vectors are part of a mesh which I'm wanting to rotate (origin at (0,0,0)) till v1 is at position v2.

下面是伪code,它是失败的:

Here's the pseudo code that is failing:

v1 = vector(0,10,0)
v2 = vector(0,-10,0)

v1 = normalize(v1)
v2 = normalize(v2)

cross = normalize( v2.cross(v1) )  // (0,0,0)
angle = acos( v2.dot(v1) )  // 180

quat  = quaternion(cross,angle) // {w:1,x:0,y:0,z:0}

我还以为四元数会是这样的:{W:?,X:3.14159,Y:0,Z:0}或{W:?,X:0,Y:0,Z:3.14159}

I would have thought the quaternion would be something like: {w:?,x:3.14159,y:0,z:0} or {w:?,x:0,y:0,z:3.14159}

推荐答案

这问题可与旋转矩阵或四元数来解决,但是我建议旋转矩阵的路线,因为你可以同时解决所有点的跟单矩阵乘法。

This problem can be solved with either a rotation matrix or quaternions, however I would suggest the rotation matrix route because you can simultaneously solve all of the points with a single matrix multiplication.

旋转矩阵:如果你知道你想绕,然后的旋转矩阵是要走的路。为了形成一个旋转矩阵,看到该链接的基本轮作部分。不是知道什么是涨是,你需要知道你是多么想旋转你的对象。在此情况下(从提供的照片来看),要绕的全球的X轴(如果你愿意这样做有关的本地的轴,则必须90度知道对象的当前方位。我可以在编辑详细说明,如果你需要的本地的旋转)。您的全球的旋转矩阵为:

Rotation Matrix: If you know what what euler angles you wish to rotate about, then a rotation matrix is the way to go. To form a rotation matrix, see the "Basic Rotations" section of the link. Rather than knowing what "up" is, you need to know how much you wish to rotate your object. In this case (judging from the photos provided), you want to rotate 90 degrees about the global x axis (if you wish to do it about a local axis, you must know the current orientation of the object. I can elaborate in an edit if you need local rotations). Your global rotation matrix will be:

[1  0  0]
[0  0  1]
[0 -1  0]

我这个计算使用的接收(90)矩阵基本轮作部分。现在,形成你的3D分列向量。比方说,一个点是(0,0,1)。这一点直接在鼻部会,因此我们预计变换点为(0,1,0)。只要离开乘以旋转矩阵,让您的结果是:

I calculated this from using the Rx(90) matrix in the "Basic Rotations" section. Now, form your 3D points in column vectors. Let's say one point is at (0,0,1). This point is directly where the nose would be, so we expect the transformed point to be (0,1,0). Simply left multiply the rotation matrix to get your result:

[1  0  0] [0] [0]
[0  0  1]*[0]=[1]
[0 -1  0] [1] [0]

请注意,在这种情况下,转化是相当微不足道;我们只是移周围的坐标(x保持不变,y为否定,z和y被交换)。可以同时把一个大组点通过水平连接所有初始坐标,以形成一个矩阵3XN然后离开旋转矩阵相乘。例如,让我们变换点{(0,0,1),(0,1,0),(1,0,1),(0,0,-1)}

Note that in this case the transformation is fairly trivial; we are simply shifting the coordinates around (x stays the same, y is negated, z and y are swapped). You can simultaneously transform a large set of points by horizontally concatenating all of the initial coordinates to form a 3xN matrix and then left multiplying the rotation matrix. For instance, let's transform the points { (0,0,1), (0,1,0), (1,0,1), (0,0,-1) }:

[1  0  0] [0  0  1  0] [0  0  1  0]
[0  0  1]*[0  1  0  0]=[1  0  1  0]
[0 -1  0] [1  0  1 -1] [0 -1  0  1]

在此提醒,此变换绕着全局原点(如图所示的(1,0,1)点)。你将不得不减去你的坐标的重心,旋转,然后在最后加上平移坐标。

As a reminder, this transform rotates about the global origin (as illustrated by the (1,0,1) point). You will have to subtract the centroid of your coordinates, rotate, then add the final translation coordinates.

四元:我可以给这里的教程,但是这通常被称为轴角符号;你可以用它来创建一个旋转矩阵,将旋转的点关于由指定的角度任意单位轴。 这里是一个伟大的教程。让我知道如果我要阐述的编辑。

Quaternion: I can give a tutorial here, but this is often referred to as "axis-angle" notation; you can use it to create a rotation matrix that will rotate your points about an arbitrary unit axis by a specified angle. Here is a great tutorial for that. Let me know if I should elaborate in an edit.

编辑:响应于加入的伪code

in response to the added pseudo code

如果该叉积是0,那么该线平行。旋转轴可以垂直于任一输入(这使得它根据定义到两个垂直)的任何载体。矢量p被定义为垂直,如果点(V,P)== 0,或VX * p.x + VY * p.y + VZ * PZ == 0和长度(P)> 0,所以我们可以任意选择满足这些方程的任何解决方案。

If the cross product is 0, then the lines are parallel. The axis of rotation can be ANY vector perpendicular to EITHER input (which makes it perpendicular to both by definition). A vector p is defined as perpendicular if dot(v,p)==0, or v.x*p.x+v.y*p.y+v.z*p.z==0 and length(p)>0, so we can arbitrarily choose any solution that satisfies these equations.

v1 = vector(0,10,0)
v2 = vector(0,-10,0)

//Not necessary, since you will normalize the cross product result
//v1 = normalize(v1)
//v2 = normalize(v2)

cross = v2.cross(v1)  // (0,0,0) and possible divide by 0 if normalized here
if(length(cross)==0){ //either "==0" or "<thresh" where thresh is some very small number
   if(v.z!=0)
        cross = vector(1,1,-(v1.x+v1.y)/v1.z);
   else if(v.y!=0) //is z==0?  well here's an identical solution as long as y isn't 0
        cross = vector(1,-(v1.x+v1.z)/v.y,1);
   else //by this point, v1.x must be the only nonzero remaining point, otherwise it's a null vector
        cross = vector(-(v1.y+v1.z)/v.x,1,1);
}
cross=normalize(cross);
angle = acos( normalize(v2.dot(v1)) )  // 180

quat  = quaternion(cross,angle)

我不熟悉Python code,所以我增加了C ++相同。如果有人可以编辑这个职位纠正它,那会是一流的。

I'm not familiar with python code, so I added the C++ equivalent. If someone could edit this post to correct it, that'd be superb.

编辑:我没有看到你对ACOS,我们对此深感抱歉意见。相应地改变了code。

I didn't see your comment about acos, sorry about that. Changed the code accordingly.

这篇关于如何对齐面对世界空间中的位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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