2017-08-30 121 views
3

这可能更像是一个线性代数问题,但是说我有一个SCNVector,并且我想要一个新的SCNVector,它与y轴(或任何轴)之间的角度与原始角度成一定角度。如此理想地:围绕一个轴旋转SCNVector3

extension SCNVector3 { 
    // assume dot, cross, length, +, - functions are available. 
    enum Axis { 
     case x, y, z 
    } 
    func rotatedVector(aroundAxis: Axis, angle: Float) -> SCNVector3 { 
     // code from smart person goes here 
    } 
} 

例如(0,0,-1).rotatedVector(aroundAxis: y, angle: pi/2) = (1,0,0)

谢谢!

回答

0

非常感谢comment on gamedev.net我想我有我需要的东西。它不适用于任意角度,但事实证明我只需要90°,所以这适用于我。以下是解决方案:

extension SCNVector3 { 
    enum Axis { case x, y, z } 
    enum Direction { case clockwise, counterClockwise } 
    func orthogonalVector(around axis: Axis, direction: Direction) -> SCNVector3 { 
     switch axis { 
     case .x: return direction == .clockwise ? SCNVector3(self.x, -self.z, self.y) : SCNVector3(self.x, self.z, -self.y) 
     case .y: return direction == .clockwise ? SCNVector3(-self.z, self.y, self.x) : SCNVector3(self.z, self.y, -self.x) 
     case .z: return direction == .clockwise ? SCNVector3(self.y, -self.x, self.z) : SCNVector3(-self.y, self.x, self.z) 
     } 
    } 
} 
1

一般情况下使用Rodrigues' rotation formula

罗德里格旋转公式被用于旋转在空间中的 矢量的高效算法,给定一个轴线和旋转

的角度对于初始向量v,旋转轴单位向量ķ和θ角的结果是

v = v * COS(THETA)+(ķ X v)* SIN(THETA)+ ķ *(ķ .DOT。 v)*(1-cos(theta))

+0

是右手还是左手单位空间? –

+1

Emm ...我总是用旋转角度theta - 右手处理 - 逆时针方向的CCW。似乎在包含矢量产品的第二个术语中,这一点很重要。但它也包含正弦函数,所以我不能说 - 手持是否影响结果 - 这取决于关于角度方向的约定。 – MBo