标签: quaternions

四元数的方向向量?

我有一个四元数代表3D字符上臂的旋转.我还有一条线应该代表角色手臂的新位置.该线位置由两个3D点给出.

这是我拥有的唯一数据,我试图调用3D包(数字符文)中的方法,该方法采用2个方向向量并返回表示将手臂移动到新位置所需的旋转的四元数.

问题是我看到了一些奇怪的行为,就好像轴混合在一起而且通常没有表现.此外,代表3D人员手臂的Quaternion对象(来自3D包)具有W,X,Y和Z.X,Y和Z是否代表方向向量?因为这就是我需要正确调用函数.我一直在使用它和我计算出的方向向量来自我的线端点,但正如我所说的看起来很有趣.

如果X,Y和Z不是方向向量,如何从四元数转换为两个端点,那么我可以计算方向向量?

3d vector rotation quaternions

7
推荐指数
1
解决办法
1万
查看次数

将单位矢量转换为四元数

所以我对四元数很新,但我理解如何用它们操作东西的基础知识.我目前要做的是将已知的四元数与空间中的两个绝对点进行比较.我希望我能做的只是将点转换成第二个四元数,让我有一个简单的方法来比较两者.

到目前为止我所做的是将这两个点转换为单位向量.从那里我希望我可以直接将ijk插入四元数的虚部,标量为零.从那里我可以将一个四元数乘以另一个四元数,得到第三个四元数.这个第三个四元数可以转换成轴角,给出原始两个四元数相差的程度.

这个思维过程是否正确?所以它应该只是[0 ijk].之后我可能需要规范化四元数,但我不确定.

我有一种不好的感觉,它不是从向量到四元数的直接映射.我试着将单位矢量转换为轴角度,但我不确定这会起作用,因为我不知道作为输入给出的角度.

axis vector angle quaternions

6
推荐指数
1
解决办法
3802
查看次数

将对象的旋转方向调整为THREE.JS中的样条点切线

我正在使用SplineCurve3仅在X轴和Y轴上绘制一条线,我有一个立方体成功动画沿着这条线使用spline.getPoint(t),其中t是0-1的时间.我试图通过使用点积的Y向量将立方体定向到线.

它几乎是对齐的,但是有点微不足道.我以为我会使用Y矢量的点积和当前点的切线作为旋转四元数的角度.

这是我的渲染功能:

function render() {

    var updateMatrix = new THREE.Matrix4(); 
    updateMatrix.setPosition(spline.getPoint(t));

    var angle = new THREE.Vector3(0,1,0).dot(spline.getTangent(t).normalize());

    var quat = new THREE.Quaternion;
    quat.setFromAxisAngle(new THREE.Vector3(0,0,1), angle);
    updateMatrix.setRotationFromQuaternion(quat);

    marker.rotation.getRotationFromMatrix(updateMatrix);
    marker.matrixWorld = updateMatrix;

    t = (t >= 1) ? 0 : t += 0.002;

    renderer.render(scene, camera); 
}
Run Code Online (Sandbox Code Playgroud)

这是一个演示我的问题的小提琴,有人能告诉我旋转方面出了什么问题吗?

你可以编辑我的 - jsfiddle示例

matrix quaternions three.js

6
推荐指数
1
解决办法
6927
查看次数

如何找到从一个向量到另一个向量的正确旋转?

我有两个对象,每个对象有两个向量:

  • 法线向量
  • 向上矢量

就像这张图片:

在此处输入图片说明

向上向量垂直于法向量。现在我想找到从一个对象到另一个对象的唯一旋转,该怎么做?

我有一种方法可以找到一个向量到另一个向量之间的旋转,并且它有效。问题是我需要注意两个向量:法向量和向上向量。如果我使用此方法将法线向量从对象 1 旋转到对象 2 的法线,则向上向量可能指向错误的方向,并且它们需要平行。

这是查找最短旋转的代码:

