Created
December 12, 2018 03:13
-
-
Save killjoy1221/02c3f1b83b0e6afad731cce616f3f97e 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
import kotlin.math.pow | |
import kotlin.math.sqrt | |
import kotlin.reflect.full.primaryConstructor | |
interface Maths<Num : Number> { | |
fun plus(a: Num, b: Num): Num | |
fun minus(a: Num, b: Num): Num | |
fun times(a: Num, b: Num): Num | |
fun div(a: Num, b: Num): Num | |
fun pow(a: Num, b: Num): Num | |
fun abs(a: Num): Num | |
fun toType(a: Number): Num | |
} | |
object IntMaths : Maths<Int> { | |
override fun plus(a: Int, b: Int) = a + b | |
override fun minus(a: Int, b: Int) = a - b | |
override fun times(a: Int, b: Int) = a * b | |
override fun div(a: Int, b: Int) = a / b | |
override fun pow(a: Int, b: Int) = a.toDouble().pow(b).toInt() | |
override fun abs(a: Int) = kotlin.math.abs(a) | |
override fun toType(a: Number) = a.toInt() | |
} | |
object DoubleMaths : Maths<Double> { | |
override fun plus(a: Double, b: Double) = a + b | |
override fun minus(a: Double, b: Double) = a - b | |
override fun times(a: Double, b: Double) = a * b | |
override fun div(a: Double, b: Double) = a / b | |
override fun pow(a: Double, b: Double) = a.pow(b) | |
override fun abs(a: Double) = kotlin.math.abs(a) | |
override fun toType(a: Number) = a.toDouble() | |
} | |
data class Vec2i(override val x: Int, override val y: Int) : Vec2<Int>(IntMaths) | |
data class Vec2d(override val x: Double, override val y: Double) : Vec2<Double>(DoubleMaths) | |
sealed class Vec2<N : Number>(private val maths: Maths<N>) { | |
abstract val x: N | |
abstract val y: N | |
fun plus(x: N, y: N = x) = new(this.x + x, this.y + y) | |
fun minus(x: N, y: N = x) = new(this.x - x, this.y - y) | |
fun times(x: N, y: N = x) = new(this.x * x, this.y * y) | |
fun div(x: N, y: N = x) = new(this.x / x, this.y / y) | |
fun length(x: N, y: N) = maths.abs(y - this.y) + maths.abs(x - this.x) | |
fun distSq(x: N, y: N) = (this.x - x).pow(!2) + (this.y - y).pow(!2) | |
fun dist(x: N, y: N) = sqrt(distSq(x, y).toDouble()) | |
fun length(other: Vec2<N>) = length(other.x, other.y) | |
fun distSq(other: Vec2<N>) = distSq(other.x, other.y) | |
fun dist(other: Vec2<N>) = dist(other.x, other.y) | |
operator fun plus(other: Vec2<N>) = plus(other.x, other.y) | |
operator fun minus(other: Vec2<N>) = minus(other.x, other.y) | |
operator fun times(other: Vec2<N>) = times(other.x, other.y) | |
operator fun div(other: Vec2<N>) = div(other.x, other.y) | |
operator fun unaryMinus() = times(!-1) | |
operator fun unaryPlus() = this | |
fun toVec2i() = this as? Vec2i ?: Vec2i(x.toInt(), y.toInt()) | |
fun toVec2d() = this as? Vec2d ?: Vec2d(x.toDouble(), y.toDouble()) | |
private fun new(x: Number, y: Number) = this::class.primaryConstructor!!.call(!x, !y) | |
private operator fun N.plus(a: N) = maths.plus(this, a) | |
private operator fun N.minus(a: N) = maths.minus(this, a) | |
private operator fun N.times(a: N) = maths.times(this, a) | |
private operator fun N.div(a: N) = maths.div(this, a) | |
private operator fun Number.not(): N = maths.toType(this) | |
private fun N.pow(a: N) = maths.pow(this, a) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment