なんじゃくにっき

プログラミングの話題中心。

Scalaでベクトル

Scala勉強会第36回の内容 by @yangiYaさん
http://scala-users.org/shibuya/index.php?title=%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC36%E5%9B%9E
に触発されてScalaでベクトル(数学とか物理の方ね、Collectionじゃないほう)をちょっと書いてみた。
 
 
@kaitenn_さんのがキレイです↓
https://gist.github.com/1002428
 
 
 

/**
* 3次元ベクトルクラス
* 名前がVektorなのはscala.collection.immutable.Vectorとの混同を避けるため
*
*/

package vektor.vektor

case class Vektor3D[T](x: T, y: T, z: T = 0)(implicit num: Numeric[T]) {
import num._
import Math._

def + (that: Vektor3D[T]): Vektor3D[T] =
Vektor3D(this.x + that.x, this.y + that.y, this.z + that.z)

def - (that: Vektor3D[T]): Vektor3D[T] =
Vektor3D(this.x - that.x, this.y - that.y, this.z - that.z)

def negate(): Vektor3D[T] =
Vektor3D(-this.x, -this.y, -this.z)

def * (a: T): Vektor3D[T] =
Vektor3D(this.x * a, this.y * a, this.z * z)

def / (a: Double): Vektor3D[Double] =
Vektor3D(this.x.toDouble / a, this.y.toDouble / a, this.z.toDouble / a)

// innner product
def * (that: Vektor3D[T]): Vektor3D[T] =
Vektor3D(this.x * that.x, this.y * that.y, this.z * that.z)

// outer product
def × (that: Vektor3D[T]): Vektor3D[T] =
Vektor3D(this.y * that.z - this.z * that.y,
this.z * that.x - this.x * that.z,
this.x * that.y - this.y * that.x)

def abs: Double = Math.sqrt((x * x + y * y + z * z).toDouble)


def rotateX(theta: Double): Vektor3D[Double] = {
Vektor3D(this.x.toDouble,
cos(theta) * this.y.toDouble - sin(theta) * this.z.toDouble,
sin(theta) * this.y.toDouble + cos(theta) * this.z.toDouble)
}

def rotateY(theta: Double): Vektor3D[Double] = {
Vektor3D(cos(theta) * this.x.toDouble + sin(theta) * this.z.toDouble,
this.y.toDouble,
-sin(theta) * this.x.toDouble + cos(theta) * this.z.toDouble)
}

def rotateZ(theta: Double): Vektor3D[Double] = {
Vektor3D(cos(theta) * this.x.toDouble - sin(theta) * this.y.toDouble,
sin(theta) * this.x.toDouble + cos(theta) * this.y.toDouble,
this.z.toDouble)
}

def toInt: Vektor3D[Int] = Vektor3D(x.toInt, y.toInt, z.toInt)
def toLong: Vektor3D[Long] = Vektor3D(x.toLong, y.toLong, z.toLong)
def toFloat: Vektor3D[Float] = Vektor3D(x.toFloat, y.toFloat, z.toFloat)
def toDouble: Vektor3D[Double] = Vektor3D(x.toDouble, y.toDouble, z.toDouble)
}

 
後でベクトルの次元を可変長にしてみた
http://d.hatena.ne.jp/nanjakkun/20110602