Apple Engine

Apple, iPhone, iOS, その周辺のことについて

ARKit や SceneKit で使用している simd について - クォータニオンでの関数編 その1 -

今回はクォータニオンで使用する関数について。
線形補間関連の関数はまたいずれ。

演算子と関数について書くが、基本的にはプロパティと関数が対になっている。

 

演算子

等価演算子と四則演算が可能。

+, - に関しては値が加算、減算されるため、正規化しないとスケールがおかしくなるので注意。

let ix:Float = 0.0
let iy:Float = 0.707107
let iz:Float = 0.0
let r:Float  = 0.707107

let q = simd_quatf(ix: ix, iy: iy, iz: iz, r: r)
let q1 = simd_quatf(ix: ix, iy: iy, iz: iz, r: r)

q == q1 // true

q + q // simd_quatf(real: 1.41421, imag: float3(0.0, 1.41421, 0.0))
q - q // simd_quatf(real: 0.0, imag: float3(0.0, 0.0, 0.0))
q * q // simd_quatf(real: 0.0, imag: float3(0.0, 1.0, 0.0))
q / q // simd_quatf(real: 1.0, imag: float3(0.0, 0.0, 0.0))

simd_add(q, q) // q + q と同じ
simd_sub(q, q) // q - q と同じ
simd_mul(q, q) // q * q と同じ

 

プロパティ / 関数

q の値を以下のものに設定し各設定を見てゆく。

// 逆時計回りに90度回転させる
let q = simd_quatf(angle: .pi / 2, axis: simd_normalize(float3(0.0, 1.0, 0.0)))

 

angle / simd_angle()

角度をラジアンで返す。

q.angle // 1.570796

simd_angle(q)

 

axis / simd_axis()

正規化した軸のベクトル返す。

q.axis // float3(0.0, 1.0, 0.0)

simd_axis(q)

 

conjugate / simd_conjugate()

対偶を返し虚数部がマイナスになる。

q.conjugate
// simd_quatf(real: 0.707107, imag: float3(-0.0, -0.707107, -0.0))

simd_conjugate(q)

 

imag / simd_imag()

虚数部を返す。

q.imag // float3(0.0, 0.707107, 0.0)

simd_imag(q)

 

real / simd_real()

実数部を返す。

q.real // 0.7071068

simd_real(q)

 

inverse / simd_inverse()

逆数を返す。

q.inverse
// simd_quatf(real: 0.707107, imag: float3(-0.0, -0.707107, -0.0))

simd_inverse(q)

 

length / simd_length()

大きさを返す。
多くの場合は単位クオータニオンなので 1 となる。

q.length // 1

simd_length(q)

 

normalized / simd_normalize()

正規化した値を返す。

q.normalized
// simd_quatf(real: 0.707107, imag: float3(0.0, 0.707107, 0.0))

simd_normalize(q)

 

vector

float4 でのベクトル値を返す。

q.vector
// float4(0.0, 0.707107, 0.0, 0.707107)

 

simd_negate()

全ての値の符号反転して返す。

simd_negate(q)
// simd_quatf(real: -0.707107, imag: float3(-0.0, -0.707107, -0.0))

 

simd_dot()

内積を返す。
例では 1 を返し同じ角度となる。

let q_90 = simd_quatf(angle: 90 * .pi / 180, axis: simd_normalize(float3(0.0, 1.0, 0.0)))

let a = simd_dot(q, q_90) // 1

 

act()

ベクトルの回転はアクションとして知られているが、ベクトルを渡し2点間を補間する。

q.act(float3(1,0,0))
// float3(1.78814e-07, 0.0, -1.0)

 

今後、補間を紹介すると思われるが、クォータニオンの利点の1つとして回転座標間の補間が簡単になることがある。

 

まとめ

クォータニオンの操作についてある程度理解できたと思われる。

時間があれば他の補間も紹介したいと思う。