はじめに
ちょっと前に書いた記事で四元数の乗算を用いて三次元空間における回転変換を表現できることを示しました。
この記事ではそれを受ける形で、四元数の演算を行うScalaのオブジェクト及びコンパニオンクラスを実装していきます。
実装の方針。
実装のやり方についてもかなり前の記事で書いた複素数のオブジェクト及びコンパニオンクラスに準ずることにします。
実装例。
実装例は以下のような感じになります。割と長いです。
package info.pandanote.test | |
import scala.reflect.ClassTag | |
import scala.math._ | |
// A class to represent and to handle a quaternion. | |
// 四元数を扱うためのクラスを書いてみました。 | |
case class Quaternion(real: Double, _i: Double, _j: Double, _k: Double) { | |
override def toString(): String = real + (if (_i == 0.0) "" else ((if (_i>0.0)"+"else"-")+(if (_i>0.0)_i else -_i) + "i")) + (if (_j == 0.0) "" else ((if (_j>0.0)"+"else"-")+(if (_j>0.0)_j else -_j) + "j")) + (if (_k == 0.0) "" else ((if (_k>0.0)"+"else"-")+(if (_k>0.0)_k else -_k) + "k")) | |
def re() = real | |
def i() = _i | |
def j() = _j | |
def k() = _k | |
def +(that: Quaternion) = Quaternion(this.real+that.real,this._i+that._i,this._j+that._j,this._k+that._k) | |
def +(that: Int) = Quaternion(this.real+that,this._i,this._j,this._k) | |
def +(that: Long) = Quaternion(this.real+that,this._i,this._j,this._k) | |
def +(that: Float) = Quaternion(this.real+that,this._i,this._j,this._k) | |
def +(that: Double) = Quaternion(this.real+that,this._i,this._j,this._k) | |
def -(that: Quaternion) = Quaternion(this.real-that.real,this._i-that._i,this._j-that._j,this._k-that._k) | |
def -(that: Int) = Quaternion(this.real-that,this._i,this._j,this._k) | |
def -(that: Long) = Quaternion(this.real-that,this._i,this._j,this._k) | |
def -(that: Float) = Quaternion(this.real-that,this._i,this._j,this._k) | |
def -(that: Double) = Quaternion(this.real-that,this._i,this._j,this._k) | |
def *(that: Quaternion) | |
= Quaternion(this.real*that.real-this._i*that._i-this._j*that._j-this._k*that._k, | |
this.real*that._i+this._i*that.real+this._j*that._k-this._k*that._j, | |
this.real*that._j-this._i*that._k+this._j*that.real+this._k*that._i, | |
this.real*that._k+this._i*that._j-this._j*that._i+this._k*that.real) | |
def *(that: Int) = Quaternion(this.real*that,this._i*that,this._j*that,this._k*that) | |
def *(that: Long) = Quaternion(this.real*that,this._i*that,this._j*that,this._k*that) | |
def *(that: Float) = Quaternion(this.real*that,this._i*that,this._j*that,this._k*that) | |
def *(that: Double) = Quaternion(this.real*that,this._i*that,this._j*that,this._k*that) | |
def unary_- = Quaternion(-this.real,-this._i,-this._j,-this._k) | |
def abs = math.sqrt(this.real*this.real+this._i*this._i+this._j*this._j+this._k*this._k) | |
def conjugate = Quaternion(this.real,-this._i,-this._j,-this._k) | |
// 除算: 四元数を除数とする除算は、逆数を右からかける演算として定義します。 | |
def /(that: Int) = Quaternion(this.real/that,this._i/that,this._j/that,this._k/that) | |
def /(that: Long) = Quaternion(this.real/that,this._i/that,this._j/that,this._k/that) | |
def /(that: Float) = Quaternion(this.real/that,this._i/that,this._j/that,this._k/that) | |
def /(that: Double) = Quaternion(this.real/that,this._i/that,this._j/that,this._k/that) | |
def /(that: Quaternion) = { | |
val xnorm = that.real*that.real+that._i*that._i+that._j*that._j+that._k*that._k | |
val q = this*that.conjugate | |
Quaternion(q.real/xnorm,q._i/xnorm,q._j/xnorm,q._k/xnorm) | |
} | |
// 四元数の剰余計算というものが定義されているのかどうかわかりませんが、書いてみました。 | |
// 複素数と同様の考え方で定義しています。 | |
def %(that: Quaternion) = { | |
val div = this./(that) | |
this - Quaternion(Math.round(div.real),Math.round(div.i),Math.round(div.j),Math.round(div.k))*that | |
} | |
def %(that: Int): Quaternion = this.%(Quaternion(that, 0, 0, 0)) | |
def %(that: Long): Quaternion = %(Quaternion(that, 0, 0, 0)) | |
def %(that: Float): Quaternion = %(Quaternion(that, 0, 0, 0)) | |
def %(that: Double): Quaternion = %(Quaternion(that, 0, 0, 0)) | |
def exp = { | |
val expreal = math.exp(real) | |
val vlen = math.sqrt(_i*_i+_j*_j+_k*_k) | |
Quaternion(math.cos(vlen),math.sin(vlen)*_i/vlen,math.sin(vlen)*_j/vlen,math.sin(vlen)*_k/vlen)*expreal | |
} | |
def log = { | |
val logimag = math.acos(real/abs)/math.sqrt(_i*_i+_j*_j+_k*_k) | |
Quaternion(math.log(abs),_i*logimag,_j*logimag,_k*logimag) | |
} | |
def pow(that: Int): Quaternion = pow(Quaternion(that,0,0,0)) | |
def pow(that: Double): Quaternion = pow(Quaternion(that,0,0,0)) | |
def pow(that: Quaternion): Quaternion = { | |
if (that == Quaternion.zero) Quaternion.one | |
else if (this == Quaternion.zero) { | |
// 実数成分は正である場合に限り0を返す。 | |
if (that.real < 0.0 || that._i != 0.0 || that._j != 0.0 || that._k != 0.0) Quaternion.nan | |
else Quaternion.zero | |
} else { | |
Quaternion.exp(log*that) | |
} | |
} | |
// こんなのも定義してみます。 | |
def **(that: Quaternion): Quaternion = pow(that) | |
def **(that: Double): Quaternion = pow(that) | |
def **(that: Int): Quaternion = pow(that) | |
override def equals(that: Any) = that match { | |
case that: Quaternion => this.real == that.real && this._i == that._i && this._j == that._j && this._k == that._k | |
case real: Double => this.real == real && this._i == 0 && this._j == 0 && this._k == 0 | |
case real: Int => this.real == real && this._i == 0 && this._j == 0 && this._k == 0 | |
case real: Short => this.real == real && this._i == 0 && this._j == 0 && this._k == 0 | |
case real: Long => this.real == real && this._i == 0 && this._j == 0 && this._k == 0 | |
case real: Float => this.real == real && this._i == 0 && this._j == 0 && this._k == 0 | |
case _ => false | |
} | |
// 試しにこんな演算子を定義してみます。 | |
def <>(that: Quaternion) = | |
(this.real != that.real || this._i != that._i || this._j != that._j || this._k != that._k) | |
override def hashCode() = real.## ^ _i.## ^ _j.## ^ _k.## | |
} | |
object Quaternion { | |
outer => | |
val one = new Quaternion(1,0,0,0) | |
val zero = new Quaternion(0,0,0,0) | |
val nan = new Quaternion(Double.NaN,Double.NaN,Double.NaN,Double.NaN) | |
// Javaでいうところのstaticなメソッドみたいなものです。 | |
def exp(that: Quaternion): Quaternion = that.exp | |
def log(that: Quaternion): Quaternion = that.log | |
// 実数に四元数を作用させる演算が定義されていなかったので、追加しました。 | |
// 試行錯誤の末、以下の一行になりました… | |
implicit def fromDouble(d: Double) = new Quaternion(d,0,0,0) | |
} |
考慮が必要と思われる点(その1): 除算
四元数
なお、四元数の集合
考慮が必要と思われる点(その2): 剰余
四元数の剰余というものが定義できるかどうかわかりませんが、複素数の場合と同様に以下の手順で計算し、その結果得られた数を剰余とするコードを実装しています。
- 剰余演算子の左辺の四元数(
と置きます。)を被除数、剰余演算子の右辺の四元数( と置きます。)を除数とする除算を実行し、その商を得ます。以下、商の値を と置きます。 の実部及び虚部( )成分をそれぞれ四捨五入した値を求め、これを とします。- 以下の式により計算される値
を剰余とします。除算を と定義しているため、 に対して を左からかけています。
(2)
考慮が必要と思われる点(その3): 四元数のべき乗
テスト。
とりあえず、Eclipseで実行できるようにmainメソッド入りのテスト用オブジェクト(QuaternionTestオブジェクト)を書いてみました。以下のような感じになります。
package info.pandanote.test | |
import Quaternion._ | |
object QuaternionTest { | |
def main(args: Array[String]): Unit = { | |
val a = Quaternion(-2,4,-3,3) | |
val b = Quaternion(-3,3,5,0) | |
val c = Quaternion(5,0,9,-4) | |
val d = Quaternion(9,-4,4,-1) | |
val e = Quaternion(4,-1,-2,4) | |
val f = -3.000428692900978 | |
val g = 10 | |
val aa = Quaternion(2,1,3,-3) | |
val ab = Quaternion(3,-3,4,5) | |
val ac = Quaternion(4,5,2,1) | |
val ad = Quaternion.one | |
// toString() | |
println("--- toString() ---") | |
println("a="+a.toString) | |
println("b="+b.toString) | |
println("c="+c.toString) | |
println("d="+d.toString) | |
println("e="+e.toString) | |
println("aa="+aa.toString) | |
println("ab="+ab.toString) | |
println("ac="+ac.toString) | |
println("ad="+ad.toString) | |
println(Quaternion.one) | |
println(Quaternion.zero) | |
// re() | |
println("--- re() ---") | |
println("Re(a) = "+a.re.toString) | |
println("Re(b) = "+b.re.toString) | |
println("Re(c) = "+c.re.toString) | |
println("Re(d) = "+d.re.toString) | |
println("Re(e) = "+e.re.toString) | |
println("Re(aa) = "+aa.re.toString) | |
println("Re(ab) = "+ab.re.toString) | |
println("Re(ac) = "+ac.re.toString) | |
println("Re(ad) = "+ad.re.toString) | |
println("Re(Quaternion.one) = "+Quaternion.one.re.toString) | |
// i() | |
println("--- i() ---") | |
println("a.i = "+a.i.toString) | |
println("b.i = "+b.i.toString) | |
println("c.i = "+c.i.toString) | |
println("d.i = "+d.i.toString) | |
println("e.i = "+e.i.toString) | |
println("aa.i = "+aa.i.toString) | |
println("ab.i = "+ab.i.toString) | |
println("ac.i = "+ac.i.toString) | |
println("ad.i = "+ad.i.toString) | |
// j() | |
println("--- j() ---") | |
println("a.j = "+a.j.toString) | |
println("b.j = "+b.j.toString) | |
println("c.j = "+c.j.toString) | |
println("d.j = "+d.j.toString) | |
println("e.j = "+e.j.toString) | |
println("aa.j = "+aa.j.toString) | |
println("ab.j = "+ab.j.toString) | |
println("ac.j = "+ac.j.toString) | |
println("ad.j = "+ad.j.toString) | |
// k() | |
println("--- k() ---") | |
println("a.k = "+a.k.toString) | |
println("b.k = "+b.k.toString) | |
println("c.k = "+c.k.toString) | |
println("d.k = "+d.k.toString) | |
println("e.k = "+e.k.toString) | |
println("aa.k = "+aa.k.toString) | |
println("ab.k = "+ab.k.toString) | |
println("ac.k = "+ac.k.toString) | |
println("ad.k = "+ad.k.toString) | |
// +(that: Quaternion) | |
println("--- +(that: Quaternion) ---") | |
println("a + b = "+(a + b).toString) | |
println("b + c = "+(b + c).toString) | |
println("c + d = "+(c + d).toString) | |
println("d + e = "+(d + e).toString) | |
println("aa + 1 = "+(aa+Quaternion.one).toString) | |
// +(that: Int) | |
println("--- +(that: Int) ---") | |
println("a + 2 = "+(a + 2).toString) | |
println("b + 3 = "+(b + 3).toString) | |
println("c + 4 = "+(c + 4).toString) | |
println("d + 5 = "+(d + 5).toString) | |
println("e + 6 = "+(d + 6).toString) | |
// +(that: Long) | |
println("--- +(that: Long) ---") | |
println("a + 2L = "+(a + 2L).toString) | |
println("b + 4L = "+(b + 4L).toString) | |
println("c + 8L = "+(c + 8L).toString) | |
println("d + 16L = "+(d + 16L).toString) | |
println("e + 32L = "+(e + 32L).toString) | |
// +(that: Float) | |
println("--- +(that: Float) ---") | |
println("a + 0.1f = "+(a + 0.1f).toString) | |
println("b + 0.2f = "+(b + 0.2f).toString) | |
println("c + 0.3f = "+(c + 0.3f).toString) | |
println("d + 0.4f = "+(d + 0.4f).toString) | |
println("e + 0.5f = "+(e + 0.5f).toString) | |
// +(that: Double) | |
println("--- +(that: Double) ---") | |
println("a + 0.3 = "+(a + 0.3).toString) | |
println("b + 0.6 = "+(b + 0.6).toString) | |
println("c + 0.9 = "+(c + 0.9).toString) | |
println("d + 1.2 = "+(d + 1.2).toString) | |
println("e + 1.5 = "+(e + 1.5).toString) | |
// -(that: Quaternion) | |
println("--- -(that: Quaternion) ---") | |
println("a - b = "+(a - b).toString) | |
println("b - c = "+(b - c).toString) | |
println("c - d = "+(c - d).toString) | |
println("d - e = "+(d - e).toString) | |
println("aa - ab = "+(aa - ab).toString) | |
// -(that: Int) | |
println("--- -(that: Int) ---") | |
println("a - 2 = "+(a - 2).toString) | |
println("b - 3 = "+(b - 3).toString) | |
println("c - 4 = "+(c - 4).toString) | |
println("d - 5 = "+(d - 5).toString) | |
println("e - 6 = "+(e - 6).toString) | |
// -(that: Long) | |
println("--- -(that: Long) ---") | |
println("a - 1L = "+(a - 1L).toString) | |
println("b - 2L = "+(b - 2L).toString) | |
println("c - 4L = "+(c - 4L).toString) | |
println("d - 8L = "+(d - 8L).toString) | |
println("e - 16L = "+(e - 16L).toString) | |
// -(that: Float) | |
println("--- -(that: Float) ---") | |
println("a - 0.1f = "+(a - 0.1f).toString) | |
println("b - 0.2f = "+(b - 0.2f).toString) | |
println("c - 0.3f = "+(c - 0.3f).toString) | |
println("d - 0.4f = "+(d - 0.4f).toString) | |
println("e - 0.5f = "+(e - 0.5f).toString) | |
// -(that: Double) | |
println("--- -(that: Double) ---") | |
println("a - 0.3 = "+(a - 0.3).toString) | |
println("b - 0.6 = "+(b - 0.6).toString) | |
println("c - 0.9 = "+(c - 0.9).toString) | |
println("d - 1.2 = "+(d - 1.2).toString) | |
println("e - 1.5 = "+(e - 1.5).toString) | |
// *(that: Quaternion) | |
println("--- *(that: Quaternion) ---") | |
println("a * b = "+(a * b).toString) | |
println("b * c = "+(b * c).toString) | |
println("c * d = "+(c * d).toString) | |
println("d * e = "+(d * e).toString) | |
println("aa * ac = "+(aa*ac).toString) | |
// *(that: Int) | |
println("--- *(that: Int) ---") | |
println("a * 2 = "+(a * 2).toString) | |
println("b * 3 = "+(b * 3).toString) | |
println("c * 4 = "+(c * 4).toString) | |
println("d * 5 = "+(d * 5).toString) | |
println("e * 6 = "+(e * 6).toString) | |
// *(that: Long) | |
println("--- *(that: Long) ---") | |
println("a * 7L = "+(a * 7L).toString) | |
println("b * 8L = "+(b * 8L).toString) | |
println("c * 9L = "+(c * 9L).toString) | |
println("d * 10L = "+(d * 10L).toString) | |
println("e * 11L = "+(e * 11L).toString) | |
// *(that: Float) | |
println("--- *(that: Float) ---") | |
println("a * 0.2f = "+(a * 0.2f).toString) | |
println("b * 0.3f = "+(b * 0.3f).toString) | |
println("c * 0.4f = "+(c * 0.4f).toString) | |
println("d * 0.5f = "+(d * 0.5f).toString) | |
println("e * 0.6f = "+(e * 0.6f).toString) | |
// *(that: Double) | |
println("--- *(that: Double) ---") | |
println("a * 0.2 = "+(a * 0.2).toString) | |
println("b * 0.3 = "+(b * 0.3).toString) | |
println("c * 0.4 = "+(c * 0.4).toString) | |
println("d * 0.5 = "+(d * 0.5).toString) | |
println("e * 0.6 = "+(e * 0.6).toString) | |
// /(that: Quaternion) | |
println("--- /(that: Quaternion) ---") | |
println("a / b = "+(a / b).toString) | |
println("b / c = "+(b / c).toString) | |
println("c / d = "+(c / d).toString) | |
println("d / e = "+(d / e).toString) | |
println("aa / ab = "+(aa/ab).toString) | |
// /(that: Int) | |
println("--- /(that: Int) ---") | |
println("a / 2 = "+(a / 2).toString) | |
println("b / 3 = "+(b / 3).toString) | |
println("c / 4 = "+(c / 4).toString) | |
println("d / 5 = "+(d / 5).toString) | |
println("e / 6 = "+(e / 6).toString) | |
println("ab / 4 = "+(ab / 4).toString) | |
// /(that: Long) | |
println("--- /(that: Long) ---") | |
println("a / 6L = "+(a / 6L).toString) | |
println("b / 5L = "+(b / 5L).toString) | |
println("c / 4L = "+(c / 4L).toString) | |
println("d / 3L = "+(d / 3L).toString) | |
println("e / 2L = "+(e / 2L).toString) | |
// /(that: Float) | |
println("--- /(that: Float) ---") | |
println("a / 0.5f = "+(a / 0.5f).toString) | |
println("b / 0.6f = "+(b / 0.6f).toString) | |
println("c / 0.7f = "+(c / 0.7f).toString) | |
println("d / 0.8f = "+(d / 0.8f).toString) | |
println("e / 0.9f = "+(e / 0.9f).toString) | |
// /(that: Double) | |
println("--- /(that: Double) ---") | |
println("a / 1.1 = "+(a / 1.1).toString) | |
println("b / 1.2 = "+(b / 1.2).toString) | |
println("c / 1.3 = "+(c / 1.3).toString) | |
println("d / 1.4 = "+(d / 1.4).toString) | |
println("e / 1.5 = "+(e / 1.5).toString) | |
// %(that: Quaternion) | |
println("--- %(that: Quaternion) ---") | |
println("a % b = "+(a % b).toString) | |
println("b % c = "+(b % c).toString) | |
println("c % d = "+(c % d).toString) | |
println("d % e = "+(d % e).toString) | |
// %(that: Int) | |
println("--- %(that: Int) ---") | |
println("a % 5 = "+(a % 5).toString) | |
println("b % 6 = "+(b % 6).toString) | |
println("c % 7 = "+(c % 7).toString) | |
println("d % 8 = "+(d % 8).toString) | |
println("ab % 4 = "+(ab % 4).toString) | |
// %(that: Long) | |
println("--- %(that: Long) ---") | |
println("a % 5L = "+(a % 5L).toString) | |
println("b % 6L = "+(b % 6L).toString) | |
println("c % 7L = "+(c % 7L).toString) | |
println("d % 8L = "+(d % 8L).toString) | |
println("e % 4L = "+(e % 9L).toString) | |
// %(that: Float) | |
println("--- %(that: Float) ---") | |
println("a % 1.5f = "+(a % 1.5f).toString) | |
println("b % 2.0f = "+(b % 2.0f).toString) | |
println("c % 2.5f = "+(c % 2.5f).toString) | |
println("d % 3.0f = "+(d % 3.0f).toString) | |
println("e % 4.0f = "+(e % 4.0f).toString) | |
// %(that: Double) | |
println("--- %(that: Double) ---") | |
println("a % 1.5 = "+(a % 1.5).toString) | |
println("b % 2.0 = "+(b % 2.0).toString) | |
println("c % 2.5 = "+(c % 2.5).toString) | |
println("d % 3.0 = "+(d % 3.0).toString) | |
println("e % 4.0 = "+(d % 4.0).toString) | |
// unary_- = Quaternion(-real,-imag,this.imagUnit) | |
println("--- unary_- ---") | |
println("-a = "+(-a).toString) | |
println("-b = "+(-b).toString) | |
println("-c = "+(-c).toString) | |
println("-d = "+(-d).toString) | |
println("-e = "+(-e).toString) | |
// abs = math.sqrt(real*real+imag*imag) | |
println("--- abs ---") | |
println("a.abs = "+a.abs.toString) | |
println("b.abs = "+b.abs.toString) | |
println("c.abs = "+c.abs.toString) | |
println("d.abs = "+d.abs.toString) | |
println("e.abs = "+e.abs.toString) | |
// conjugate = Quaternion(real,-imag,this.imagUnit) | |
println("--- conjugate ---") | |
println("a.conjugate = "+a.conjugate.toString) | |
println("b.conjugate = "+b.conjugate.toString) | |
println("c.conjugate = "+c.conjugate.toString) | |
println("d.conjugate = "+d.conjugate.toString) | |
println("e.conjugate = "+e.conjugate.toString) | |
println("aa.conjugate*(ac-Quaternion.one*7) = "+(aa.conjugate*(ac-Quaternion.one*7)).toString) | |
// log = Quaternion(math.log(abs)) | |
println("--- log ---") | |
println("a.log = "+a.log.toString) | |
println("b.log = "+b.log.toString) | |
println("c.log = "+c.log.toString) | |
println("d.log = "+d.log.toString) | |
println("e.log = "+e.log.toString) | |
// exp = { | |
println("--- exp ---") | |
println("a.exp = "+a.exp.toString) | |
println("b.exp = "+b.exp.toString) | |
println("c.exp = "+c.exp.toString) | |
println("d.exp = "+d.exp.toString) | |
println("e.exp = "+e.exp.toString) | |
println("aa.exp = "+aa.exp.toString) | |
println("aa.exp.log = "+aa.exp.log.toString) | |
println("aa.exp.log != aa: "+(aa.exp.log == aa)) | |
// pow(that: Double) | |
println("--- pow(that: Double) ---") | |
println("a pow 0.2 = "+(a pow 0.2).toString) | |
println("b pow 0.4 = "+(b pow 0.4).toString) | |
println("c pow 0.6 = "+(c pow 0.6).toString) | |
println("d pow 0.8 = "+(d pow 0.8).toString) | |
println("e pow 1.1 = "+(e pow 1.1).toString) | |
println("a.pow(0.2) = "+a.pow(0.2).toString) | |
println("b.pow(0.4) = "+b.pow(0.4).toString) | |
println("c.pow(0.6) = "+c.pow(0.6).toString) | |
println("d.pow(0.8) = "+d.pow(0.8).toString) | |
println("e.pow(1.1) = "+e.pow(1.1).toString) | |
// pow(that: Int) | |
println("--- pow(that: Int) ---") | |
println("aa.pow(3) = "+aa.pow(3).toString) | |
// pow(that: Quaternion) | |
println("--- pow(that: Quaternion) ---") | |
println("a pow b = "+(a pow b).toString) | |
println("b pow c = "+(b pow c).toString) | |
println("c pow d = "+(c pow d).toString) | |
println("d pow e = "+(d pow e).toString) | |
println("e pow a = "+(e pow a).toString) | |
println("a.pow(b) = "+a.pow(b).toString) | |
println("b.pow(c) = "+b.pow(c).toString) | |
println("c.pow(d) = "+c.pow(d).toString) | |
println("d.pow(e) = "+d.pow(e).toString) | |
println("e.pow(a) = "+e.pow(a).toString) | |
println("aa.pow(aa) = "+aa.pow(aa).toString) | |
// **(that: Quaternion) | |
println("--- **(that: Quaternion) ---") | |
println("a ** b = "+(a ** b).toString) | |
println("b ** c = "+(b ** c).toString) | |
println("c ** d = "+(c ** d).toString) | |
println("d ** e = "+(d ** e).toString) | |
println("e ** a = "+(d ** e).toString) | |
println("aa ** ab = "+(aa**ab).toString) | |
// **(that: Double) | |
println("--- **(that: Double) ---") | |
println("a ** 0.2 = "+(a ** 0.2).toString) | |
println("b ** 0.4 = "+(b ** 0.4).toString) | |
println("c ** 0.6 = "+(c ** 0.6).toString) | |
println("d ** 0.8 = "+(d ** 0.8).toString) | |
println("e ** 1.1 = "+(e ** 1.1).toString) | |
// **(that: Int) | |
println("--- **(that: Int) ---") | |
println("aa ** 2 = "+(aa ** 2).toString) | |
// equals(that: Any) | |
println("--- equals(that: Any) ---") | |
println("a equals b: "+(a equals b).toString) | |
println("b equals c: "+(b equals c).toString) | |
println("c equals d: "+(c equals d).toString) | |
println("d equals e: "+(d equals e).toString) | |
println("e equals a: "+(e equals a).toString) | |
println("a equals a: "+(a equals a).toString) | |
println("b equals b: "+(b equals b).toString) | |
println("c equals c: "+(c equals c).toString) | |
println("d equals d: "+(d equals d).toString) | |
println("e equals e: "+(e equals e).toString) | |
println("ad == 1: "+(ad == 1).toString) | |
println("ad.equals(1): "+ad.equals(1)) | |
println("aa != aa: "+(aa!=aa)) | |
// <>(that: Quaternion) | |
println("--- <>(that: Quaternion) ---") | |
println("a <> b: "+(a <> b).toString) | |
println("b <> c: "+(b <> c).toString) | |
println("c <> d: "+(c <> d).toString) | |
println("d <> e: "+(d <> e).toString) | |
println("aa <> aa: "+(aa<>aa).toString) | |
// exp(that: Quaternion) | |
println("--- Quaternion.exp(that: Quaternion)---") | |
println("Quaternion.exp(a) = "+Quaternion.exp(a).toString) | |
println("Quaternion.exp(b) = "+Quaternion.exp(b).toString) | |
println("Quaternion.exp(c) = "+Quaternion.exp(c).toString) | |
println("Quaternion.exp(d) = "+Quaternion.exp(d).toString) | |
println("Quaternion.exp(e) = "+Quaternion.exp(e).toString) | |
println("Quaternion.exp(aa) = "+Quaternion.exp(aa).toString) | |
// log(that: Quaternion) | |
println("--- Quaternion.log(that: Quaternion)---") | |
println("Quaternion.log(a) = "+Quaternion.log(a).toString) | |
println("Quaternion.log(b) = "+Quaternion.log(b).toString) | |
println("Quaternion.log(c) = "+Quaternion.log(c).toString) | |
println("Quaternion.log(d) = "+Quaternion.log(d).toString) | |
println("Quaternion.log(e) = "+Quaternion.log(e).toString) | |
// Imaginary Unit and others. | |
println("--- Imaginary Unit and others. ---") | |
val aj = new Quaternion(2,-5,-1,6) | |
println("aj = "+aj) | |
println("aj * aa = "+(aj*aa).toString) | |
println("aa * aj = "+(aa*aj).toString) | |
println("aj.pow(0) = "+aj.pow(0)) | |
println("aj.pow(2) = "+aj.pow(2)) | |
println("aj * aj = "+(aj*aj)) | |
println("aj.pow(2).log = "+aj.pow(2).log) | |
println("aj.pow(2).pow(0.5) = "+aj.pow(2).pow(0.5)) | |
// -- Doubleクラスにメソッドを追加してみた。-- | |
println("Append some methods to handle Quaternion") | |
println("g*a = "+(g*a).toString) | |
println("g/a = "+(g/a).toString) | |
println("g+a = "+(g+a).toString) | |
val g1: Double = 1 | |
val g2: Double = 1 | |
println("g1 equals g2: "+(g1 equals g2).toString) | |
} | |
} |
テスト結果は長くなりますので掲載しないことにしますが、結果を確認した感じでは問題なさそうな感じに見えます。
まとめ
ここまで、Scalaで四元数を扱うためのオブジェクト及びクラスの実装について書きました。
前項で示したテスト用のプログラムもScalaTestで使用できるように書くべきところかもしれませんが、今回はここで力尽きてしまったので、別の機会に書きたいと考えています。
(´・ω・`)
この記事は以上です。