GE::Quat GE::Quat::fromTo(const Vector3 &v1, const Vector3 &v2)
{
    Vector3 a = Vector3::cross(v1, v2);
    Quat q;

    float dot = Vector3::dot(v1, v2);

    if ( dot >= 1 ) 
    {
        q = Quat(0,0,0,1);

    }
    else if ( dot < -0.999999 )
    {
        Vector3 axis = Vector3::cross(Vector3(1,0,0),v2);

        if (axis.length() == 0) // pick another if colinear
                axis = Vector3::cross(Vector3(0,1,0),v2);
        axis.normalize();
        q = Quat::axisToQuat(axis,180);
    }
    else
    {
        float s = sqrt( (1+dot)*2 );
        float …
Run Code Online (Sandbox Code Playgroud)

c++ opengl rotation quaternions

6
推荐指数
1
解决办法
1万
查看次数

为什么我的直接四元数乘法比SSE快?

我已经经历了一些不同的四元数乘法实现,但是我很惊讶地发现参考实现到目前为止是我最快的.这是有问题的实施:

inline static quat multiply(const quat& lhs, const quat& rhs)
{
    return quat((lhs.w * rhs.x) + (lhs.x * rhs.w) + (lhs.y * rhs.z) - (lhs.z * rhs.y),
                (lhs.w * rhs.y) + (lhs.y * rhs.w) + (lhs.z * rhs.x) - (lhs.x * rhs.z),
                (lhs.w * rhs.z) + (lhs.z * rhs.w) + (lhs.x * rhs.y) - (lhs.y * rhs.x),
                (lhs.w * rhs.w) - (lhs.x * rhs.x) - (lhs.y * rhs.y) - (lhs.z * rhs.z));
}
Run Code Online (Sandbox Code Playgroud)

我尝试了一些其他的实现,一些使用SSE,一些不使用.以下是一个这样的SSE实现的示例,基本上是从Bullet Physics使用的库中复制的:

inline static __m128 multiplynew(__m128 lhs, …
Run Code Online (Sandbox Code Playgroud)

c++ optimization sse quaternions

6
推荐指数
1
解决办法
2760
查看次数

如何避免在Core Motion控制的SceneKit相机中滚动?

我正在CMDeviceMotion使用本答案中描述的CMDeviceMotion扩展将SceneKit相机设置为当前姿态:

func deviceDidMove(motion: CMDeviceMotion?, error: NSError?) {
    if let motion = motion {
        let orientation = motion.gaze(atOrientation: UIApplication.sharedApplication().statusBarOrientation)
        cameraNode.orientation = orientation
    }
}
Run Code Online (Sandbox Code Playgroud)

这很漂亮,但是,我想阻止旋转(滚动)并且只允许相机转动(偏转)和俯仰.

我试图将四元数转换回欧拉角,并将roll保持为0:

cameraNode.eulerAngles = SCNVector3(
            x: orientation.pitch(),
            y: orientation.yaw(),
            z: 0)
Run Code Online (Sandbox Code Playgroud)

然而,这仅适用于偏航运动的一半.另一半,相机倒置.我怀疑这是涉及欧拉角的万向节锁定问题.

四元数对我来说有点像黑魔法,但是有没有办法直接在四元数上去除滚动分量,这样我就可以避免欧拉角?

camera quaternions ios core-motion scenekit

6
推荐指数
0
解决办法
669
查看次数

关于glm四元数旋转

我想通过四元数进行一些旋转。

glm 库在这方面做得很好。

以下是我的代码:

vec3 v(0.0f, 0.0f, 1.0f);
float deg = 45.0f * 0.5f;
quat q(glm::cos(glm::radians(deg)), 0, glm::sin(glm::radians(deg)), 0);
vec3 newv = q*v;
printf("v %f %f %f \n", newv[0], newv[1], newv[2]);
Run Code Online (Sandbox Code Playgroud)

我的问题是,在许多文章中,四元数旋转的公式是

rotated_v = q*v*q_conj
Run Code Online (Sandbox Code Playgroud)

有点奇怪。在glm中,向量“v”只需乘以四元数“q”就可以进行旋转。

这让我很困惑。

opengl quaternions glm-math

6
推荐指数
1
解决办法
7981
查看次数

将角速度积分为四元数旋转

我已经(有点盲目地)在物理刚体模拟中使用四元数进行旋转有一段时间了,但最近开始对四元数旋转通常是如何定义的以及我是如何定义的(基于游戏开发者的物理书)感到困惑。

在书中,您有一个角速度 angVel 和一个时间步长 dt 以及一个初始方向。

它的步骤如下

方向 += 0.5*方向*angVel * dt

其中四元数向量乘法是通过首先将向量 xyz 转换为四元数 xyz,0 来完成的

这是可行的,但在其他任何地方,程序都是创建一个四元数,它定义了时间积分 angVel,在 dt 上,然后在方向上乘以它。它本质上将 angVel*dt 转换为旋转(非常有意义),然后通过乘法将其应用于原始方向,如下所示,语法更好https://math.stackexchange.com/questions/39553/how-do- i-apply-an-angular-velocity-vector3-to-a-unit-quaternion-orientation

我的问题是上面的 0.5 * 四元数 * 矢量 * 标量在概念上什么,以及这个结果四元数添加到我的方向是什么,考虑到你通常乘法而不是加法来旋转。

rotation rigid-bodies quaternions

6
推荐指数
1
解决办法
8645
查看次数

Cesiumjs 从向量计算俯仰、偏航、航向

我将 Cesium 的模型之一加载到场景中,并且我想使用两个点来计算模型的方向,这是我创建的函数。

// calculate the direction which the model is facing
calculateOrientation({ position, nextPosition }) {

    let dir = new Cesium.Cartesian3();
    let normalizedDir = new Cesium.Cartesian3();

    Cesium.Cartesian3.subtract(nextPosition, position, dir);
    Cesium.Cartesian3.normalize(dir, normalizedDir);

    var heading = Math.acos(normalizedDir.x);
    var pitch = Math.acos(normalizedDir.y);
    var roll = 0;

    var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
    var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
    return orientation;
}
Run Code Online (Sandbox Code Playgroud)

但我得到的轮换没有任何意义。我的数学错了吗?

更新

在@Keshet 给出第一个答案后,我查找了如何找到平面和向量之间的角度。我想如果我找到每个平面的法线和 -90 之间的角度,我应该得到正确的角度,但我不确定这是否正确。

另外我不知道Cesium Axis是如何工作的,也找不到任何描述它的文档。例如XY平面等。

    let dir = new Cesium.Cartesian3();
    let xyNormal = new Cesium.Cartesian3(0,0,1);
    let xzNormal = …
Run Code Online (Sandbox Code Playgroud)

javascript rotation linear-algebra quaternions cesiumjs

6
推荐指数
1
解决办法
2405
查看次数

Quaternion division and hyperbolic tangent tanh

Quaternion multiplication is well-defined, and is known to me as "Hamilton product":

// hamilton product
vec4 qmul(in vec4 q1, in vec4 q2) {
    return vec4(
        q1.w * q2.xyz + q2.w * q1.xyz - cross(q1.xyz, q2.xyz),
        q1.w*q2.w - dot(q1.xyz, q2.xyz)
    );
}
Run Code Online (Sandbox Code Playgroud)

However, for implementing qtanh() quaternionic function, we need division. So far I've found this, and it is working OK. Could you help me to undestand, where does this comes from?

// division
// https://www.boost.org/doc/libs/1_67_0/boost/math/quaternion.hpp
vec4 qdiv(in vec4 q1, in …
Run Code Online (Sandbox Code Playgroud)

glsl linear-algebra quaternions hyperbolic-function

6
推荐指数
1
解决办法
92
查看次数