3d 如何用4D向量表示旋转?

3d 如何用4D向量表示旋转?,3d,rotation,scenekit,3d,Rotation,Scenekit,我正在学习如何使用SceneKit,我对涉及SCInvector4的方法/属性深感困惑,例如SCNPhysicsBody.applyTorque和SCNNode.rotation。显然,您可以仅使用4个值来表示三维对象的旋转。我完全不明白这是为什么 我在网上搜索了“用4d矢量表达3d旋转”,发现了很多关于4d空间旋转的东西,这不是我想要的。我也看到很多关于罪与因的网页,但我不明白它们的意思。我对正反方向的知识仅限于寻找直角三角形的角度/边长 在我看来,3D对象的旋转需要用7个值表示,即7D向量:

我正在学习如何使用SceneKit,我对涉及
SCInvector4
的方法/属性深感困惑,例如
SCNPhysicsBody.applyTorque
SCNNode.rotation
。显然,您可以仅使用4个值来表示三维对象的旋转。我完全不明白这是为什么

我在网上搜索了“用4d矢量表达3d旋转”,发现了很多关于4d空间旋转的东西,这不是我想要的。我也看到很多关于罪与因的网页,但我不明白它们的意思。我对正反方向的知识仅限于寻找直角三角形的角度/边长

在我看来,3D对象的旋转需要用7个值表示,即7D向量:

  • 3旋转轴一端的位置值
  • 3旋转轴另一端的位置值
  • 1表示旋转角度的值
我想我对SpriteKit中的2D旋转理解得很好:每个节点都有一个锚点,因此旋转属性就是锚点的弧度。但是,我在
SCNNode
中找不到这样的定位点。当我查找“锚点scnnode”时,我得到了关于
ARSCNNode
的东西,这不是我想要的

我还看了一下,上面写着:

x、y和z分量确定旋转轴,而w分量确定旋转角度,即扭矩大小

仅x、y、z组件如何指定旋转轴

你能解释一下我怎么能对这种疯狂的行为束手无策吗

我想现在的问题是“节点上的‘原点’在哪里?”

它由(减去)
SCNNode.position
()给出。这是相对于其父节点应用于它的转换

。。。和“如何用3个标量表示2个角度”

根据本发明,3D中的任何旋转都可以由轴和旋转角度来表示。这些信息可依次存储为:

  • (如
    @OliverCharlesworth
    所建议的)2个球面极角指定轴,另一个指定旋转角度
  • 或平行于轴的向量,其大小与其顺时针(或逆时针)旋转成正比;例如,这通常是角速度的表示方式
  • SceneKit仅使用4D矢量,以避免在笛卡尔坐标系中重新计算轴(对于(1))或检索角度(对于(2))

    在我看来,3D对象的旋转需要用7来表示 值,即7D向量:

    • 3旋转轴一端的位置值
    • 3旋转轴另一端的位置值
    • 1表示旋转角度的值
    问题在于:您混淆了“轴”一词的两个定义,它们可以是:

    • 空间中的固定线,如X轴
    • 相互平行的线族的共同方向

    按照惯例,第二个用于指定旋转。旋转的中心是节点的中心位置(通常是其AABB的中点)。

    我意识到我可以编写一个小的“SceneKit控制台”来测试向量中的四个值中的每一个值的作用

    我将一个文本字段、一个按钮和一个
    SCNView
    放入视图控制器的视图中。在场景中,我添加了一个具有运动学物理体的地面节点和一个具有动力学物理体的长方体节点。然后,我将其设置为当点击按钮时,文本字段中输入的命令将运行。我是这样解析命令的:

    func executeCommand(_ command: String) {
        let parts = command.components(separatedBy: " ")
        let node: SCNNode
        guard let nodeString = parts.first else { return }
        switch nodeString {
        case "box": node = box
        case "ground": node = ground
        default: return
        }
        guard let selector = parts.dropFirst().first else { return }
        switch selector {
        case "applyTorque":
            if parts.count == 6 {
                let x = Double(parts[2])!
                let y = Double(parts[3])!
                let z = Double(parts[4])!
                let w = Double(parts[5])!
                let direction = SCNVector4(x, y, z, w)
                node.physicsBody?.applyTorque(direction, asImpulse: true)
            }
        // I decided to add other commands as well, but they're irrelevant so I left them out
        default: break
        }
    }
    
    现在,我尝试输入类似于
    box applyTorque 1 0 1
    的命令,并看到了发生的情况。以下是我的发现:

    • 前三个值分别表示节点应绕x、y和z轴旋转的程度
    • 最后一个值似乎类似于“整体力”。如果我将其设置为0,则无论其他值是什么,框都不会移动
    • 围绕y轴旋转似乎“更容易”。Y值为1可以将立方体“旋转”90度,但X值为1只能将长方体从一侧稍微向上提升一点
    以下是一个屏幕截图:


    IIRC您应该只需要三个坐标来唯一指定旋转(假设旋转轴包括原点)-例如,两个角度来指定旋转轴,一个角度来指定旋转角度。更多信息请参见。@OliverCharlesworth如果我真的很努力的话,我可以用两个角度来表示旋转轴。我想现在的问题变成了“节点上的‘原点’在哪里”和“如何用3个标量表示2个角度”…好吧,首先,你只需要两个标量来指定两个角度:)原点的选择取决于你-基本上是你如何选择坐标系的模型。您可以先应用平移,然后应用旋转,然后应用相反的平移来表示围绕模型以外的对象的旋转。@OliverCharlesworth如果我正在编写自己的游戏引擎,那么我想我可以指定自己的原点。。。但是我使用的是SceneKit,所以我必须坚持使用它的API。不知何故,
    applyTorque
    方法采用了
    scinvector4
    。这就是我试图理解的。唉,我对SceneKit一无所知:/我的评论实际上只是为了解决“需要7个值”的问题。我仍然不太理解axis位。如果我想使用立方体节点的对角线作为轴,我应该为前三个值设置什么?任何节点的原点都是根节点的原点?我是否正确理解了这一部分?为了回答第一个问题,前三个值是旋转轴的标准化XYZ分量(或“方向”,如果您愿意),因此第四个分量表示时钟