Created
September 2, 2016 13:06
-
-
Save kaffepanna/948bb80ef7038a5fbda1a4171a07ccdf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package se.randomserver.math | |
class DimensionError extends Error | |
trait VecFactory[V[_]] { | |
def apply[T](s: T*)(implicit num: VecIntegral[T]): V[T] | |
} | |
abstract sealed class Vec[T, V[T] <: Vec[T, V]](val elems: T*)(implicit num: VecIntegral[T], factory: VecFactory[V]) { | |
import num._ | |
def +(v: V[T]): V[T] = factory(elems.zip(v.elems).map { case (a, b) => a + b }:_*) | |
def -(v: V[T]): V[T] = this + (-v) | |
def cross(v: V[T]): V[T] | |
def dot(v: V[T]): T = elems.zip(v.elems).map { case (a,b) => a * b }.sum | |
def unary_-(): V[T] = map(_.unary_-()) | |
def *(scalar: T): V[T] = map(_ * scalar) | |
def abs: T = sqrt(elems.map(a => a * a).sum) | |
def *(v: V[T]): V[T] = cross(v) | |
def apply(n: Int): T = elems(n) | |
def map[C](f: T => C)(implicit n: VecIntegral[C], fa: VecFactory[V]): V[C] = fa(elems.map(f):_*) | |
override def toString: String = elems.mkString("[", ", ", "]") | |
} | |
class Vec2[T](x: T, y: T)(implicit num: VecIntegral[T]) extends Vec[T, Vec2](x,y) { | |
override def cross(v: Vec2[T]): Vec2[T] = throw new DimensionError | |
} | |
object Vec2 { | |
implicit val factory: VecFactory[Vec2] = new VecFactory[Vec2] { | |
override def apply[T](s: T*)(implicit num: VecIntegral[T]): Vec2[T] = s match { | |
case Seq(x,y) => new Vec2[T](x,y) | |
case _ => throw new DimensionError | |
} | |
} | |
def apply[T](elems: T*)(implicit num: VecIntegral[T]): Vec2[T] = factory(elems:_*) | |
} | |
class Vec3[T](x: T, y: T, z: T)(implicit num: VecIntegral[T]) extends Vec[T, Vec3](x,y, z) { | |
import num._ | |
override def cross(v: Vec3[T]): Vec3[T] = v match { | |
case Vec(bx,by, bz) => new Vec3[T](y * bz - z * by, | |
z * bx - x * bz, | |
x * by - y * bx) | |
case _ => throw new DimensionError | |
} | |
} | |
object Vec3 { | |
implicit val factory: VecFactory[Vec3] = new VecFactory[Vec3] { | |
override def apply[T](s: T*)(implicit num: VecIntegral[T]): Vec3[T] = s match { | |
case Seq(x,y,z) => new Vec3[T](x,y,z) | |
case _ => throw new DimensionError | |
} | |
} | |
def apply[T](elems: T*)(implicit num: VecIntegral[T]): Vec3[T] = factory(elems:_*) | |
} | |
object Vec { | |
def unapplySeq[T, V[T] <: Vec[T, V]](v: Vec[T, V]): Option[Seq[T]] = Some(v.elems) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment