这可能更像是一个线性代数问题,但是说我有一个scnvector,我想要一个与y轴围绕y轴的原始角度(或任何轴的任何轴)的新scnvector事情)。理想情况下:
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)
谢谢!
尝试使用quaternions https://developer.apple.com/documentation/accelerate/working_with_quaternions
extension SCNVector3 {
enum Axis {
case x, y, z
func getAxisVector() -> simd_float3 {
switch self {
case .x:
return simd_float3(1,0,0)
case .y:
return simd_float3(0,1,0)
case .z:
return simd_float3(0,0,1)
}
}
}
func rotatedVector(aroundAxis: Axis, angle: Float) -> SCNVector3 {
/// create quaternion with angle in radians and your axis
let q = simd_quatf(angle: angle, axis: aroundAxis.getAxisVector())
/// use ACT method of quaternion
let simdVector = q.act(simd_float3(self))
return SCNVector3(simdVector)
}
}
使用:
let a = SCNVector3(5,0,0)
let b = a.rotatedVector(aroundAxis: SCNVector3.Axis.y, angle: -.pi/2)
// SCNVector3(x: 0.0, y: 0.0, z: 5.0)
您也可以围绕任何向量旋转:
let simdVector = q.act(simd_normalize(simd_float3(x: 0.75, y: 0.75, z: -0.2)))
在通常的情况下,使用rodrigues的旋转公式。
Rodrigues的旋转公式是用于旋转A的有效算法 在空间中的向量,给定轴和旋转角
对于初始矢量 v ,旋转轴单元向量 k 和角度theta结果是
v rot = v * cos(theta) ( k X v * sin(theta) k *( k .dot。p>
,感谢对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)
}
}
}