2017-08-30 117 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