我从坐标系Y = up,X = right,Z = backwards的传感器数据得到四元数.Mine是X =正向,Y =正确,Z =向上.
所以OX = Y,OY = Z且OZ = -X.
我有一个函数可以将四元数转换为4by4矩阵,但不知道从哪里开始.任何帮助将不胜感激.
当我在某个位置有一个QUAD时,我怎么能以这样的方式旋转它以使其法线指向一个给定的点?想象一下,彩色块只是矩形四边形,然后这个图像显示了我的意思.四边形都以这样的方式定向,它们指向球体的中心.
alt text http://emrahgunduz.com/wp-content/uploads/2009/01/material_id_gui-600x364.jpg
也许这第二张图片显示了我正在尝试的更多内容: alt text http://img689.imageshack.us/img689/3130/screenshot20100708at555.png
我正在使用openGL/C++(以及Eigen lib).我有这个代码来绘制一个简单的四边形:
#include "ofMain.h"
#include "Quad.h"
Quad::Quad(Vector3f oPosition):position(oPosition) {
}
void Quad::update() {
}
void Quad::draw() {
float size = 1.3;
glColor3f(1.0f, 0.0f, 0.6f);
glPushMatrix();
glTranslatef(position.x(), position.y(), position.z());
glScalef(size, size,size);
glBegin(GL_QUADS);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glVertex3f(1,1,0);
glVertex3f(0,1,0);
glEnd();
glPopMatrix();
}
Run Code Online (Sandbox Code Playgroud)
更新17-07 亲爱的读者,
旋转四边形进一步了解一下.我随机定位了几个四边形,然后look_at使用此代码使用以下回复中的描述将它们旋转到vector3f:
void Quad::draw() {
float size = 0.5;
glColor3f(1.0f, 0.0f, 0.6f);
glPushMatrix();
Vector3f center = look_at - position;
Vector3f center_norm = center.normalized();
float r_angle = acos(center_norm.dot(normal));
Vector3f axis = normal.normalized().cross(center_norm); …Run Code Online (Sandbox Code Playgroud) 我一直试图找到2之间的区别,但没有运气减去这个
两个表示之间的主要差异在于四元数的旋转轴由半旋转角的正弦缩放,而不是将角度存储在矢量的第四个分量中,我们存储半角的余弦.
我不知道是什么
半角旋转的正弦
要么
半角的余弦
手段?
我目前正在GLSL中实现骨架动画着色器,为了节省空间和复杂性,我使用四元数进行骨骼旋转,使用加权四元数乘法(每个骨骼)为每个顶点累积"最终旋转".
像:(伪代码,只是假设四元数数学按预期工作)
float weights[5];
int bones[5];
vec4 position;
uniform quaternion allBoneRotations[100];
uniform vec3 allBonePositions[100];
main(){
quaternion finalQuaternion;
for(i=0;i<5;i++){finalQuaternion *= allBoneRotations[bones[i]]*weights[i];}
gl_position = position.rotateByQuaternion(finalQuaternion);
}
Run Code Online (Sandbox Code Playgroud)
真正的代码是复杂的,草率的,并按预期工作,但这应该给出一般的想法,因为这主要是一个数学问题,代码没有太大影响,它只是为了清晰起见.
当我意识到"最终四元数"不会采用不同的支点时,我正在向每个骨骼添加"枢轴点"/"关节位置"(负翻译,通过"最终四元数"旋转,翻译回来)在组合四元数时自己考虑.在这种情况下,每个骨骼旋转都将被视为在点(0,0,0)附近.
鉴于四元数仅代表一个旋转,似乎我需要向四元数"添加"一个位置(如果可能),或者只是将所有四元数转换为矩阵,然后进行矩阵乘法以组合一系列的平移和旋转.我真的希望后者不是必要的,因为它似乎相对来说效率很低.
我已经搜索了mathoverflow,math.stackexchange以及谷歌提供的任何其他内容并阅读了以下资源,希望能够自己找出答案:
加上通过谷歌搜索发现的各种其他小讨论(我只能发布2个链接)
一致认为,Quaternions在任何意义上都不编码"翻译"或"位置",并且似乎没有提供直观的方法来模拟它,因此纯四元数数似乎不太可能是一个可行的解决方案.
但是,在这里找到明确的答案可能会很好.有没有人知道任何方法来"伪造"四元数的位置组件,以某种方式保持四元数数学效率,或者某种其他方法在不同的原点周围"累积"旋转,这比仅计算矩阵更有效四元数,以及每个四元数的矩阵平移和旋转乘法?或者也许一些不同轴心点的数学保证实际上没有任何区别,事实上可以在以后应用(但我对此表示怀疑).
或者在这种情况下使用四元数只是一个坏主意呢?
我可以找到很多关于将四元数转换为方向向量的问题,但是没有其他问题让我觉得我做错了什么,但请耐心等待.
我想要做的只是使用箭头模型显示定向光的方向.
方向光的方向是单位矢量,但模型使用四元数旋转.
那么..如何旋转此模型以匹配光的方向?
或者我是疯了,我不能真的这样做,因为光没有位置,但模型呢?
我有一个Y轴为UP的坐标系.我需要将它转换为Z为UP的坐标系.我将旋转存储在四元数中,所以我的问题是:如果我有一个四元数X,Y,Z我可以用Z切换Y并获得Z实际上是UP的结果吗?
我有两个描述旋转的向量; 开始旋转A和目标旋转B.我最好如何用因子F插值A来接近B?
当需要插入多个维度(即产生不希望的旋转)时,在矢量上使用简单的lerp无法工作.也许从旋转向量构建四元数并使用slerp是可行的方法.但是,如何从结果四元数中提取描述新旋转的向量?
提前致谢.
经过一番思考,我想出了以下代码,用于使用SSE乘以两个四元数:
#include <pmmintrin.h> /* SSE3 intrinsics */
/* multiplication of two quaternions (x, y, z, w) x (a, b, c, d) */
__m128 _mm_cross4_ps(__m128 xyzw, __m128 abcd)
{
/* The product of two quaternions is: */
/* (X,Y,Z,W) = (xd+yc-zb+wa, -xc+yd+za+wb, xb-ya+zd+wc, -xa-yb-zc+wd) */
__m128 wzyx = _mm_shuffle_ps(xyzw, xyzw, _MM_SHUFFLE(0,1,2,3));
__m128 baba = _mm_shuffle_ps(abcd, abcd, _MM_SHUFFLE(0,1,0,1));
__m128 dcdc = _mm_shuffle_ps(abcd, abcd, _MM_SHUFFLE(2,3,2,3));
/* variable names below are for parts of componens of result (X,Y,Z,W) */
/* nX stands for -X …Run Code Online (Sandbox Code Playgroud) 我尝试基于四元数学实现FPS相机.我存储一个旋转四元数变量,_quat并在需要时将其乘以另一个四元数.这是一些代码:
void Camera::SetOrientation(float rightAngle, float upAngle)//in degrees
{
glm::quat q = glm::angleAxis(glm::radians(-upAngle), glm::vec3(1,0,0));
q*= glm::angleAxis(glm::radians(rightAngle), glm::vec3(0,1,0));
_quat = q;
}
void Camera::OffsetOrientation(float rightAngle, float upAngle)//in degrees
{
glm::quat q = glm::angleAxis(glm::radians(-upAngle), glm::vec3(1,0,0));
q*= glm::angleAxis(glm::radians(rightAngle), glm::vec3(0,1,0));
_quat *= q;
}
Run Code Online (Sandbox Code Playgroud)
应用程序可以通过GetOrientation简单地将四元数转换为矩阵来请求方向矩阵.
glm::mat4 Camera::GetOrientation() const
{
return glm::mat4_cast(_quat);
}
Run Code Online (Sandbox Code Playgroud)
应用程序按以下方式更改方向:
int diffX = ...;//some computations based on mouse movement
int diffY = ...;
camera.OffsetOrientation(g_mouseSensitivity * diffX, g_mouseSensitivity * diffY);
Run Code Online (Sandbox Code Playgroud)
这会在几乎所有轴周围产生不良的混合旋转.我究竟做错了什么?