diff --git a/gradle.properties b/gradle.properties index 1398e06..68da322 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ kotlin.code.style=official specifyKotlinAsDependency=false projectGroup=ru.dbotthepony.kommons -projectVersion=2.14.1 +projectVersion=2.15.0 guavaDepVersion=33.0.0 gsonDepVersion=2.8.9 diff --git a/gson-linear-algebra/build.gradle.kts b/gson-linear-algebra/build.gradle.kts deleted file mode 100644 index 52b0e67..0000000 --- a/gson-linear-algebra/build.gradle.kts +++ /dev/null @@ -1,43 +0,0 @@ - -plugins { - kotlin("jvm") -} - -repositories { - mavenCentral() -} - -val gsonDepVersion: String by project -val specifyKotlinAsDependency: String by project - -dependencies { - testImplementation("org.jetbrains.kotlin:kotlin-test") - - implementation(project(":linear-algebra")) - implementation(project(":gson")) - implementation(project(":")) - - implementation("com.google.code.gson:gson:$gsonDepVersion") -} - -publishing { - publications { - create("mavenJava") { - from(components["java"]) - artifact(tasks["sourceJar"]) - artifactId = "kommons-gson-linear-algebra" - - pom { - dependencies { - if (specifyKotlinAsDependency.toBoolean()) implementation(kotlin("stdlib")) - - implementation(project(":linear-algebra")) - implementation(project(":gson")) - implementation(project(":")) - - implementation("com.google.code.gson:gson:[2.8,)") - } - } - } - } -} diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/AABBTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/AABBTypeAdapter.kt deleted file mode 100644 index 8b761d9..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/AABBTypeAdapter.kt +++ /dev/null @@ -1,39 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector2d -import ru.dbotthepony.kommons.util.AABB - -object AABBTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: AABB) { - `out`.beginArray() - `out`.value(value.mins.x) - `out`.value(value.mins.y) - `out`.value(value.maxs.x) - `out`.value(value.maxs.y) - `out`.endArray() - } - - override fun read(`in`: JsonReader): AABB { - `in`.beginArray() - val minX = `in`.nextDouble() - val minY = `in`.nextDouble() - val maxX = `in`.nextDouble() - val maxY = `in`.nextDouble() - `in`.endArray() - - val xMins = minX.coerceAtMost(maxX) - val xMaxs = maxX.coerceAtLeast(minX) - - val yMins = minY.coerceAtMost(maxY) - val yMaxs = maxX.coerceAtLeast(minY) - - return AABB( - Vector2d(xMins, yMins), - Vector2d(xMaxs, yMaxs), - ) - } -} - diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/AABBiTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/AABBiTypeAdapter.kt deleted file mode 100644 index 6f92199..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/AABBiTypeAdapter.kt +++ /dev/null @@ -1,38 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector2i -import ru.dbotthepony.kommons.util.AABBi - -object AABBiTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: AABBi) { - `out`.beginArray() - `out`.value(value.mins.x) - `out`.value(value.mins.y) - `out`.value(value.maxs.x) - `out`.value(value.maxs.y) - `out`.endArray() - } - - override fun read(`in`: JsonReader): AABBi { - `in`.beginArray() - val minX = `in`.nextInt() - val minY = `in`.nextInt() - val maxX = `in`.nextInt() - val maxY = `in`.nextInt() - `in`.endArray() - - val xMins = minX.coerceAtMost(maxX) - val xMaxs = maxX.coerceAtLeast(minX) - - val yMins = minY.coerceAtMost(maxY) - val yMaxs = maxX.coerceAtLeast(minY) - - return AABBi( - Vector2i(xMins, yMins), - Vector2i(xMaxs, yMaxs), - ) - } -} \ No newline at end of file diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2dTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2dTypeAdapter.kt deleted file mode 100644 index 79d91d6..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2dTypeAdapter.kt +++ /dev/null @@ -1,26 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector2d - -object Vector2dTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector2d) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector2d { - `in`.beginArray() - - val x = `in`.nextDouble() - val y = `in`.nextDouble() - - `in`.endArray() - - return Vector2d(x, y) - } -} diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2fTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2fTypeAdapter.kt deleted file mode 100644 index 35d16c2..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2fTypeAdapter.kt +++ /dev/null @@ -1,26 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector2f - -object Vector2fTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector2f) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector2f { - `in`.beginArray() - - val x = `in`.nextDouble().toFloat() - val y = `in`.nextDouble().toFloat() - - `in`.endArray() - - return Vector2f(x, y) - } -} \ No newline at end of file diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2iTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2iTypeAdapter.kt deleted file mode 100644 index 76c39bf..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector2iTypeAdapter.kt +++ /dev/null @@ -1,26 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector2i - -object Vector2iTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector2i) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector2i { - `in`.beginArray() - - val x = `in`.nextInt() - val y = `in`.nextInt() - - `in`.endArray() - - return Vector2i(x, y) - } -} \ No newline at end of file diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3dTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3dTypeAdapter.kt deleted file mode 100644 index 91d4b4b..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3dTypeAdapter.kt +++ /dev/null @@ -1,28 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector3d - -object Vector3dTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector3d) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.value(value.z) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector3d { - `in`.beginArray() - - val x = `in`.nextDouble() - val y = `in`.nextDouble() - val z = `in`.nextDouble() - - `in`.endArray() - - return Vector3d(x, y, z) - } -} diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3fTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3fTypeAdapter.kt deleted file mode 100644 index 6e750a2..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3fTypeAdapter.kt +++ /dev/null @@ -1,28 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector3f - -object Vector3fTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector3f) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.value(value.z) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector3f { - `in`.beginArray() - - val x = `in`.nextDouble().toFloat() - val y = `in`.nextDouble().toFloat() - val z = `in`.nextDouble().toFloat() - - `in`.endArray() - - return Vector3f(x, y, z) - } -} \ No newline at end of file diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3iTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3iTypeAdapter.kt deleted file mode 100644 index fb82323..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector3iTypeAdapter.kt +++ /dev/null @@ -1,28 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector3i - -object Vector3iTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector3i) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.value(value.z) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector3i { - `in`.beginArray() - - val x = `in`.nextInt() - val y = `in`.nextInt() - val z = `in`.nextInt() - - `in`.endArray() - - return Vector3i(x, y, z) - } -} \ No newline at end of file diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4dTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4dTypeAdapter.kt deleted file mode 100644 index 0e5d463..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4dTypeAdapter.kt +++ /dev/null @@ -1,30 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector4d - -object Vector4dTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector4d) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.value(value.z) - `out`.value(value.w) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector4d { - `in`.beginArray() - - val x = `in`.nextDouble() - val y = `in`.nextDouble() - val z = `in`.nextDouble() - val w = `in`.nextDouble() - - `in`.endArray() - - return Vector4d(x, y, z, w) - } -} \ No newline at end of file diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4fTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4fTypeAdapter.kt deleted file mode 100644 index 9a4cab1..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4fTypeAdapter.kt +++ /dev/null @@ -1,30 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector4f - -object Vector4fTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector4f) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.value(value.z) - `out`.value(value.w) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector4f { - `in`.beginArray() - - val x = `in`.nextDouble().toFloat() - val y = `in`.nextDouble().toFloat() - val z = `in`.nextDouble().toFloat() - val w = `in`.nextDouble().toFloat() - - `in`.endArray() - - return Vector4f(x, y, z, w) - } -} diff --git a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4iTypeAdapter.kt b/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4iTypeAdapter.kt deleted file mode 100644 index 4fe0931..0000000 --- a/gson-linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/gson/Vector4iTypeAdapter.kt +++ /dev/null @@ -1,30 +0,0 @@ -package ru.dbotthepony.kommons.gson - -import com.google.gson.TypeAdapter -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import ru.dbotthepony.kommons.vector.Vector4i - -object Vector4iTypeAdapter : TypeAdapter() { - override fun write(out: JsonWriter, value: Vector4i) { - `out`.beginArray() - `out`.value(value.x) - `out`.value(value.y) - `out`.value(value.z) - `out`.value(value.w) - `out`.endArray() - } - - override fun read(`in`: JsonReader): Vector4i { - `in`.beginArray() - - val x = `in`.nextInt() - val y = `in`.nextInt() - val z = `in`.nextInt() - val w = `in`.nextInt() - - `in`.endArray() - - return Vector4i(x, y, z, w) - } -} \ No newline at end of file diff --git a/linear-algebra/build.gradle.kts b/linear-algebra/build.gradle.kts deleted file mode 100644 index 0d7fcc4..0000000 --- a/linear-algebra/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ - -plugins { - kotlin("jvm") -} - -val specifyKotlinAsDependency: String by project - -repositories { - mavenCentral() -} - -dependencies { - testImplementation("org.jetbrains.kotlin:kotlin-test") - - implementation(project(":")) -} - -publishing { - publications { - create("mavenJava") { - from(components["java"]) - artifact(tasks["sourceJar"]) - artifactId = "kommons-linear-algebra" - - pom { - dependencies { - if (specifyKotlinAsDependency.toBoolean()) implementation(kotlin("stdlib")) - - implementation(project(":")) - } - } - } - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/io/VectorsIO.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/io/VectorsIO.kt deleted file mode 100644 index cf63d22..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/io/VectorsIO.kt +++ /dev/null @@ -1,65 +0,0 @@ -package ru.dbotthepony.kommons.io - -import ru.dbotthepony.kommons.util.DelegateGetter -import ru.dbotthepony.kommons.util.DelegateSetter -import ru.dbotthepony.kommons.util.ListenableDelegate -import ru.dbotthepony.kommons.vector.Vector2d -import ru.dbotthepony.kommons.vector.Vector2f -import ru.dbotthepony.kommons.vector.Vector2i -import ru.dbotthepony.kommons.vector.Vector3d -import ru.dbotthepony.kommons.vector.Vector3f -import ru.dbotthepony.kommons.vector.Vector3i -import ru.dbotthepony.kommons.vector.Vector4d -import ru.dbotthepony.kommons.vector.Vector4f -import ru.dbotthepony.kommons.vector.Vector4i -import java.io.DataInputStream -import java.io.DataOutputStream -import java.io.InputStream - -private inline fun InputStream.read2(factory: (I, I) -> T, reader: (InputStream) -> I): T { - return factory(reader(this), reader(this)) -} - -private inline fun InputStream.read3(factory: (I, I, I) -> T, reader: (InputStream) -> I): T { - return factory(reader(this), reader(this), reader(this)) -} - -private inline fun InputStream.read4(factory: (I, I, I, I) -> T, reader: (InputStream) -> I): T { - return factory(reader(this), reader(this), reader(this), reader(this)) -} - -fun InputStream.readVector2i() = read2(::Vector2i) { it.readInt() } -fun InputStream.readVector2d() = read2(::Vector2d) { it.readDouble() } -fun InputStream.readVector2f() = read2(::Vector2f) { it.readFloat() } - -fun InputStream.readVector3i() = read3(::Vector3i) { it.readInt() } -fun InputStream.readVector3d() = read3(::Vector3d) { it.readDouble() } -fun InputStream.readVector3f() = read3(::Vector3f) { it.readFloat() } - -fun InputStream.readVector4i() = read4(::Vector4i) { it.readInt() } -fun InputStream.readVector4d() = read4(::Vector4d) { it.readDouble() } -fun InputStream.readVector4f() = read4(::Vector4f) { it.readFloat() } - -val Vector2iCodec = StreamCodec.Impl(DataInputStream::readVector2i, DataOutputStream::writeStruct2i) -val Vector2dCodec = StreamCodec.Impl(DataInputStream::readVector2d, DataOutputStream::writeStruct2d) -val Vector2fCodec = StreamCodec.Impl(DataInputStream::readVector2f, DataOutputStream::writeStruct2f) - -val Vector3iCodec = StreamCodec.Impl(DataInputStream::readVector3i, DataOutputStream::writeStruct3i) -val Vector3dCodec = StreamCodec.Impl(DataInputStream::readVector3d, DataOutputStream::writeStruct3d) -val Vector3fCodec = StreamCodec.Impl(DataInputStream::readVector3f, DataOutputStream::writeStruct3f) - -val Vector4iCodec = StreamCodec.Impl(DataInputStream::readVector4i, DataOutputStream::writeStruct4i) -val Vector4dCodec = StreamCodec.Impl(DataInputStream::readVector4d, DataOutputStream::writeStruct4d) -val Vector4fCodec = StreamCodec.Impl(DataInputStream::readVector4f, DataOutputStream::writeStruct4f) - -fun DelegateSyncher.vec2i(value: Vector2i, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector2iCodec) -fun DelegateSyncher.vec2d(value: Vector2d, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector2dCodec) -fun DelegateSyncher.vec2f(value: Vector2f, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector2fCodec) - -fun DelegateSyncher.vec3i(value: Vector3i, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector3iCodec) -fun DelegateSyncher.vec3d(value: Vector3d, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector3dCodec) -fun DelegateSyncher.vec3f(value: Vector3f, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector3fCodec) - -fun DelegateSyncher.vec4i(value: Vector4i, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector4iCodec) -fun DelegateSyncher.vec4d(value: Vector4d, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector4dCodec) -fun DelegateSyncher.vec4f(value: Vector4f, setter: DelegateSetter = DelegateSetter.passthrough(), getter: DelegateGetter = DelegateGetter.passthrough()) = Slot(ListenableDelegate.maskSmart(value, getter, setter), Vector4fCodec) diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/math/VectorLerp.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/math/VectorLerp.kt deleted file mode 100644 index f4672f5..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/math/VectorLerp.kt +++ /dev/null @@ -1,81 +0,0 @@ -package ru.dbotthepony.kommons.math - -import ru.dbotthepony.kommons.vector.Vector2d -import ru.dbotthepony.kommons.vector.Vector2f -import ru.dbotthepony.kommons.vector.Vector3d -import ru.dbotthepony.kommons.vector.Vector3f -import ru.dbotthepony.kommons.vector.Vector4d -import ru.dbotthepony.kommons.vector.Vector4f - -/** - * Linear interpolation between [a] and [b] by [t] - */ -fun linearInterpolation(t: Float, a: Vector2f, b: Vector2f): Vector2f { - if (t <= 0f) - return a - else if (t >= 1f) - return b - - return a + (b - a) * t -} - -/** - * Linear interpolation between [a] and [b] by [t] - */ -fun linearInterpolation(t: Float, a: Vector3f, b: Vector3f): Vector3f { - if (t <= 0f) - return a - else if (t >= 1f) - return b - - return a + (b - a) * t -} - -/** - * Linear interpolation between [a] and [b] by [t] - */ -fun linearInterpolation(t: Float, a: Vector4f, b: Vector4f): Vector4f { - if (t <= 0f) - return a - else if (t >= 1f) - return b - - return a + (b - a) * t -} - - -/** - * Linear interpolation between [a] and [b] by [t] - */ -fun linearInterpolation(t: Double, a: Vector2d, b: Vector2d): Vector2d { - if (t <= 0.0) - return a - else if (t >= 1.0) - return b - - return a + (b - a) * t -} - -/** - * Linear interpolation between [a] and [b] by [t] - */ -fun linearInterpolation(t: Double, a: Vector3d, b: Vector3d): Vector3d { - if (t <= 0.0) - return a - else if (t >= 1.0) - return b - - return a + (b - a) * t -} - -/** - * Linear interpolation between [a] and [b] by [t] - */ -fun linearInterpolation(t: Double, a: Vector4d, b: Vector4d): Vector4d { - if (t <= 0.0) - return a - else if (t >= 1.0) - return b - - return a + (b - a) * t -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix2d.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix2d.kt deleted file mode 100644 index 5764f18..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix2d.kt +++ /dev/null @@ -1,310 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -import ru.dbotthepony.kommons.arrays.Double2DArray -import ru.dbotthepony.kommons.arrays.mulMatrixComponents -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.vector.Vector2d -import java.nio.ByteBuffer -import java.nio.DoubleBuffer - -sealed class Matrix2d : Double2DArray() { - abstract var c00: Double - abstract var c01: Double - abstract var c10: Double - abstract var c11: Double - - fun c00() = c00 - fun c00(value: Double): Matrix2d { c00 = value; return this } - fun c01() = c01 - fun c01(value: Double): Matrix2d { c01 = value; return this } - fun c10() = c10 - fun c10(value: Double): Matrix2d { c10 = value; return this } - fun c11() = c11 - fun c11(value: Double): Matrix2d { c11 = value; return this } - - var r00: Double get() = c00; set(value) { c00 = value } // row 0 column 0 - var r01: Double get() = c10; set(value) { c10 = value } // row 1 column 0 - var r10: Double get() = c01; set(value) { c01 = value } // row 0 column 1 - var r11: Double get() = c11; set(value) { c11 = value } // row 1 column 1 - - fun r00() = r00 - fun r00(value: Double): Matrix2d { r00 = value; return this } - fun r01() = r01 - fun r01(value: Double): Matrix2d { r01 = value; return this } - fun r10() = r10 - fun r10(value: Double): Matrix2d { r10 = value; return this } - fun r11() = r11 - fun r11(value: Double): Matrix2d { r11 = value; return this } - - final override val transposed get() = - columnMajor( - c00 = r00, - c01 = r01, - c10 = r10, - c11 = r11, - ) - - final override val rows: Int - get() = 2 - final override val columns: Int - get() = 2 - - final override fun get(column: Int, row: Int): Double { - return when (row or (column shl 1)) { - C00 -> c00 - C01 -> c01 - C10 -> c10 - C11 -> c11 - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - override fun set(column: Int, row: Int, value: Double) { - when (column or (row shl 2)) { - C00 -> c00 = value - C01 -> c01 = value - C10 -> c10 = value - C11 -> c11 = value - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - final override val determinant: Double - get() = super.determinant!! - final override val cofactorMatrix - get() = from(super.cofactorMatrix!!) - final override val adjugateMatrix - get() = from(super.adjugateMatrix!!) - final override val inversed - get() = super.inversed?.let { from(it) } - - fun mul(other: Matrix2d): Matrix2d { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - this.c00 = c00 - this.c01 = c01 - this.c10 = c10 - this.c11 = c11 - return this - } - - fun mulIntoOther(other: Matrix2d): Matrix2d { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - other.c00 = c00 - other.c01 = c01 - other.c10 = c10 - other.c11 = c11 - return other - } - - fun mul( - c00: Double = 1.0, - c01: Double = 0.0, - c10: Double = 0.0, - c11: Double = 1.0, - ): Matrix2d { - val fc00 = this.c00 * c00 + this.c10 * c01 - val fc01 = this.c01 * c00 + this.c11 * c01 - val fc10 = this.c00 * c10 + this.c10 * c11 - val fc11 = this.c01 * c10 + this.c11 * c11 - this.c00 = fc00 - this.c01 = fc01 - this.c10 = fc10 - this.c11 = fc11 - return this - } - - fun mulIntoThis( - c00: Double = 1.0, - c01: Double = 0.0, - c10: Double = 0.0, - c11: Double = 1.0, - ): Matrix2d { - val fc00 = c00 * this.c00 + c10 * this.c01 - val fc01 = c01 * this.c00 + c11 * this.c01 - val fc10 = c00 * this.c10 + c10 * this.c11 - val fc11 = c01 * this.c10 + c11 * this.c11 - this.c00 = fc00 - this.c01 = fc01 - this.c10 = fc10 - this.c11 = fc11 - return this - } - - final override fun add(other: Double): Matrix2d { - return super.add(other) as Matrix2d - } - - final override fun sub(other: Double): Matrix2d { - return super.sub(other) as Matrix2d - } - - final override fun mul(other: Double): Matrix2d { - return super.mul(other) as Matrix2d - } - - final override fun div(other: Double): Matrix2d { - return super.div(other) as Matrix2d - } - - final override fun add(other: Double2DArray): Matrix2d { - return super.add(other) as Matrix2d - } - - final override fun sub(other: Double2DArray): Matrix2d { - return super.sub(other) as Matrix2d - } - - fun to3d(filler: Double) = Matrix3d.from(this, filler) - fun to3d() = Matrix3d.from(this) - fun to4d(filler: Double) = Matrix4d.from(this, filler) - fun to4d() = Matrix4d.from(this) - - fun copy(): Matrix2d { - return Impl(c00, c01, c10, c11) - } - - @JvmOverloads - fun scale(x: Double = 1.0, y: Double = 1.0): Matrix2d { - return mul(c00 = x, c11 = y) - } - - fun scale(value: IStruct2d) = scale(value.component1(), value.component2()) - fun scale(value: Vector2d) = scale(value.component1(), value.component2()) - - @JvmOverloads - fun preScale(x: Double = 1.0, y: Double = 1.0): Matrix2d { - return mulIntoThis(c00 = x, c11 = y) - } - - fun preScale(value: IStruct2d) = preScale(value.component1(), value.component2()) - fun preScale(value: Vector2d) = preScale(value.component1(), value.component2()) - - fun translate(x: Double) = mul(c10 = x) - fun preTranslate(x: Double) = mulIntoThis(c10 = x) - - private data class Impl( - override var c00: Double = 1.0, - override var c01: Double = 0.0, - override var c10: Double = 0.0, - override var c11: Double = 1.0, - ) : Matrix2d() { - override fun toString(): String { - return "Matrix2d" + super.toString() - } - - override fun equals(other: Any?): Boolean { - if (other !is Matrix2d) return false - - return this === other || c00 == other.c00 && - c01 == other.c01 && - c10 == other.c10 && - c11 == other.c11 - } - } - - private class View(private val parent: Matrix2d) : Matrix2d() { - override var c00: Double get() = parent.c00; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c01: Double get() = parent.c01; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c10: Double get() = parent.c10; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c11: Double get() = parent.c11; set(_) { throw UnsupportedOperationException("Read-Only view") } - - override fun set(column: Int, row: Int, value: Double) { - throw UnsupportedOperationException("Read-Only view") - } - - override fun equals(other: Any?): Boolean { - return other === this || parent == other - } - - override fun hashCode(): Int { - return parent.hashCode() - } - - override fun toString(): String { - return "View = $parent" - } - } - - companion object { - @JvmStatic - fun all(value: Double) = construct2(value, ::columnMajor) - - @JvmStatic - fun zero() = all(0.0) - - @JvmStatic - fun identity() = columnMajor() - - @JvmStatic - fun unmodifiable(value: Matrix2d): Matrix2d { - if (value is View) - return value - else - return View(value) - } - - @JvmStatic - fun columnMajor( - c00: Double = 1.0, - c01: Double = 0.0, - c10: Double = 0.0, - c11: Double = 1.0, - ): Matrix2d { - return Impl(c00, c01, c10, c11) - } - - @JvmStatic - fun rowMajor( - r00: Double = 1.0, r01: Double = 0.0, - r10: Double = 0.0, r11: Double = 1.0, - ): Matrix2d { - return Impl( - r00, r10, - r01, r11, - ) - } - - @JvmStatic - fun from(matrix: Double2DArray, filler: Double) = construct2(matrix, Double2DArray::get, ::columnMajor, filler) - @JvmStatic - fun from(matrix: Double2DArray) = construct2(matrix, Double2DArray::get, ::columnMajor, 0.0) - @JvmStatic - fun from(matrix: Matrix2d) = construct2(matrix, Double2DArray::get, ::columnMajor) - @JvmStatic - fun from(matrix: Matrix3d) = construct2(matrix, Double2DArray::get, ::columnMajor) - @JvmStatic - fun from(matrix: Matrix4d) = construct2(matrix, Double2DArray::get, ::columnMajor) - - @JvmStatic - fun fromTransposed(matrix: Double2DArray) = construct2(matrix, Double2DArray::get, Companion::rowMajor, 0.0) - @JvmStatic - fun fromTransposed(matrix: Double2DArray, filler: Double) = construct2(matrix, Double2DArray::get, Companion::rowMajor, filler) - @JvmStatic - fun fromTransposed(matrix: Matrix2d) = construct2(matrix, Double2DArray::get, Companion::rowMajor) - @JvmStatic - fun fromTransposed(matrix: Matrix3d) = construct2(matrix, Double2DArray::get, Companion::rowMajor) - @JvmStatic - fun fromTransposed(matrix: Matrix4d) = construct2(matrix, Double2DArray::get, Companion::rowMajor) - - @JvmStatic - fun fromColumnMajor(buffer: DoubleBuffer) = construct2(buffer, DoubleBuffer::get, ::columnMajor) - @JvmStatic - fun fromColumnMajor(buffer: ByteBuffer) = construct2(buffer, ByteBuffer::getDouble, ::columnMajor) - @JvmStatic - fun fromRowMajor(buffer: DoubleBuffer) = construct2(buffer, DoubleBuffer::get, Companion::rowMajor) - @JvmStatic - fun fromRowMajor(buffer: ByteBuffer) = construct2(buffer, ByteBuffer::getDouble, Companion::rowMajor) - - // kotlin compiler bug? it refuses to use TABLESWITCH if these are inlined - const val C00 = (0 or (0 shl 1)) - const val C01 = (0 or (1 shl 1)) - const val C10 = (1 or (0 shl 1)) - const val C11 = (1 or (1 shl 1)) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix2f.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix2f.kt deleted file mode 100644 index 3d0b7b3..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix2f.kt +++ /dev/null @@ -1,310 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -import ru.dbotthepony.kommons.arrays.Float2DArray -import ru.dbotthepony.kommons.arrays.mulMatrixComponents -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.vector.Vector2f -import java.nio.ByteBuffer -import java.nio.FloatBuffer - -sealed class Matrix2f : Float2DArray() { - abstract var c00: Float - abstract var c01: Float - abstract var c10: Float - abstract var c11: Float - - fun c00() = c00 - fun c00(value: Float): Matrix2f { c00 = value; return this } - fun c01() = c01 - fun c01(value: Float): Matrix2f { c01 = value; return this } - fun c10() = c10 - fun c10(value: Float): Matrix2f { c10 = value; return this } - fun c11() = c11 - fun c11(value: Float): Matrix2f { c11 = value; return this } - - var r00: Float get() = c00; set(value) { c00 = value } // row 0 column 0 - var r01: Float get() = c10; set(value) { c10 = value } // row 1 column 0 - var r10: Float get() = c01; set(value) { c01 = value } // row 0 column 1 - var r11: Float get() = c11; set(value) { c11 = value } // row 1 column 1 - - fun r00() = r00 - fun r00(value: Float): Matrix2f { r00 = value; return this } - fun r01() = r01 - fun r01(value: Float): Matrix2f { r01 = value; return this } - fun r10() = r10 - fun r10(value: Float): Matrix2f { r10 = value; return this } - fun r11() = r11 - fun r11(value: Float): Matrix2f { r11 = value; return this } - - final override val transposed get() = - columnMajor( - c00 = r00, - c01 = r01, - c10 = r10, - c11 = r11, - ) - - final override val rows: Int - get() = 2 - final override val columns: Int - get() = 2 - - final override fun get(column: Int, row: Int): Float { - return when (row or (column shl 1)) { - C00 -> c00 - C01 -> c01 - C10 -> c10 - C11 -> c11 - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - override fun set(column: Int, row: Int, value: Float) { - when (column or (row shl 2)) { - C00 -> c00 = value - C01 -> c01 = value - C10 -> c10 = value - C11 -> c11 = value - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - final override val determinant: Float - get() = super.determinant!! - final override val cofactorMatrix - get() = from(super.cofactorMatrix!!) - final override val adjugateMatrix - get() = from(super.adjugateMatrix!!) - final override val inversed - get() = super.inversed?.let { from(it) } - - fun mul(other: Matrix2f): Matrix2f { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - this.c00 = c00 - this.c01 = c01 - this.c10 = c10 - this.c11 = c11 - return this - } - - fun mulIntoOther(other: Matrix2f): Matrix2f { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - other.c00 = c00 - other.c01 = c01 - other.c10 = c10 - other.c11 = c11 - return other - } - - fun mul( - c00: Float = 1f, - c01: Float = 0f, - c10: Float = 0f, - c11: Float = 1f, - ): Matrix2f { - val fc00 = this.c00 * c00 + this.c10 * c01 - val fc01 = this.c01 * c00 + this.c11 * c01 - val fc10 = this.c00 * c10 + this.c10 * c11 - val fc11 = this.c01 * c10 + this.c11 * c11 - this.c00 = fc00 - this.c01 = fc01 - this.c10 = fc10 - this.c11 = fc11 - return this - } - - fun mulIntoThis( - c00: Float = 1f, - c01: Float = 0f, - c10: Float = 0f, - c11: Float = 1f, - ): Matrix2f { - val fc00 = c00 * this.c00 + c10 * this.c01 - val fc01 = c01 * this.c00 + c11 * this.c01 - val fc10 = c00 * this.c10 + c10 * this.c11 - val fc11 = c01 * this.c10 + c11 * this.c11 - this.c00 = fc00 - this.c01 = fc01 - this.c10 = fc10 - this.c11 = fc11 - return this - } - - final override fun add(other: Float): Matrix2f { - return super.add(other) as Matrix2f - } - - final override fun sub(other: Float): Matrix2f { - return super.sub(other) as Matrix2f - } - - final override fun mul(other: Float): Matrix2f { - return super.mul(other) as Matrix2f - } - - final override fun div(other: Float): Matrix2f { - return super.div(other) as Matrix2f - } - - final override fun add(other: Float2DArray): Matrix2f { - return super.add(other) as Matrix2f - } - - final override fun sub(other: Float2DArray): Matrix2f { - return super.sub(other) as Matrix2f - } - - fun to3f(filler: Float) = Matrix3f.from(this, filler) - fun to3f() = Matrix3f.from(this) - fun to4f(filler: Float) = Matrix4f.from(this, filler) - fun to4f() = Matrix4f.from(this) - - fun copy(): Matrix2f { - return Impl(c00, c01, c10, c11) - } - - @JvmOverloads - fun scale(x: Float = 1f, y: Float = 1f): Matrix2f { - return mul(c00 = x, c11 = y) - } - - fun scale(value: IStruct2f) = scale(value.component1(), value.component2()) - fun scale(value: Vector2f) = scale(value.component1(), value.component2()) - - @JvmOverloads - fun preScale(x: Float = 1f, y: Float = 1f): Matrix2f { - return mulIntoThis(c00 = x, c11 = y) - } - - fun preScale(value: IStruct2f) = preScale(value.component1(), value.component2()) - fun preScale(value: Vector2f) = preScale(value.component1(), value.component2()) - - fun translate(x: Float) = mul(c10 = x) - fun preTranslate(x: Float) = mulIntoThis(c10 = x) - - private data class Impl( - override var c00: Float = 1f, - override var c01: Float = 0f, - override var c10: Float = 0f, - override var c11: Float = 1f, - ) : Matrix2f() { - override fun toString(): String { - return "Matrix2f" + super.toString() - } - - override fun equals(other: Any?): Boolean { - if (other !is Matrix2f) return false - - return this === other || c00 == other.c00 && - c01 == other.c01 && - c10 == other.c10 && - c11 == other.c11 - } - } - - private class View(private val parent: Matrix2f) : Matrix2f() { - override var c00: Float get() = parent.c00; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c01: Float get() = parent.c01; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c10: Float get() = parent.c10; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c11: Float get() = parent.c11; set(_) { throw UnsupportedOperationException("Read-Only view") } - - override fun set(column: Int, row: Int, value: Float) { - throw UnsupportedOperationException("Read-Only view") - } - - override fun equals(other: Any?): Boolean { - return other === this || parent == other - } - - override fun hashCode(): Int { - return parent.hashCode() - } - - override fun toString(): String { - return "View = $parent" - } - } - - companion object { - @JvmStatic - fun all(value: Float) = construct2(value, ::columnMajor) - - @JvmStatic - fun zero() = all(0f) - - @JvmStatic - fun identity() = columnMajor() - - @JvmStatic - fun unmodifiable(value: Matrix2f): Matrix2f { - if (value is View) - return value - else - return View(value) - } - - @JvmStatic - fun columnMajor( - c00: Float = 1f, - c01: Float = 0f, - c10: Float = 0f, - c11: Float = 1f, - ): Matrix2f { - return Impl(c00, c01, c10, c11) - } - - @JvmStatic - fun rowMajor( - r00: Float = 1f, r01: Float = 0f, - r10: Float = 0f, r11: Float = 1f, - ): Matrix2f { - return Impl( - r00, r10, - r01, r11, - ) - } - - @JvmStatic - fun from(matrix: Float2DArray, filler: Float) = construct2(matrix, Float2DArray::get, ::columnMajor, filler) - @JvmStatic - fun from(matrix: Float2DArray) = construct2(matrix, Float2DArray::get, ::columnMajor, 0f) - @JvmStatic - fun from(matrix: Matrix2f) = construct2(matrix, Float2DArray::get, ::columnMajor) - @JvmStatic - fun from(matrix: Matrix3f) = construct2(matrix, Float2DArray::get, ::columnMajor) - @JvmStatic - fun from(matrix: Matrix4f) = construct2(matrix, Float2DArray::get, ::columnMajor) - - @JvmStatic - fun fromTransposed(matrix: Float2DArray) = construct2(matrix, Float2DArray::get, Companion::rowMajor, 0f) - @JvmStatic - fun fromTransposed(matrix: Float2DArray, filler: Float) = construct2(matrix, Float2DArray::get, Companion::rowMajor, filler) - @JvmStatic - fun fromTransposed(matrix: Matrix2f) = construct2(matrix, Float2DArray::get, Companion::rowMajor) - @JvmStatic - fun fromTransposed(matrix: Matrix3f) = construct2(matrix, Float2DArray::get, Companion::rowMajor) - @JvmStatic - fun fromTransposed(matrix: Matrix4f) = construct2(matrix, Float2DArray::get, Companion::rowMajor) - - @JvmStatic - fun fromColumnMajor(buffer: FloatBuffer) = construct2(buffer, FloatBuffer::get, ::columnMajor) - @JvmStatic - fun fromColumnMajor(buffer: ByteBuffer) = construct2(buffer, ByteBuffer::getFloat, ::columnMajor) - @JvmStatic - fun fromRowMajor(buffer: FloatBuffer) = construct2(buffer, FloatBuffer::get, Companion::rowMajor) - @JvmStatic - fun fromRowMajor(buffer: ByteBuffer) = construct2(buffer, ByteBuffer::getFloat, Companion::rowMajor) - - // kotlin compiler bug? it refuses to use TABLESWITCH if these are inlined - const val C00 = (0 or (0 shl 1)) - const val C01 = (0 or (1 shl 1)) - const val C10 = (1 or (0 shl 1)) - const val C11 = (1 or (1 shl 1)) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3d.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3d.kt deleted file mode 100644 index d88d448..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3d.kt +++ /dev/null @@ -1,496 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -import ru.dbotthepony.kommons.arrays.Double2DArray -import ru.dbotthepony.kommons.arrays.mulMatrixComponents -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct3d -import ru.dbotthepony.kommons.vector.Vector2d -import ru.dbotthepony.kommons.vector.Vector3d -import java.nio.ByteBuffer -import java.nio.DoubleBuffer -import kotlin.math.cos -import kotlin.math.sin - -sealed class Matrix3d : Double2DArray() { - abstract var c00: Double - abstract var c01: Double - abstract var c02: Double - abstract var c10: Double - abstract var c11: Double - abstract var c12: Double - abstract var c20: Double - abstract var c21: Double - abstract var c22: Double - - fun c00() = c00 - fun c00(value: Double): Matrix3d { c00 = value; return this } - fun c01() = c01 - fun c01(value: Double): Matrix3d { c01 = value; return this } - fun c02() = c02 - fun c02(value: Double): Matrix3d { c02 = value; return this } - fun c10() = c10 - fun c10(value: Double): Matrix3d { c10 = value; return this } - fun c11() = c11 - fun c11(value: Double): Matrix3d { c11 = value; return this } - fun c12() = c12 - fun c12(value: Double): Matrix3d { c12 = value; return this } - fun c20() = c20 - fun c20(value: Double): Matrix3d { c20 = value; return this } - fun c21() = c21 - fun c21(value: Double): Matrix3d { c21 = value; return this } - fun c22() = c22 - fun c22(value: Double): Matrix3d { c22 = value; return this } - - var r00: Double get() = c00; set(value) { c00 = value } // row 0 column 0 - var r01: Double get() = c10; set(value) { c10 = value } // row 1 column 0 - var r02: Double get() = c20; set(value) { c20 = value } // row 2 column 0 - var r10: Double get() = c01; set(value) { c01 = value } // row 0 column 1 - var r11: Double get() = c11; set(value) { c11 = value } // row 1 column 1 - var r12: Double get() = c21; set(value) { c21 = value } // row 2 column 1 - var r20: Double get() = c02; set(value) { c02 = value } // row 0 column 2 - var r21: Double get() = c12; set(value) { c12 = value } // row 1 column 2 - var r22: Double get() = c22; set(value) { c22 = value } // row 2 column 2 - - fun r00() = r00 - fun r00(value: Double): Matrix3d { r00 = value; return this } - fun r01() = r01 - fun r01(value: Double): Matrix3d { r01 = value; return this } - fun r02() = r02 - fun r02(value: Double): Matrix3d { r02 = value; return this } - fun r10() = r10 - fun r10(value: Double): Matrix3d { r10 = value; return this } - fun r11() = r11 - fun r11(value: Double): Matrix3d { r11 = value; return this } - fun r12() = r12 - fun r12(value: Double): Matrix3d { r12 = value; return this } - fun r20() = r20 - fun r20(value: Double): Matrix3d { r20 = value; return this } - fun r21() = r21 - fun r21(value: Double): Matrix3d { r21 = value; return this } - fun r22() = r22 - fun r22(value: Double): Matrix3d { r22 = value; return this } - - final override val rows: Int - get() = 3 - final override val columns: Int - get() = 3 - - final override val determinant: Double - get() = super.determinant!! - final override val cofactorMatrix - get() = from(super.cofactorMatrix!!) - final override val adjugateMatrix - get() = from(super.adjugateMatrix!!) - final override val inversed - get() = super.inversed?.let { from(it) } - - final override val transposed get() = - columnMajor( - c00 = r00, - c01 = r01, - c02 = r02, - c10 = r10, - c11 = r11, - c12 = r12, - c20 = r20, - c21 = r21, - c22 = r22, - ) - - final override fun get(column: Int, row: Int): Double { - return when (column or (row shl 2)) { - C00 -> c00 - C01 -> c01 - C02 -> c02 - C10 -> c10 - C11 -> c11 - C12 -> c12 - C20 -> c20 - C21 -> c21 - C22 -> c22 - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - override fun set(column: Int, row: Int, value: Double) { - when (column or (row shl 2)) { - C00 -> c00 = value - C01 -> c01 = value - C02 -> c02 = value - C10 -> c10 = value - C11 -> c11 = value - C12 -> c12 = value - C20 -> c20 = value - C21 -> c21 = value - C22 -> c22 = value - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - fun mul(other: Matrix3d): Matrix3d { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c02 = mulMatrixComponents(this, other, 0, 2) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - val c12 = mulMatrixComponents(this, other, 1, 2) - val c20 = mulMatrixComponents(this, other, 2, 0) - val c21 = mulMatrixComponents(this, other, 2, 1) - val c22 = mulMatrixComponents(this, other, 2, 2) - this.c00 = c00 - this.c01 = c01 - this.c02 = c02 - this.c10 = c10 - this.c11 = c11 - this.c12 = c12 - this.c20 = c20 - this.c21 = c21 - this.c22 = c22 - return this - } - - fun mulIntoOther(other: Matrix3d): Matrix3d { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c02 = mulMatrixComponents(this, other, 0, 2) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - val c12 = mulMatrixComponents(this, other, 1, 2) - val c20 = mulMatrixComponents(this, other, 2, 0) - val c21 = mulMatrixComponents(this, other, 2, 1) - val c22 = mulMatrixComponents(this, other, 2, 2) - other.c00 = c00 - other.c01 = c01 - other.c02 = c02 - other.c10 = c10 - other.c11 = c11 - other.c12 = c12 - other.c20 = c20 - other.c21 = c21 - other.c22 = c22 - return other - } - - fun mul( - c00: Double = 1.0, - c01: Double = 0.0, - c02: Double = 0.0, - c10: Double = 0.0, - c11: Double = 1.0, - c12: Double = 0.0, - c20: Double = 0.0, - c21: Double = 0.0, - c22: Double = 1.0, - ): Matrix3d { - val fc00 = this.c00 * c00 + this.c10 * c01 + this.c20 * c02 - val fc01 = this.c01 * c00 + this.c11 * c01 + this.c21 * c02 - val fc02 = this.c02 * c00 + this.c12 * c01 + this.c22 * c02 - val fc10 = this.c00 * c10 + this.c10 * c11 + this.c20 * c12 - val fc11 = this.c01 * c10 + this.c11 * c11 + this.c21 * c12 - val fc12 = this.c02 * c10 + this.c12 * c11 + this.c22 * c12 - val fc20 = this.c00 * c20 + this.c10 * c21 + this.c20 * c22 - val fc21 = this.c01 * c20 + this.c11 * c21 + this.c21 * c22 - val fc22 = this.c02 * c20 + this.c12 * c21 + this.c22 * c22 - this.c00 = fc00 - this.c01 = fc01 - this.c02 = fc02 - this.c10 = fc10 - this.c11 = fc11 - this.c12 = fc12 - this.c20 = fc20 - this.c21 = fc21 - this.c22 = fc22 - return this - } - - fun mulIntoThis( - c00: Double = 1.0, - c01: Double = 0.0, - c02: Double = 0.0, - c10: Double = 0.0, - c11: Double = 1.0, - c12: Double = 0.0, - c20: Double = 0.0, - c21: Double = 0.0, - c22: Double = 1.0, - ): Matrix3d { - val fc00 = c00 * this.c00 + c10 * this.c01 + c20 * this.c02 - val fc01 = c01 * this.c00 + c11 * this.c01 + c21 * this.c02 - val fc02 = c02 * this.c00 + c12 * this.c01 + c22 * this.c02 - val fc10 = c00 * this.c10 + c10 * this.c11 + c20 * this.c12 - val fc11 = c01 * this.c10 + c11 * this.c11 + c21 * this.c12 - val fc12 = c02 * this.c10 + c12 * this.c11 + c22 * this.c12 - val fc20 = c00 * this.c20 + c10 * this.c21 + c20 * this.c22 - val fc21 = c01 * this.c20 + c11 * this.c21 + c21 * this.c22 - val fc22 = c02 * this.c20 + c12 * this.c21 + c22 * this.c22 - this.c00 = fc00 - this.c01 = fc01 - this.c02 = fc02 - this.c10 = fc10 - this.c11 = fc11 - this.c12 = fc12 - this.c20 = fc20 - this.c21 = fc21 - this.c22 = fc22 - return this - } - - final override fun add(other: Double): Matrix3d { - return super.add(other) as Matrix3d - } - - final override fun sub(other: Double): Matrix3d { - return super.sub(other) as Matrix3d - } - - final override fun mul(other: Double): Matrix3d { - return super.mul(other) as Matrix3d - } - - final override fun div(other: Double): Matrix3d { - return super.div(other) as Matrix3d - } - - final override fun add(other: Double2DArray): Matrix3d { - return super.add(other) as Matrix3d - } - - final override fun sub(other: Double2DArray): Matrix3d { - return super.sub(other) as Matrix3d - } - - fun to2d() = Matrix2d.from(this) - fun to4d(filler: Double) = Matrix4d.from(this, filler) - fun to4d() = Matrix4d.from(this) - - fun copy(): Matrix3d { - return Impl(c00, c01, c02, c10, c11, c12, c20, c21, c22) - } - - @JvmOverloads - fun translate(x: Double = 0.0, y: Double = 0.0): Matrix3d { - return mul(c20 = x, c21 = y) - } - - fun translate(value: IStruct2d) = translate(value.component1(), value.component2()) - fun translate(value: Vector2d) = translate(value.component1(), value.component2()) - - @JvmOverloads - fun preTranslate(x: Double = 0.0, y: Double = 0.0): Matrix3d { - return mulIntoThis(c20 = x, c21 = y) - } - - fun preTranslate(value: IStruct2d) = preTranslate(value.component1(), value.component2()) - fun preTranslate(value: Vector2d) = preTranslate(value.component1(), value.component2()) - - @JvmOverloads - fun scale(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0): Matrix3d { - return mul(c00 = x, c11 = y, c22 = z) - } - - fun scale(value: IStruct2d) = scale(value.component1(), value.component2()) - fun scale(value: IStruct3d) = scale(value.component1(), value.component2(), value.component3()) - - fun scale(value: Vector2d) = scale(value.component1(), value.component2()) - fun scale(value: Vector3d) = scale(value.component1(), value.component2(), value.component3()) - - @JvmOverloads - fun preScale(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0): Matrix3d { - return mulIntoThis(c00 = x, c11 = y, c22 = z) - } - - fun preScale(value: IStruct2d) = preScale(value.component1(), value.component2()) - fun preScale(value: IStruct3d) = preScale(value.component1(), value.component2(), value.component3()) - - fun preScale(value: Vector2d) = preScale(value.component1(), value.component2()) - fun preScale(value: Vector3d) = preScale(value.component1(), value.component2(), value.component3()) - - fun rotateAroundZ(angle: Double): Matrix3d { - val cos = cos(angle) - val sin = sin(angle) - - return mul( - c00 = cos, - c10 = -sin, - c01 = sin, - c11 = cos, - ) - } - - fun preRotateAroundZ(angle: Double): Matrix3d { - val cos = cos(angle) - val sin = sin(angle) - - return mulIntoThis( - c00 = cos, - c10 = -sin, - c01 = sin, - c11 = cos, - ) - } - - private data class Impl( - override var c00: Double, - override var c01: Double, - override var c02: Double, - override var c10: Double, - override var c11: Double, - override var c12: Double, - override var c20: Double, - override var c21: Double, - override var c22: Double, - ) : Matrix3d() { - override fun toString(): String { - return "Matrix3d" + super.toString() - } - - override fun equals(other: Any?): Boolean { - if (other !is Matrix3d) return false - - return this === other || c00 == other.c00 && - c01 == other.c01 && - c02 == other.c02 && - c10 == other.c10 && - c11 == other.c11 && - c12 == other.c12 && - c20 == other.c20 && - c21 == other.c21 && - c22 == other.c22 - } - } - - private class View(private val parent: Matrix3d) : Matrix3d() { - override var c00: Double get() = parent.c00; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c01: Double get() = parent.c01; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c02: Double get() = parent.c02; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c10: Double get() = parent.c10; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c11: Double get() = parent.c11; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c12: Double get() = parent.c12; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c20: Double get() = parent.c20; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c21: Double get() = parent.c21; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c22: Double get() = parent.c22; set(_) { throw UnsupportedOperationException("Read-Only view") } - - override fun set(column: Int, row: Int, value: Double) { - throw UnsupportedOperationException("Read-Only view") - } - - override fun equals(other: Any?): Boolean { - return other === this || parent == other - } - - override fun hashCode(): Int { - return parent.hashCode() - } - - override fun toString(): String { - return "View = $parent" - } - } - - companion object { - @JvmStatic - fun all(value: Double) = construct3(value, ::columnMajor) - - @JvmStatic - fun zero() = all(0.0) - - @JvmStatic - fun identity() = columnMajor() - - @JvmStatic - fun unmodifiable(value: Matrix3d): Matrix3d { - if (value is View) - return value - else - return View(value) - } - - @JvmStatic - fun columnMajor( - c00: Double = 1.0, c01: Double = 0.0, c02: Double = 0.0, - c10: Double = 0.0, c11: Double = 1.0, c12: Double = 0.0, - c20: Double = 0.0, c21: Double = 0.0, c22: Double = 1.0, - ): Matrix3d { - return Impl(c00, c01, c02, c10, c11, c12, c20, c21, c22) - } - - @JvmStatic - fun rowMajor( - r00: Double = 1.0, r01: Double = 0.0, r02: Double = 0.0, - r10: Double = 0.0, r11: Double = 1.0, r12: Double = 0.0, - r20: Double = 0.0, r21: Double = 0.0, r22: Double = 1.0, - ): Matrix3d { - return Impl( - r00, r10, r20, - r01, r11, r21, - r02, r12, r22, - ) - } - - @JvmStatic - fun from(matrix: Double2DArray, filler: Double) = construct3(matrix, Double2DArray::get, ::columnMajor, filler) - @JvmStatic - fun from(matrix: Double2DArray) = construct3(matrix, Double2DArray::get, ::columnMajor, 0.0) - @JvmStatic - fun from(matrix: Matrix3d) = construct3(matrix, Double2DArray::get, ::columnMajor) - @JvmStatic - fun from(matrix: Matrix4d) = construct3(matrix, Double2DArray::get, ::columnMajor) - - @JvmStatic - fun fromTransposed(matrix: Double2DArray, filler: Double) = construct3(matrix, Double2DArray::get, Companion::rowMajor, filler) - @JvmStatic - fun fromTransposed(matrix: Double2DArray) = construct3(matrix, Double2DArray::get, Companion::rowMajor, 0.0) - @JvmStatic - fun fromTransposed(matrix: Matrix3d) = construct3(matrix, Double2DArray::get, Companion::rowMajor) - @JvmStatic - fun fromTransposed(matrix: Matrix4d) = construct3(matrix, Double2DArray::get, Companion::rowMajor) - - @JvmStatic - fun fromColumnMajor(buffer: DoubleBuffer) = construct3(buffer, DoubleBuffer::get, ::columnMajor) - @JvmStatic - fun fromColumnMajor(buffer: ByteBuffer) = construct3(buffer, ByteBuffer::getDouble, ::columnMajor) - @JvmStatic - fun fromRowMajor(buffer: DoubleBuffer) = construct3(buffer, DoubleBuffer::get, Companion::rowMajor) - @JvmStatic - fun fromRowMajor(buffer: ByteBuffer) = construct3(buffer, ByteBuffer::getDouble, Companion::rowMajor) - - /** - * Constructs new ortho projection matrix, with Y coordinate flipped (useful for OpenGL GUI drawing). - * - * Inversion of Y means that X 0 Y 0 will be top left position on screen (in OpenGL), not bottom left. - */ - @JvmStatic - fun ortho(left: Double, right: Double, bottom: Double, top: Double): Matrix3d { - return rowMajor( - r00 = 2.0 / (right - left), - r11 = -2.0 / (top - bottom), - r02 = -(right + left) / (right - left), - r12 = -(top + bottom) / (top - bottom) + 2f, - ) - } - - /** - * Constructs new ortho projection matrix - */ - @JvmStatic - fun orthoDirect(left: Double, right: Double, bottom: Double, top: Double): Matrix3d { - return rowMajor( - r00 = 2.0 / (right - left), - r11 = 2.0 / (top - bottom), - r02 = -(right + left) / (right - left), - r12 = -(top + bottom) / (top - bottom), - ) - } - - // kotlin compiler bug? it refuses to use TABLESWITCH if these are inlined - const val C00 = (0 or (0 shl 2)) - const val C01 = (0 or (1 shl 2)) - const val C02 = (0 or (2 shl 2)) - const val C10 = (1 or (0 shl 2)) - const val C11 = (1 or (1 shl 2)) - const val C12 = (1 or (2 shl 2)) - const val C20 = (2 or (0 shl 2)) - const val C21 = (2 or (1 shl 2)) - const val C22 = (2 or (2 shl 2)) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3dStack.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3dStack.kt deleted file mode 100644 index 25fcd0d..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3dStack.kt +++ /dev/null @@ -1,55 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -class Matrix3dStack { - private val stack = ArrayDeque() - - init { - stack.addLast(Matrix3d.identity()) - } - - fun clear(top: Matrix3d): Matrix3dStack { - stack.clear() - stack.addLast(top.copy()) - return this - } - - fun push(): Matrix3dStack { - stack.addLast(stack.last().copy()) - return this - } - - fun pop(): Matrix3d { - return stack.removeLast() - } - - fun last(): Matrix3d { - return stack.last() - } - - fun push(matrix: Matrix3d): Matrix3dStack { - stack.addLast(matrix.copy()) - return this - } - - fun identity() = push(Matrix3d.identity()) - fun zero() = push(Matrix3d.all(0.0)) - fun all(value: Double) = push(Matrix3d.all(value)) - - inline fun with(block: Matrix3d.() -> T): T { - return try { - push() - block(last()) - } finally { - pop() - } - } - - inline fun with(matrix: Matrix3d, block: Matrix3d.() -> T): T { - return try { - push(matrix) - block(last()) - } finally { - pop() - } - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3f.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3f.kt deleted file mode 100644 index f32e59b..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3f.kt +++ /dev/null @@ -1,496 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -import ru.dbotthepony.kommons.arrays.Float2DArray -import ru.dbotthepony.kommons.arrays.mulMatrixComponents -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct3f -import ru.dbotthepony.kommons.vector.Vector2f -import ru.dbotthepony.kommons.vector.Vector3f -import java.nio.ByteBuffer -import java.nio.FloatBuffer -import kotlin.math.cos -import kotlin.math.sin - -sealed class Matrix3f : Float2DArray() { - abstract var c00: Float - abstract var c01: Float - abstract var c02: Float - abstract var c10: Float - abstract var c11: Float - abstract var c12: Float - abstract var c20: Float - abstract var c21: Float - abstract var c22: Float - - fun c00() = c00 - fun c00(value: Float): Matrix3f { c00 = value; return this } - fun c01() = c01 - fun c01(value: Float): Matrix3f { c01 = value; return this } - fun c02() = c02 - fun c02(value: Float): Matrix3f { c02 = value; return this } - fun c10() = c10 - fun c10(value: Float): Matrix3f { c10 = value; return this } - fun c11() = c11 - fun c11(value: Float): Matrix3f { c11 = value; return this } - fun c12() = c12 - fun c12(value: Float): Matrix3f { c12 = value; return this } - fun c20() = c20 - fun c20(value: Float): Matrix3f { c20 = value; return this } - fun c21() = c21 - fun c21(value: Float): Matrix3f { c21 = value; return this } - fun c22() = c22 - fun c22(value: Float): Matrix3f { c22 = value; return this } - - var r00: Float get() = c00; set(value) { c00 = value } // row 0 column 0 - var r01: Float get() = c10; set(value) { c10 = value } // row 1 column 0 - var r02: Float get() = c20; set(value) { c20 = value } // row 2 column 0 - var r10: Float get() = c01; set(value) { c01 = value } // row 0 column 1 - var r11: Float get() = c11; set(value) { c11 = value } // row 1 column 1 - var r12: Float get() = c21; set(value) { c21 = value } // row 2 column 1 - var r20: Float get() = c02; set(value) { c02 = value } // row 0 column 2 - var r21: Float get() = c12; set(value) { c12 = value } // row 1 column 2 - var r22: Float get() = c22; set(value) { c22 = value } // row 2 column 2 - - fun r00() = r00 - fun r00(value: Float): Matrix3f { r00 = value; return this } - fun r01() = r01 - fun r01(value: Float): Matrix3f { r01 = value; return this } - fun r02() = r02 - fun r02(value: Float): Matrix3f { r02 = value; return this } - fun r10() = r10 - fun r10(value: Float): Matrix3f { r10 = value; return this } - fun r11() = r11 - fun r11(value: Float): Matrix3f { r11 = value; return this } - fun r12() = r12 - fun r12(value: Float): Matrix3f { r12 = value; return this } - fun r20() = r20 - fun r20(value: Float): Matrix3f { r20 = value; return this } - fun r21() = r21 - fun r21(value: Float): Matrix3f { r21 = value; return this } - fun r22() = r22 - fun r22(value: Float): Matrix3f { r22 = value; return this } - - final override val rows: Int - get() = 3 - final override val columns: Int - get() = 3 - - final override val determinant: Float - get() = super.determinant!! - final override val cofactorMatrix - get() = from(super.cofactorMatrix!!) - final override val adjugateMatrix - get() = from(super.adjugateMatrix!!) - final override val inversed - get() = super.inversed?.let { from(it) } - - final override val transposed get() = - columnMajor( - c00 = r00, - c01 = r01, - c02 = r02, - c10 = r10, - c11 = r11, - c12 = r12, - c20 = r20, - c21 = r21, - c22 = r22, - ) - - final override fun get(column: Int, row: Int): Float { - return when (column or (row shl 2)) { - C00 -> c00 - C01 -> c01 - C02 -> c02 - C10 -> c10 - C11 -> c11 - C12 -> c12 - C20 -> c20 - C21 -> c21 - C22 -> c22 - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - override fun set(column: Int, row: Int, value: Float) { - when (column or (row shl 2)) { - C00 -> c00 = value - C01 -> c01 = value - C02 -> c02 = value - C10 -> c10 = value - C11 -> c11 = value - C12 -> c12 = value - C20 -> c20 = value - C21 -> c21 = value - C22 -> c22 = value - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - fun mul(other: Matrix3f): Matrix3f { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c02 = mulMatrixComponents(this, other, 0, 2) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - val c12 = mulMatrixComponents(this, other, 1, 2) - val c20 = mulMatrixComponents(this, other, 2, 0) - val c21 = mulMatrixComponents(this, other, 2, 1) - val c22 = mulMatrixComponents(this, other, 2, 2) - this.c00 = c00 - this.c01 = c01 - this.c02 = c02 - this.c10 = c10 - this.c11 = c11 - this.c12 = c12 - this.c20 = c20 - this.c21 = c21 - this.c22 = c22 - return this - } - - fun mulIntoOther(other: Matrix3f): Matrix3f { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c02 = mulMatrixComponents(this, other, 0, 2) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - val c12 = mulMatrixComponents(this, other, 1, 2) - val c20 = mulMatrixComponents(this, other, 2, 0) - val c21 = mulMatrixComponents(this, other, 2, 1) - val c22 = mulMatrixComponents(this, other, 2, 2) - other.c00 = c00 - other.c01 = c01 - other.c02 = c02 - other.c10 = c10 - other.c11 = c11 - other.c12 = c12 - other.c20 = c20 - other.c21 = c21 - other.c22 = c22 - return other - } - - fun mul( - c00: Float = 1f, - c01: Float = 0f, - c02: Float = 0f, - c10: Float = 0f, - c11: Float = 1f, - c12: Float = 0f, - c20: Float = 0f, - c21: Float = 0f, - c22: Float = 1f, - ): Matrix3f { - val fc00 = this.c00 * c00 + this.c10 * c01 + this.c20 * c02 - val fc01 = this.c01 * c00 + this.c11 * c01 + this.c21 * c02 - val fc02 = this.c02 * c00 + this.c12 * c01 + this.c22 * c02 - val fc10 = this.c00 * c10 + this.c10 * c11 + this.c20 * c12 - val fc11 = this.c01 * c10 + this.c11 * c11 + this.c21 * c12 - val fc12 = this.c02 * c10 + this.c12 * c11 + this.c22 * c12 - val fc20 = this.c00 * c20 + this.c10 * c21 + this.c20 * c22 - val fc21 = this.c01 * c20 + this.c11 * c21 + this.c21 * c22 - val fc22 = this.c02 * c20 + this.c12 * c21 + this.c22 * c22 - this.c00 = fc00 - this.c01 = fc01 - this.c02 = fc02 - this.c10 = fc10 - this.c11 = fc11 - this.c12 = fc12 - this.c20 = fc20 - this.c21 = fc21 - this.c22 = fc22 - return this - } - - fun mulIntoThis( - c00: Float = 1f, - c01: Float = 0f, - c02: Float = 0f, - c10: Float = 0f, - c11: Float = 1f, - c12: Float = 0f, - c20: Float = 0f, - c21: Float = 0f, - c22: Float = 1f, - ): Matrix3f { - val fc00 = c00 * this.c00 + c10 * this.c01 + c20 * this.c02 - val fc01 = c01 * this.c00 + c11 * this.c01 + c21 * this.c02 - val fc02 = c02 * this.c00 + c12 * this.c01 + c22 * this.c02 - val fc10 = c00 * this.c10 + c10 * this.c11 + c20 * this.c12 - val fc11 = c01 * this.c10 + c11 * this.c11 + c21 * this.c12 - val fc12 = c02 * this.c10 + c12 * this.c11 + c22 * this.c12 - val fc20 = c00 * this.c20 + c10 * this.c21 + c20 * this.c22 - val fc21 = c01 * this.c20 + c11 * this.c21 + c21 * this.c22 - val fc22 = c02 * this.c20 + c12 * this.c21 + c22 * this.c22 - this.c00 = fc00 - this.c01 = fc01 - this.c02 = fc02 - this.c10 = fc10 - this.c11 = fc11 - this.c12 = fc12 - this.c20 = fc20 - this.c21 = fc21 - this.c22 = fc22 - return this - } - - final override fun add(other: Float): Matrix3f { - return super.add(other) as Matrix3f - } - - final override fun sub(other: Float): Matrix3f { - return super.sub(other) as Matrix3f - } - - final override fun mul(other: Float): Matrix3f { - return super.mul(other) as Matrix3f - } - - final override fun div(other: Float): Matrix3f { - return super.div(other) as Matrix3f - } - - final override fun add(other: Float2DArray): Matrix3f { - return super.add(other) as Matrix3f - } - - final override fun sub(other: Float2DArray): Matrix3f { - return super.sub(other) as Matrix3f - } - - fun to2f() = Matrix2f.from(this) - fun to4f(filler: Float) = Matrix4f.from(this, filler) - fun to4f() = Matrix4f.from(this) - - fun copy(): Matrix3f { - return Impl(c00, c01, c02, c10, c11, c12, c20, c21, c22) - } - - @JvmOverloads - fun translate(x: Float = 0f, y: Float = 0f): Matrix3f { - return mul(c20 = x, c21 = y) - } - - fun translate(value: IStruct2f) = translate(value.component1(), value.component2()) - fun translate(value: Vector2f) = translate(value.component1(), value.component2()) - - @JvmOverloads - fun preTranslate(x: Float = 0f, y: Float = 0f): Matrix3f { - return mulIntoThis(c20 = x, c21 = y) - } - - fun preTranslate(value: IStruct2f) = preTranslate(value.component1(), value.component2()) - fun preTranslate(value: Vector2f) = preTranslate(value.component1(), value.component2()) - - @JvmOverloads - fun scale(x: Float = 1f, y: Float = 1f, z: Float = 1f): Matrix3f { - return mul(c00 = x, c11 = y, c22 = z) - } - - fun scale(value: IStruct2f) = scale(value.component1(), value.component2()) - fun scale(value: IStruct3f) = scale(value.component1(), value.component2(), value.component3()) - - fun scale(value: Vector2f) = scale(value.component1(), value.component2()) - fun scale(value: Vector3f) = scale(value.component1(), value.component2(), value.component3()) - - @JvmOverloads - fun preScale(x: Float = 1f, y: Float = 1f, z: Float = 1f): Matrix3f { - return mulIntoThis(c00 = x, c11 = y, c22 = z) - } - - fun preScale(value: IStruct2f) = preScale(value.component1(), value.component2()) - fun preScale(value: IStruct3f) = preScale(value.component1(), value.component2(), value.component3()) - - fun preScale(value: Vector2f) = preScale(value.component1(), value.component2()) - fun preScale(value: Vector3f) = preScale(value.component1(), value.component2(), value.component3()) - - fun rotateAroundZ(angle: Float): Matrix3f { - val cos = cos(angle) - val sin = sin(angle) - - return mul( - c00 = cos, - c10 = -sin, - c01 = sin, - c11 = cos, - ) - } - - fun preRotateAroundZ(angle: Float): Matrix3f { - val cos = cos(angle) - val sin = sin(angle) - - return mulIntoThis( - c00 = cos, - c10 = -sin, - c01 = sin, - c11 = cos, - ) - } - - private data class Impl( - override var c00: Float, - override var c01: Float, - override var c02: Float, - override var c10: Float, - override var c11: Float, - override var c12: Float, - override var c20: Float, - override var c21: Float, - override var c22: Float, - ) : Matrix3f() { - override fun toString(): String { - return "Matrix3f" + super.toString() - } - - override fun equals(other: Any?): Boolean { - if (other !is Matrix3f) return false - - return c00 == other.c00 && - c01 == other.c01 && - c02 == other.c02 && - c10 == other.c10 && - c11 == other.c11 && - c12 == other.c12 && - c20 == other.c20 && - c21 == other.c21 && - c22 == other.c22 - } - } - - private class View(private val parent: Matrix3f) : Matrix3f() { - override var c00: Float get() = parent.c00; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c01: Float get() = parent.c01; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c02: Float get() = parent.c02; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c10: Float get() = parent.c10; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c11: Float get() = parent.c11; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c12: Float get() = parent.c12; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c20: Float get() = parent.c20; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c21: Float get() = parent.c21; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c22: Float get() = parent.c22; set(_) { throw UnsupportedOperationException("Read-Only view") } - - override fun set(column: Int, row: Int, value: Float) { - throw UnsupportedOperationException("Read-Only view") - } - - override fun equals(other: Any?): Boolean { - return other === this || parent == other - } - - override fun hashCode(): Int { - return parent.hashCode() - } - - override fun toString(): String { - return "View = $parent" - } - } - - companion object { - @JvmStatic - fun all(value: Float) = construct3(value, ::columnMajor) - - @JvmStatic - fun zero() = all(0f) - - @JvmStatic - fun identity() = columnMajor() - - @JvmStatic - fun unmodifiable(value: Matrix3f): Matrix3f { - if (value is View) - return value - else - return View(value) - } - - @JvmStatic - fun columnMajor( - c00: Float = 1f, c01: Float = 0f, c02: Float = 0f, - c10: Float = 0f, c11: Float = 1f, c12: Float = 0f, - c20: Float = 0f, c21: Float = 0f, c22: Float = 1f, - ): Matrix3f { - return Impl(c00, c01, c02, c10, c11, c12, c20, c21, c22) - } - - @JvmStatic - fun rowMajor( - r00: Float = 1f, r01: Float = 0f, r02: Float = 0f, - r10: Float = 0f, r11: Float = 1f, r12: Float = 0f, - r20: Float = 0f, r21: Float = 0f, r22: Float = 1f, - ): Matrix3f { - return Impl( - r00, r10, r20, - r01, r11, r21, - r02, r12, r22, - ) - } - - @JvmStatic - fun from(matrix: Float2DArray, filler: Float) = construct3(matrix, Float2DArray::get, ::columnMajor, filler) - @JvmStatic - fun from(matrix: Float2DArray) = construct3(matrix, Float2DArray::get, ::columnMajor, 0f) - @JvmStatic - fun from(matrix: Matrix3f) = construct3(matrix, Float2DArray::get, ::columnMajor) - @JvmStatic - fun from(matrix: Matrix4f) = construct3(matrix, Float2DArray::get, ::columnMajor) - - @JvmStatic - fun fromTransposed(matrix: Float2DArray, filler: Float) = construct3(matrix, Float2DArray::get, Companion::rowMajor, filler) - @JvmStatic - fun fromTransposed(matrix: Float2DArray) = construct3(matrix, Float2DArray::get, Companion::rowMajor, 0f) - @JvmStatic - fun fromTransposed(matrix: Matrix3f) = construct3(matrix, Float2DArray::get, Companion::rowMajor) - @JvmStatic - fun fromTransposed(matrix: Matrix4f) = construct3(matrix, Float2DArray::get, Companion::rowMajor) - - @JvmStatic - fun fromColumnMajor(buffer: FloatBuffer) = construct3(buffer, FloatBuffer::get, ::columnMajor) - @JvmStatic - fun fromColumnMajor(buffer: ByteBuffer) = construct3(buffer, ByteBuffer::getFloat, ::columnMajor) - @JvmStatic - fun fromRowMajor(buffer: FloatBuffer) = construct3(buffer, FloatBuffer::get, Companion::rowMajor) - @JvmStatic - fun fromRowMajor(buffer: ByteBuffer) = construct3(buffer, ByteBuffer::getFloat, Companion::rowMajor) - - /** - * Constructs new ortho projection matrix, with Y coordinate flipped (useful for OpenGL GUI drawing). - * - * Inversion of Y means that X 0 Y 0 will be top left position on screen (in OpenGL), not bottom left. - */ - @JvmStatic - fun ortho(left: Float, right: Float, bottom: Float, top: Float): Matrix3f { - return rowMajor( - r00 = 2f / (right - left), - r11 = -2f / (top - bottom), - r02 = -(right + left) / (right - left), - r12 = -(top + bottom) / (top - bottom) + 2f, - ) - } - - /** - * Constructs new ortho projection matrix - */ - @JvmStatic - fun orthoDirect(left: Float, right: Float, bottom: Float, top: Float): Matrix3f { - return rowMajor( - r00 = 2f / (right - left), - r11 = 2f / (top - bottom), - r02 = -(right + left) / (right - left), - r12 = -(top + bottom) / (top - bottom), - ) - } - - // kotlin compiler bug? it refuses to use TABLESWITCH if these are inlined - const val C00 = (0 or (0 shl 2)) - const val C01 = (0 or (1 shl 2)) - const val C02 = (0 or (2 shl 2)) - const val C10 = (1 or (0 shl 2)) - const val C11 = (1 or (1 shl 2)) - const val C12 = (1 or (2 shl 2)) - const val C20 = (2 or (0 shl 2)) - const val C21 = (2 or (1 shl 2)) - const val C22 = (2 or (2 shl 2)) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3fStack.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3fStack.kt deleted file mode 100644 index 14ed9af..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix3fStack.kt +++ /dev/null @@ -1,55 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -class Matrix3fStack { - private val stack = ArrayDeque() - - init { - stack.addLast(Matrix3f.identity()) - } - - fun clear(top: Matrix3f): Matrix3fStack { - stack.clear() - stack.addLast(top.copy()) - return this - } - - fun push(): Matrix3fStack { - stack.addLast(stack.last().copy()) - return this - } - - fun pop(): Matrix3f { - return stack.removeLast() - } - - fun last(): Matrix3f { - return stack.last() - } - - fun push(matrix: Matrix3f): Matrix3fStack { - stack.addLast(matrix.copy()) - return this - } - - fun identity() = push(Matrix3f.identity()) - fun zero() = push(Matrix3f.all(0f)) - fun all(value: Float) = push(Matrix3f.all(value)) - - inline fun with(block: Matrix3f.() -> T): T { - return try { - push() - block(last()) - } finally { - pop() - } - } - - inline fun with(matrix: Matrix3f, block: Matrix3f.() -> T): T { - return try { - push(matrix) - block(last()) - } finally { - pop() - } - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4d.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4d.kt deleted file mode 100644 index fd49214..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4d.kt +++ /dev/null @@ -1,734 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -import ru.dbotthepony.kommons.arrays.Double2DArray -import ru.dbotthepony.kommons.arrays.mulMatrixComponents -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct3d -import ru.dbotthepony.kommons.util.IStruct4d -import ru.dbotthepony.kommons.vector.Vector2d -import ru.dbotthepony.kommons.vector.Vector3d -import ru.dbotthepony.kommons.vector.Vector4d -import java.nio.ByteBuffer -import java.nio.DoubleBuffer -import kotlin.math.cos -import kotlin.math.sin -import kotlin.math.tan - -sealed class Matrix4d : Double2DArray() { - abstract var c00: Double - abstract var c01: Double - abstract var c02: Double - abstract var c03: Double - abstract var c10: Double - abstract var c11: Double - abstract var c12: Double - abstract var c13: Double - abstract var c20: Double - abstract var c21: Double - abstract var c22: Double - abstract var c23: Double - abstract var c30: Double - abstract var c31: Double - abstract var c32: Double - abstract var c33: Double - - fun c00() = c00 - fun c00(value: Double): Matrix4d { c00 = value; return this } - fun c01() = c01 - fun c01(value: Double): Matrix4d { c01 = value; return this } - fun c02() = c02 - fun c02(value: Double): Matrix4d { c02 = value; return this } - fun c03() = c03 - fun c03(value: Double): Matrix4d { c03 = value; return this } - fun c10() = c10 - fun c10(value: Double): Matrix4d { c10 = value; return this } - fun c11() = c11 - fun c11(value: Double): Matrix4d { c11 = value; return this } - fun c12() = c12 - fun c12(value: Double): Matrix4d { c12 = value; return this } - fun c13() = c13 - fun c13(value: Double): Matrix4d { c13 = value; return this } - fun c20() = c20 - fun c20(value: Double): Matrix4d { c20 = value; return this } - fun c21() = c21 - fun c21(value: Double): Matrix4d { c21 = value; return this } - fun c22() = c22 - fun c22(value: Double): Matrix4d { c22 = value; return this } - fun c23() = c23 - fun c23(value: Double): Matrix4d { c23 = value; return this } - fun c30() = c30 - fun c30(value: Double): Matrix4d { c30 = value; return this } - fun c31() = c31 - fun c31(value: Double): Matrix4d { c31 = value; return this } - fun c32() = c32 - fun c32(value: Double): Matrix4d { c32 = value; return this } - fun c33() = c33 - fun c33(value: Double): Matrix4d { c33 = value; return this } - - var r00: Double get() = c00; set(value) { c00 = value } // row 0 column 0 - var r01: Double get() = c10; set(value) { c10 = value } // row 1 column 0 - var r02: Double get() = c20; set(value) { c20 = value } // row 2 column 0 - var r03: Double get() = c30; set(value) { c30 = value } // row 3 column 0 - var r10: Double get() = c01; set(value) { c01 = value } // row 0 column 1 - var r11: Double get() = c11; set(value) { c11 = value } // row 1 column 1 - var r12: Double get() = c21; set(value) { c21 = value } // row 2 column 1 - var r13: Double get() = c31; set(value) { c31 = value } // row 3 column 1 - var r20: Double get() = c02; set(value) { c02 = value } // row 0 column 2 - var r21: Double get() = c12; set(value) { c12 = value } // row 1 column 2 - var r22: Double get() = c22; set(value) { c22 = value } // row 2 column 2 - var r23: Double get() = c32; set(value) { c32 = value } // row 3 column 2 - var r30: Double get() = c03; set(value) { c03 = value } // row 0 column 3 - var r31: Double get() = c13; set(value) { c13 = value } // row 1 column 3 - var r32: Double get() = c23; set(value) { c23 = value } // row 2 column 3 - var r33: Double get() = c33; set(value) { c33 = value } // row 3 column 3 - - fun r00() = r00 - fun r00(value: Double): Matrix4d { r00 = value; return this } - fun r01() = r01 - fun r01(value: Double): Matrix4d { r01 = value; return this } - fun r02() = r02 - fun r02(value: Double): Matrix4d { r02 = value; return this } - fun r03() = r03 - fun r03(value: Double): Matrix4d { r03 = value; return this } - fun r10() = r10 - fun r10(value: Double): Matrix4d { r10 = value; return this } - fun r11() = r11 - fun r11(value: Double): Matrix4d { r11 = value; return this } - fun r12() = r12 - fun r12(value: Double): Matrix4d { r12 = value; return this } - fun r13() = r13 - fun r13(value: Double): Matrix4d { r13 = value; return this } - fun r20() = r20 - fun r20(value: Double): Matrix4d { r20 = value; return this } - fun r21() = r21 - fun r21(value: Double): Matrix4d { r21 = value; return this } - fun r22() = r22 - fun r22(value: Double): Matrix4d { r22 = value; return this } - fun r23() = r23 - fun r23(value: Double): Matrix4d { r23 = value; return this } - fun r30() = r30 - fun r30(value: Double): Matrix4d { r30 = value; return this } - fun r31() = r31 - fun r31(value: Double): Matrix4d { r31 = value; return this } - fun r32() = r32 - fun r32(value: Double): Matrix4d { r32 = value; return this } - fun r33() = r33 - fun r33(value: Double): Matrix4d { r33 = value; return this } - - final override val rows: Int - get() = 4 - final override val columns: Int - get() = 4 - - final override val transposed get() = - columnMajor( - c00 = r00, - c01 = r01, - c02 = r02, - c03 = r03, - c10 = r10, - c11 = r11, - c12 = r12, - c13 = r13, - c20 = r20, - c21 = r21, - c22 = r22, - c23 = r23, - c30 = r30, - c31 = r31, - c32 = r32, - c33 = r33, - ) - - final override fun get(column: Int, row: Int): Double { - return when (column or (row shl 2)) { - C00 -> c00 - C01 -> c01 - C02 -> c02 - C03 -> c03 - C10 -> c10 - C11 -> c11 - C12 -> c12 - C13 -> c13 - C20 -> c20 - C21 -> c21 - C22 -> c22 - C23 -> c23 - C30 -> c30 - C31 -> c31 - C32 -> c32 - C33 -> c33 - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - override fun set(column: Int, row: Int, value: Double) { - when (column or (row shl 2)) { - C00 -> c00 = value - C01 -> c01 = value - C02 -> c02 = value - C03 -> c03 = value - C10 -> c10 = value - C11 -> c11 = value - C12 -> c12 = value - C13 -> c13 = value - C20 -> c20 = value - C21 -> c21 = value - C22 -> c22 = value - C23 -> c23 = value - C30 -> c30 = value - C31 -> c31 = value - C32 -> c32 = value - C33 -> c33 = value - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - fun mul(other: Matrix4d): Matrix4d { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c02 = mulMatrixComponents(this, other, 0, 2) - val c03 = mulMatrixComponents(this, other, 0, 3) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - val c12 = mulMatrixComponents(this, other, 1, 2) - val c13 = mulMatrixComponents(this, other, 1, 3) - val c20 = mulMatrixComponents(this, other, 2, 0) - val c21 = mulMatrixComponents(this, other, 2, 1) - val c22 = mulMatrixComponents(this, other, 2, 2) - val c23 = mulMatrixComponents(this, other, 2, 3) - val c30 = mulMatrixComponents(this, other, 3, 0) - val c31 = mulMatrixComponents(this, other, 3, 1) - val c32 = mulMatrixComponents(this, other, 3, 2) - val c33 = mulMatrixComponents(this, other, 3, 3) - this.c00 = c00 - this.c01 = c01 - this.c02 = c02 - this.c03 = c03 - this.c10 = c10 - this.c11 = c11 - this.c12 = c12 - this.c13 = c13 - this.c20 = c20 - this.c21 = c21 - this.c22 = c22 - this.c23 = c23 - this.c30 = c30 - this.c31 = c31 - this.c32 = c32 - this.c33 = c33 - return this - } - - fun mulIntoOther(other: Matrix4d): Matrix4d { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c02 = mulMatrixComponents(this, other, 0, 2) - val c03 = mulMatrixComponents(this, other, 0, 3) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - val c12 = mulMatrixComponents(this, other, 1, 2) - val c13 = mulMatrixComponents(this, other, 1, 3) - val c20 = mulMatrixComponents(this, other, 2, 0) - val c21 = mulMatrixComponents(this, other, 2, 1) - val c22 = mulMatrixComponents(this, other, 2, 2) - val c23 = mulMatrixComponents(this, other, 2, 3) - val c30 = mulMatrixComponents(this, other, 3, 0) - val c31 = mulMatrixComponents(this, other, 3, 1) - val c32 = mulMatrixComponents(this, other, 3, 2) - val c33 = mulMatrixComponents(this, other, 3, 3) - other.c00 = c00 - other.c01 = c01 - other.c02 = c02 - other.c03 = c03 - other.c10 = c10 - other.c11 = c11 - other.c12 = c12 - other.c13 = c13 - other.c20 = c20 - other.c21 = c21 - other.c22 = c22 - other.c23 = c23 - other.c30 = c30 - other.c31 = c31 - other.c32 = c32 - other.c33 = c33 - return other - } - - /** - * this * other, writes result into this - */ - fun mul( - c00: Double = 1.0, - c01: Double = 0.0, - c02: Double = 0.0, - c03: Double = 0.0, - c10: Double = 0.0, - c11: Double = 1.0, - c12: Double = 0.0, - c13: Double = 0.0, - c20: Double = 0.0, - c21: Double = 0.0, - c22: Double = 1.0, - c23: Double = 0.0, - c30: Double = 0.0, - c31: Double = 0.0, - c32: Double = 0.0, - c33: Double = 1.0, - ): Matrix4d { - val fc00 = this.c00 * c00 + this.c10 * c01 + this.c20 * c02 + this.c30 * c03 - val fc01 = this.c01 * c00 + this.c11 * c01 + this.c21 * c02 + this.c31 * c03 - val fc02 = this.c02 * c00 + this.c12 * c01 + this.c22 * c02 + this.c32 * c03 - val fc03 = this.c03 * c00 + this.c13 * c01 + this.c23 * c02 + this.c33 * c03 - val fc10 = this.c00 * c10 + this.c10 * c11 + this.c20 * c12 + this.c30 * c13 - val fc11 = this.c01 * c10 + this.c11 * c11 + this.c21 * c12 + this.c31 * c13 - val fc12 = this.c02 * c10 + this.c12 * c11 + this.c22 * c12 + this.c32 * c13 - val fc13 = this.c03 * c10 + this.c13 * c11 + this.c23 * c12 + this.c33 * c13 - val fc20 = this.c00 * c20 + this.c10 * c21 + this.c20 * c22 + this.c30 * c23 - val fc21 = this.c01 * c20 + this.c11 * c21 + this.c21 * c22 + this.c31 * c23 - val fc22 = this.c02 * c20 + this.c12 * c21 + this.c22 * c22 + this.c32 * c23 - val fc23 = this.c03 * c20 + this.c13 * c21 + this.c23 * c22 + this.c33 * c23 - val fc30 = this.c00 * c30 + this.c10 * c31 + this.c20 * c32 + this.c30 * c33 - val fc31 = this.c01 * c30 + this.c11 * c31 + this.c21 * c32 + this.c31 * c33 - val fc32 = this.c02 * c30 + this.c12 * c31 + this.c22 * c32 + this.c32 * c33 - val fc33 = this.c03 * c30 + this.c13 * c31 + this.c23 * c32 + this.c33 * c33 - this.c00 = fc00 - this.c01 = fc01 - this.c02 = fc02 - this.c03 = fc03 - this.c10 = fc10 - this.c11 = fc11 - this.c12 = fc12 - this.c13 = fc13 - this.c20 = fc20 - this.c21 = fc21 - this.c22 = fc22 - this.c23 = fc23 - this.c30 = fc30 - this.c31 = fc31 - this.c32 = fc32 - this.c33 = fc33 - return this - } - - /** - * other * this, writes result into this - */ - fun mulIntoThis( - c00: Double = 1.0, - c01: Double = 0.0, - c02: Double = 0.0, - c03: Double = 0.0, - c10: Double = 0.0, - c11: Double = 1.0, - c12: Double = 0.0, - c13: Double = 0.0, - c20: Double = 0.0, - c21: Double = 0.0, - c22: Double = 1.0, - c23: Double = 0.0, - c30: Double = 0.0, - c31: Double = 0.0, - c32: Double = 0.0, - c33: Double = 1.0, - ): Matrix4d { - val fc00 = c00 * this.c00 + c10 * this.c01 + c20 * this.c02 + c30 * this.c03 - val fc01 = c01 * this.c00 + c11 * this.c01 + c21 * this.c02 + c31 * this.c03 - val fc02 = c02 * this.c00 + c12 * this.c01 + c22 * this.c02 + c32 * this.c03 - val fc03 = c03 * this.c00 + c13 * this.c01 + c23 * this.c02 + c33 * this.c03 - val fc10 = c00 * this.c10 + c10 * this.c11 + c20 * this.c12 + c30 * this.c13 - val fc11 = c01 * this.c10 + c11 * this.c11 + c21 * this.c12 + c31 * this.c13 - val fc12 = c02 * this.c10 + c12 * this.c11 + c22 * this.c12 + c32 * this.c13 - val fc13 = c03 * this.c10 + c13 * this.c11 + c23 * this.c12 + c33 * this.c13 - val fc20 = c00 * this.c20 + c10 * this.c21 + c20 * this.c22 + c30 * this.c23 - val fc21 = c01 * this.c20 + c11 * this.c21 + c21 * this.c22 + c31 * this.c23 - val fc22 = c02 * this.c20 + c12 * this.c21 + c22 * this.c22 + c32 * this.c23 - val fc23 = c03 * this.c20 + c13 * this.c21 + c23 * this.c22 + c33 * this.c23 - val fc30 = c00 * this.c30 + c10 * this.c31 + c20 * this.c32 + c30 * this.c33 - val fc31 = c01 * this.c30 + c11 * this.c31 + c21 * this.c32 + c31 * this.c33 - val fc32 = c02 * this.c30 + c12 * this.c31 + c22 * this.c32 + c32 * this.c33 - val fc33 = c03 * this.c30 + c13 * this.c31 + c23 * this.c32 + c33 * this.c33 - this.c00 = fc00 - this.c01 = fc01 - this.c02 = fc02 - this.c03 = fc03 - this.c10 = fc10 - this.c11 = fc11 - this.c12 = fc12 - this.c13 = fc13 - this.c20 = fc20 - this.c21 = fc21 - this.c22 = fc22 - this.c23 = fc23 - this.c30 = fc30 - this.c31 = fc31 - this.c32 = fc32 - this.c33 = fc33 - return this - } - - final override fun add(other: Double): Matrix4d { - return super.add(other) as Matrix4d - } - - final override fun sub(other: Double): Matrix4d { - return super.sub(other) as Matrix4d - } - - final override fun mul(other: Double): Matrix4d { - return super.mul(other) as Matrix4d - } - - final override fun div(other: Double): Matrix4d { - return super.div(other) as Matrix4d - } - - final override fun add(other: Double2DArray): Matrix4d { - return super.add(other) as Matrix4d - } - - final override fun sub(other: Double2DArray): Matrix4d { - return super.sub(other) as Matrix4d - } - - fun to2d() = Matrix2d.from(this) - fun to3d() = Matrix3d.from(this) - - fun copy(): Matrix4d { - return Impl(c00, c01, c02, c03, c10, c11, c12, c13, c20, c21, c22, c23, c30, c31, c32, c33) - } - - @JvmOverloads - fun translate(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): Matrix4d { - return mul(c30 = x, c31 = y, c32 = z) - } - - fun translate(value: IStruct2d) = translate(value.component1(), value.component2()) - fun translate(value: IStruct3d) = translate(value.component1(), value.component2(), value.component3()) - - fun translate(value: Vector2d) = translate(value.component1(), value.component2()) - fun translate(value: Vector3d) = translate(value.component1(), value.component2(), value.component3()) - - @JvmOverloads - fun preTranslate(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): Matrix4d { - return mulIntoThis(c30 = x, c31 = y, c32 = z) - } - - fun preTranslate(value: IStruct2d) = preTranslate(value.component1(), value.component2()) - fun preTranslate(value: IStruct3d) = preTranslate(value.component1(), value.component2(), value.component3()) - - fun preTranslate(value: Vector2d) = preTranslate(value.component1(), value.component2()) - fun preTranslate(value: Vector3d) = preTranslate(value.component1(), value.component2(), value.component3()) - - @JvmOverloads - fun scale(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0, w: Double = 1.0): Matrix4d { - return mul(c00 = x, c11 = y, c22 = z, c33 = w) - } - - fun scale(value: IStruct2d) = scale(value.component1(), value.component2()) - fun scale(value: IStruct3d) = scale(value.component1(), value.component2(), value.component3()) - fun scale(value: IStruct4d) = scale(value.component1(), value.component2(), value.component3(), value.component3()) - - fun scale(value: Vector2d) = scale(value.component1(), value.component2()) - fun scale(value: Vector3d) = scale(value.component1(), value.component2(), value.component3()) - fun scale(value: Vector4d) = scale(value.component1(), value.component2(), value.component3(), value.component3()) - - @JvmOverloads - fun preScale(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0, w: Double = 1.0): Matrix4d { - return mulIntoThis(c00 = x, c11 = y, c22 = z, c33 = w) - } - - fun preScale(value: IStruct2d) = preScale(value.component1(), value.component2()) - fun preScale(value: IStruct3d) = preScale(value.component1(), value.component2(), value.component3()) - fun preScale(value: IStruct4d) = preScale(value.component1(), value.component2(), value.component3(), value.component3()) - - fun preScale(value: Vector2d) = preScale(value.component1(), value.component2()) - fun preScale(value: Vector3d) = preScale(value.component1(), value.component2(), value.component3()) - fun preScale(value: Vector4d) = preScale(value.component1(), value.component2(), value.component3(), value.component3()) - - fun rotateAroundX(angle: Double): Matrix4d { - val cos = cos(angle) - val sin = sin(angle) - - return mul( - c11 = cos, - c21 = -sin, - c12 = sin, - c22 = cos, - ) - } - - fun rotateAroundY(angle: Double): Matrix4d { - val cos = cos(angle) - val sin = sin(angle) - - return mul( - c00 = cos, - c20 = sin, - c02 = -sin, - c22 = cos, - ) - } - - fun rotateAroundZ(angle: Double): Matrix4d { - val cos = cos(angle) - val sin = sin(angle) - - return mul( - c00 = cos, - c10 = -sin, - c01 = sin, - c11 = cos, - ) - } - - fun preRotateAroundX(angle: Double): Matrix4d { - val cos = cos(angle) - val sin = sin(angle) - - return mulIntoThis( - c11 = cos, - c21 = -sin, - c12 = sin, - c22 = cos, - ) - } - - fun preRotateAroundY(angle: Double): Matrix4d { - val cos = cos(angle) - val sin = sin(angle) - - return mulIntoThis( - c00 = cos, - c20 = sin, - c02 = -sin, - c22 = cos, - ) - } - - fun preRotateAroundZ(angle: Double): Matrix4d { - val cos = cos(angle) - val sin = sin(angle) - - return mulIntoThis( - c00 = cos, - c10 = -sin, - c01 = sin, - c11 = cos, - ) - } - - private data class Impl( - override var c00: Double, - override var c01: Double, - override var c02: Double, - override var c03: Double, - override var c10: Double, - override var c11: Double, - override var c12: Double, - override var c13: Double, - override var c20: Double, - override var c21: Double, - override var c22: Double, - override var c23: Double, - override var c30: Double, - override var c31: Double, - override var c32: Double, - override var c33: Double, - ) : Matrix4d() { - override fun toString(): String { - return "Matrix4d" + super.toString() - } - - override fun equals(other: Any?): Boolean { - if (other !is Matrix4d) return false - - return this === other || c00 == other.c00 && - c01 == other.c01 && - c02 == other.c02 && - c03 == other.c03 && - c10 == other.c10 && - c11 == other.c11 && - c12 == other.c12 && - c13 == other.c13 && - c20 == other.c20 && - c21 == other.c21 && - c22 == other.c22 && - c23 == other.c23 && - c30 == other.c30 && - c31 == other.c31 && - c32 == other.c32 && - c33 == other.c33 - } - } - - private class View(private val parent: Matrix4d) : Matrix4d() { - override var c00: Double get() = parent.c00; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c01: Double get() = parent.c01; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c02: Double get() = parent.c02; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c03: Double get() = parent.c03; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c10: Double get() = parent.c10; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c11: Double get() = parent.c11; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c12: Double get() = parent.c12; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c13: Double get() = parent.c13; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c20: Double get() = parent.c20; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c21: Double get() = parent.c21; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c22: Double get() = parent.c22; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c23: Double get() = parent.c23; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c30: Double get() = parent.c30; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c31: Double get() = parent.c31; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c32: Double get() = parent.c32; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c33: Double get() = parent.c33; set(_) { throw UnsupportedOperationException("Read-Only view") } - - override fun set(column: Int, row: Int, value: Double) { - throw UnsupportedOperationException("Read-Only view") - } - - override fun equals(other: Any?): Boolean { - return other === this || parent == other - } - - override fun hashCode(): Int { - return parent.hashCode() - } - - override fun toString(): String { - return "View = $parent" - } - } - - companion object { - @JvmStatic - fun all(value: Double) = construct4(value, ::columnMajor) - - @JvmStatic - fun zero() = all(0.0) - - @JvmStatic - fun identity() = columnMajor() - - @JvmStatic - fun unmodifiable(value: Matrix4d): Matrix4d { - if (value is View) - return value - else - return View(value) - } - - @JvmStatic - fun columnMajor( - c00: Double = 1.0, c01: Double = 0.0, c02: Double = 0.0, c03: Double = 0.0, - c10: Double = 0.0, c11: Double = 1.0, c12: Double = 0.0, c13: Double = 0.0, - c20: Double = 0.0, c21: Double = 0.0, c22: Double = 1.0, c23: Double = 0.0, - c30: Double = 0.0, c31: Double = 0.0, c32: Double = 0.0, c33: Double = 1.0, - ): Matrix4d { - return Impl(c00, c01, c02, c03, c10, c11, c12, c13, c20, c21, c22, c23, c30, c31, c32, c33) - } - - @JvmStatic - fun rowMajor( - r00: Double = 1.0, r01: Double = 0.0, r02: Double = 0.0, r03: Double = 0.0, - r10: Double = 0.0, r11: Double = 1.0, r12: Double = 0.0, r13: Double = 0.0, - r20: Double = 0.0, r21: Double = 0.0, r22: Double = 1.0, r23: Double = 0.0, - r30: Double = 0.0, r31: Double = 0.0, r32: Double = 0.0, r33: Double = 1.0 - ): Matrix4d { - return Impl( - r00, r10, r20, r30, - r01, r11, r21, r31, - r02, r12, r22, r32, - r03, r13, r23, r33 - ) - } - - @JvmStatic - fun from(matrix: Double2DArray, filler: Double) = construct4(matrix, Double2DArray::get, ::columnMajor, filler) - @JvmStatic - fun from(matrix: Double2DArray) = construct4(matrix, Double2DArray::get, ::columnMajor, 0.0) - @JvmStatic - fun from(matrix: Matrix4d) = construct4(matrix, Double2DArray::get, ::columnMajor) - - @JvmStatic - fun fromTransposed(matrix: Double2DArray) = construct4(matrix, Double2DArray::get, Companion::rowMajor, 0.0) - @JvmStatic - fun fromTransposed(matrix: Double2DArray, filler: Double) = construct4(matrix, Double2DArray::get, Companion::rowMajor, filler) - @JvmStatic - fun fromTransposed(matrix: Matrix4d) = construct4(matrix, Double2DArray::get, Companion::rowMajor) - - @JvmStatic - fun fromColumnMajor(buffer: DoubleBuffer) = construct4(buffer, DoubleBuffer::get, ::columnMajor) - @JvmStatic - fun fromColumnMajor(buffer: ByteBuffer) = construct4(buffer, ByteBuffer::getDouble, ::columnMajor) - @JvmStatic - fun fromRowMajor(buffer: DoubleBuffer) = construct4(buffer, DoubleBuffer::get, Companion::rowMajor) - @JvmStatic - fun fromRowMajor(buffer: ByteBuffer) = construct4(buffer, ByteBuffer::getDouble, Companion::rowMajor) - - /** - * Constructs new ortho projection matrix, with Y coordinate flipped (useful for OpenGL GUI drawing). - * - * Inversion of Y means that X 0 Y 0 will be top left position on screen (in OpenGL), not bottom left. - */ - @JvmStatic - fun ortho(left: Double, right: Double, bottom: Double, top: Double, zNear: Double, zFar: Double): Matrix4d { - return rowMajor( - r00 = 2.0 / (right - left), - r11 = -2.0 / (top - bottom), - r22 = 2.0 / (zFar - zNear), - r03 = -(right + left) / (right - left), - r13 = -(top + bottom) / (top - bottom) + 2.0, - r23 = -(zFar + zNear) / (zFar - zNear) - ) - } - - /** - * Constructs new ortho projection matrix - */ - @JvmStatic - fun orthoDirect(left: Double, right: Double, bottom: Double, top: Double, zNear: Double, zFar: Double): Matrix4d { - return rowMajor( - r00 = 2.0 / (right - left), - r11 = 2.0 / (top - bottom), - r22 = 2.0 / (zFar - zNear), - r03 = -(right + left) / (right - left), - r13 = -(top + bottom) / (top - bottom), - r23 = -(zFar + zNear) / (zFar - zNear) - ) - } - - /** - * Constructs new perspective matrix - */ - @JvmStatic - fun perspective(fov: Double, zFar: Double, zNear: Double): Matrix4d { - val scale = (1.0 / (tan(Math.toRadians(fov.toDouble()) / 2.0))).toDouble() - val r = zFar - zNear - - return rowMajor( - r00 = scale, - r11 = scale, - r22 = -zFar / r, - r23 = -1.0, - r32 = -zFar * zNear / r, - ) - } - - // kotlin compiler bug? it refuses to use TABLESWITCH if these are inlined - const val C00 = (0 or (0 shl 2)) - const val C01 = (0 or (1 shl 2)) - const val C02 = (0 or (2 shl 2)) - const val C03 = (0 or (3 shl 2)) - const val C10 = (1 or (0 shl 2)) - const val C11 = (1 or (1 shl 2)) - const val C12 = (1 or (2 shl 2)) - const val C13 = (1 or (3 shl 2)) - const val C20 = (2 or (0 shl 2)) - const val C21 = (2 or (1 shl 2)) - const val C22 = (2 or (2 shl 2)) - const val C23 = (2 or (3 shl 2)) - const val C30 = (3 or (0 shl 2)) - const val C31 = (3 or (1 shl 2)) - const val C32 = (3 or (2 shl 2)) - const val C33 = (3 or (3 shl 2)) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4dStack.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4dStack.kt deleted file mode 100644 index 230e8b0..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4dStack.kt +++ /dev/null @@ -1,55 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -class Matrix4dStack { - private val stack = ArrayDeque() - - init { - stack.addLast(Matrix4d.identity()) - } - - fun clear(top: Matrix4d): Matrix4dStack { - stack.clear() - stack.addLast(top.copy()) - return this - } - - fun push(): Matrix4dStack { - stack.addLast(stack.last().copy()) - return this - } - - fun pop(): Matrix4d { - return stack.removeLast() - } - - fun last(): Matrix4d { - return stack.last() - } - - fun push(matrix: Matrix4d): Matrix4dStack { - stack.addLast(matrix.copy()) - return this - } - - fun identity() = push(Matrix4d.identity()) - fun zero() = push(Matrix4d.all(0.0)) - fun all(value: Double) = push(Matrix4d.all(value)) - - inline fun with(block: Matrix4d.() -> T): T { - return try { - push() - block(last()) - } finally { - pop() - } - } - - inline fun with(matrix: Matrix4d, block: Matrix4d.() -> T): T { - return try { - push(matrix) - block(last()) - } finally { - pop() - } - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4f.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4f.kt deleted file mode 100644 index 6f1d32e..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4f.kt +++ /dev/null @@ -1,734 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -import ru.dbotthepony.kommons.arrays.Float2DArray -import ru.dbotthepony.kommons.arrays.mulMatrixComponents -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct3f -import ru.dbotthepony.kommons.util.IStruct4f -import ru.dbotthepony.kommons.vector.Vector2f -import ru.dbotthepony.kommons.vector.Vector3f -import ru.dbotthepony.kommons.vector.Vector4f -import java.nio.ByteBuffer -import java.nio.FloatBuffer -import kotlin.math.cos -import kotlin.math.sin -import kotlin.math.tan - -sealed class Matrix4f : Float2DArray() { - abstract var c00: Float - abstract var c01: Float - abstract var c02: Float - abstract var c03: Float - abstract var c10: Float - abstract var c11: Float - abstract var c12: Float - abstract var c13: Float - abstract var c20: Float - abstract var c21: Float - abstract var c22: Float - abstract var c23: Float - abstract var c30: Float - abstract var c31: Float - abstract var c32: Float - abstract var c33: Float - - fun c00() = c00 - fun c00(value: Float): Matrix4f { c00 = value; return this } - fun c01() = c01 - fun c01(value: Float): Matrix4f { c01 = value; return this } - fun c02() = c02 - fun c02(value: Float): Matrix4f { c02 = value; return this } - fun c03() = c03 - fun c03(value: Float): Matrix4f { c03 = value; return this } - fun c10() = c10 - fun c10(value: Float): Matrix4f { c10 = value; return this } - fun c11() = c11 - fun c11(value: Float): Matrix4f { c11 = value; return this } - fun c12() = c12 - fun c12(value: Float): Matrix4f { c12 = value; return this } - fun c13() = c13 - fun c13(value: Float): Matrix4f { c13 = value; return this } - fun c20() = c20 - fun c20(value: Float): Matrix4f { c20 = value; return this } - fun c21() = c21 - fun c21(value: Float): Matrix4f { c21 = value; return this } - fun c22() = c22 - fun c22(value: Float): Matrix4f { c22 = value; return this } - fun c23() = c23 - fun c23(value: Float): Matrix4f { c23 = value; return this } - fun c30() = c30 - fun c30(value: Float): Matrix4f { c30 = value; return this } - fun c31() = c31 - fun c31(value: Float): Matrix4f { c31 = value; return this } - fun c32() = c32 - fun c32(value: Float): Matrix4f { c32 = value; return this } - fun c33() = c33 - fun c33(value: Float): Matrix4f { c33 = value; return this } - - var r00: Float get() = c00; set(value) { c00 = value } // row 0 column 0 - var r01: Float get() = c10; set(value) { c10 = value } // row 1 column 0 - var r02: Float get() = c20; set(value) { c20 = value } // row 2 column 0 - var r03: Float get() = c30; set(value) { c30 = value } // row 3 column 0 - var r10: Float get() = c01; set(value) { c01 = value } // row 0 column 1 - var r11: Float get() = c11; set(value) { c11 = value } // row 1 column 1 - var r12: Float get() = c21; set(value) { c21 = value } // row 2 column 1 - var r13: Float get() = c31; set(value) { c31 = value } // row 3 column 1 - var r20: Float get() = c02; set(value) { c02 = value } // row 0 column 2 - var r21: Float get() = c12; set(value) { c12 = value } // row 1 column 2 - var r22: Float get() = c22; set(value) { c22 = value } // row 2 column 2 - var r23: Float get() = c32; set(value) { c32 = value } // row 3 column 2 - var r30: Float get() = c03; set(value) { c03 = value } // row 0 column 3 - var r31: Float get() = c13; set(value) { c13 = value } // row 1 column 3 - var r32: Float get() = c23; set(value) { c23 = value } // row 2 column 3 - var r33: Float get() = c33; set(value) { c33 = value } // row 3 column 3 - - fun r00() = r00 - fun r00(value: Float): Matrix4f { r00 = value; return this } - fun r01() = r01 - fun r01(value: Float): Matrix4f { r01 = value; return this } - fun r02() = r02 - fun r02(value: Float): Matrix4f { r02 = value; return this } - fun r03() = r03 - fun r03(value: Float): Matrix4f { r03 = value; return this } - fun r10() = r10 - fun r10(value: Float): Matrix4f { r10 = value; return this } - fun r11() = r11 - fun r11(value: Float): Matrix4f { r11 = value; return this } - fun r12() = r12 - fun r12(value: Float): Matrix4f { r12 = value; return this } - fun r13() = r13 - fun r13(value: Float): Matrix4f { r13 = value; return this } - fun r20() = r20 - fun r20(value: Float): Matrix4f { r20 = value; return this } - fun r21() = r21 - fun r21(value: Float): Matrix4f { r21 = value; return this } - fun r22() = r22 - fun r22(value: Float): Matrix4f { r22 = value; return this } - fun r23() = r23 - fun r23(value: Float): Matrix4f { r23 = value; return this } - fun r30() = r30 - fun r30(value: Float): Matrix4f { r30 = value; return this } - fun r31() = r31 - fun r31(value: Float): Matrix4f { r31 = value; return this } - fun r32() = r32 - fun r32(value: Float): Matrix4f { r32 = value; return this } - fun r33() = r33 - fun r33(value: Float): Matrix4f { r33 = value; return this } - - final override val rows: Int - get() = 4 - final override val columns: Int - get() = 4 - - final override val transposed get() = - columnMajor( - c00 = r00, - c01 = r01, - c02 = r02, - c03 = r03, - c10 = r10, - c11 = r11, - c12 = r12, - c13 = r13, - c20 = r20, - c21 = r21, - c22 = r22, - c23 = r23, - c30 = r30, - c31 = r31, - c32 = r32, - c33 = r33, - ) - - final override fun get(column: Int, row: Int): Float { - return when (column or (row shl 2)) { - C00 -> c00 - C01 -> c01 - C02 -> c02 - C03 -> c03 - C10 -> c10 - C11 -> c11 - C12 -> c12 - C13 -> c13 - C20 -> c20 - C21 -> c21 - C22 -> c22 - C23 -> c23 - C30 -> c30 - C31 -> c31 - C32 -> c32 - C33 -> c33 - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - override fun set(column: Int, row: Int, value: Float) { - when (column or (row shl 2)) { - C00 -> c00 = value - C01 -> c01 = value - C02 -> c02 = value - C03 -> c03 = value - C10 -> c10 = value - C11 -> c11 = value - C12 -> c12 = value - C13 -> c13 = value - C20 -> c20 = value - C21 -> c21 = value - C22 -> c22 = value - C23 -> c23 = value - C30 -> c30 = value - C31 -> c31 = value - C32 -> c32 = value - C33 -> c33 = value - else -> throw IndexOutOfBoundsException("Column $column; Row $row; while size of this matrix are 4x4") - } - } - - fun mul(other: Matrix4f): Matrix4f { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c02 = mulMatrixComponents(this, other, 0, 2) - val c03 = mulMatrixComponents(this, other, 0, 3) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - val c12 = mulMatrixComponents(this, other, 1, 2) - val c13 = mulMatrixComponents(this, other, 1, 3) - val c20 = mulMatrixComponents(this, other, 2, 0) - val c21 = mulMatrixComponents(this, other, 2, 1) - val c22 = mulMatrixComponents(this, other, 2, 2) - val c23 = mulMatrixComponents(this, other, 2, 3) - val c30 = mulMatrixComponents(this, other, 3, 0) - val c31 = mulMatrixComponents(this, other, 3, 1) - val c32 = mulMatrixComponents(this, other, 3, 2) - val c33 = mulMatrixComponents(this, other, 3, 3) - this.c00 = c00 - this.c01 = c01 - this.c02 = c02 - this.c03 = c03 - this.c10 = c10 - this.c11 = c11 - this.c12 = c12 - this.c13 = c13 - this.c20 = c20 - this.c21 = c21 - this.c22 = c22 - this.c23 = c23 - this.c30 = c30 - this.c31 = c31 - this.c32 = c32 - this.c33 = c33 - return this - } - - fun mulIntoOther(other: Matrix4f): Matrix4f { - val c00 = mulMatrixComponents(this, other, 0, 0) - val c01 = mulMatrixComponents(this, other, 0, 1) - val c02 = mulMatrixComponents(this, other, 0, 2) - val c03 = mulMatrixComponents(this, other, 0, 3) - val c10 = mulMatrixComponents(this, other, 1, 0) - val c11 = mulMatrixComponents(this, other, 1, 1) - val c12 = mulMatrixComponents(this, other, 1, 2) - val c13 = mulMatrixComponents(this, other, 1, 3) - val c20 = mulMatrixComponents(this, other, 2, 0) - val c21 = mulMatrixComponents(this, other, 2, 1) - val c22 = mulMatrixComponents(this, other, 2, 2) - val c23 = mulMatrixComponents(this, other, 2, 3) - val c30 = mulMatrixComponents(this, other, 3, 0) - val c31 = mulMatrixComponents(this, other, 3, 1) - val c32 = mulMatrixComponents(this, other, 3, 2) - val c33 = mulMatrixComponents(this, other, 3, 3) - other.c00 = c00 - other.c01 = c01 - other.c02 = c02 - other.c03 = c03 - other.c10 = c10 - other.c11 = c11 - other.c12 = c12 - other.c13 = c13 - other.c20 = c20 - other.c21 = c21 - other.c22 = c22 - other.c23 = c23 - other.c30 = c30 - other.c31 = c31 - other.c32 = c32 - other.c33 = c33 - return other - } - - /** - * this * other, writes result into this - */ - fun mul( - c00: Float = 1f, - c01: Float = 0f, - c02: Float = 0f, - c03: Float = 0f, - c10: Float = 0f, - c11: Float = 1f, - c12: Float = 0f, - c13: Float = 0f, - c20: Float = 0f, - c21: Float = 0f, - c22: Float = 1f, - c23: Float = 0f, - c30: Float = 0f, - c31: Float = 0f, - c32: Float = 0f, - c33: Float = 1f, - ): Matrix4f { - val fc00 = this.c00 * c00 + this.c10 * c01 + this.c20 * c02 + this.c30 * c03 - val fc01 = this.c01 * c00 + this.c11 * c01 + this.c21 * c02 + this.c31 * c03 - val fc02 = this.c02 * c00 + this.c12 * c01 + this.c22 * c02 + this.c32 * c03 - val fc03 = this.c03 * c00 + this.c13 * c01 + this.c23 * c02 + this.c33 * c03 - val fc10 = this.c00 * c10 + this.c10 * c11 + this.c20 * c12 + this.c30 * c13 - val fc11 = this.c01 * c10 + this.c11 * c11 + this.c21 * c12 + this.c31 * c13 - val fc12 = this.c02 * c10 + this.c12 * c11 + this.c22 * c12 + this.c32 * c13 - val fc13 = this.c03 * c10 + this.c13 * c11 + this.c23 * c12 + this.c33 * c13 - val fc20 = this.c00 * c20 + this.c10 * c21 + this.c20 * c22 + this.c30 * c23 - val fc21 = this.c01 * c20 + this.c11 * c21 + this.c21 * c22 + this.c31 * c23 - val fc22 = this.c02 * c20 + this.c12 * c21 + this.c22 * c22 + this.c32 * c23 - val fc23 = this.c03 * c20 + this.c13 * c21 + this.c23 * c22 + this.c33 * c23 - val fc30 = this.c00 * c30 + this.c10 * c31 + this.c20 * c32 + this.c30 * c33 - val fc31 = this.c01 * c30 + this.c11 * c31 + this.c21 * c32 + this.c31 * c33 - val fc32 = this.c02 * c30 + this.c12 * c31 + this.c22 * c32 + this.c32 * c33 - val fc33 = this.c03 * c30 + this.c13 * c31 + this.c23 * c32 + this.c33 * c33 - this.c00 = fc00 - this.c01 = fc01 - this.c02 = fc02 - this.c03 = fc03 - this.c10 = fc10 - this.c11 = fc11 - this.c12 = fc12 - this.c13 = fc13 - this.c20 = fc20 - this.c21 = fc21 - this.c22 = fc22 - this.c23 = fc23 - this.c30 = fc30 - this.c31 = fc31 - this.c32 = fc32 - this.c33 = fc33 - return this - } - - /** - * other * this, writes result into this - */ - fun mulIntoThis( - c00: Float = 1f, - c01: Float = 0f, - c02: Float = 0f, - c03: Float = 0f, - c10: Float = 0f, - c11: Float = 1f, - c12: Float = 0f, - c13: Float = 0f, - c20: Float = 0f, - c21: Float = 0f, - c22: Float = 1f, - c23: Float = 0f, - c30: Float = 0f, - c31: Float = 0f, - c32: Float = 0f, - c33: Float = 1f, - ): Matrix4f { - val fc00 = c00 * this.c00 + c10 * this.c01 + c20 * this.c02 + c30 * this.c03 - val fc01 = c01 * this.c00 + c11 * this.c01 + c21 * this.c02 + c31 * this.c03 - val fc02 = c02 * this.c00 + c12 * this.c01 + c22 * this.c02 + c32 * this.c03 - val fc03 = c03 * this.c00 + c13 * this.c01 + c23 * this.c02 + c33 * this.c03 - val fc10 = c00 * this.c10 + c10 * this.c11 + c20 * this.c12 + c30 * this.c13 - val fc11 = c01 * this.c10 + c11 * this.c11 + c21 * this.c12 + c31 * this.c13 - val fc12 = c02 * this.c10 + c12 * this.c11 + c22 * this.c12 + c32 * this.c13 - val fc13 = c03 * this.c10 + c13 * this.c11 + c23 * this.c12 + c33 * this.c13 - val fc20 = c00 * this.c20 + c10 * this.c21 + c20 * this.c22 + c30 * this.c23 - val fc21 = c01 * this.c20 + c11 * this.c21 + c21 * this.c22 + c31 * this.c23 - val fc22 = c02 * this.c20 + c12 * this.c21 + c22 * this.c22 + c32 * this.c23 - val fc23 = c03 * this.c20 + c13 * this.c21 + c23 * this.c22 + c33 * this.c23 - val fc30 = c00 * this.c30 + c10 * this.c31 + c20 * this.c32 + c30 * this.c33 - val fc31 = c01 * this.c30 + c11 * this.c31 + c21 * this.c32 + c31 * this.c33 - val fc32 = c02 * this.c30 + c12 * this.c31 + c22 * this.c32 + c32 * this.c33 - val fc33 = c03 * this.c30 + c13 * this.c31 + c23 * this.c32 + c33 * this.c33 - this.c00 = fc00 - this.c01 = fc01 - this.c02 = fc02 - this.c03 = fc03 - this.c10 = fc10 - this.c11 = fc11 - this.c12 = fc12 - this.c13 = fc13 - this.c20 = fc20 - this.c21 = fc21 - this.c22 = fc22 - this.c23 = fc23 - this.c30 = fc30 - this.c31 = fc31 - this.c32 = fc32 - this.c33 = fc33 - return this - } - - final override fun add(other: Float): Matrix4f { - return super.add(other) as Matrix4f - } - - final override fun sub(other: Float): Matrix4f { - return super.sub(other) as Matrix4f - } - - final override fun mul(other: Float): Matrix4f { - return super.mul(other) as Matrix4f - } - - final override fun div(other: Float): Matrix4f { - return super.div(other) as Matrix4f - } - - final override fun add(other: Float2DArray): Matrix4f { - return super.add(other) as Matrix4f - } - - final override fun sub(other: Float2DArray): Matrix4f { - return super.sub(other) as Matrix4f - } - - fun to2f() = Matrix2f.from(this) - fun to3f() = Matrix3f.from(this) - - fun copy(): Matrix4f { - return Impl(c00, c01, c02, c03, c10, c11, c12, c13, c20, c21, c22, c23, c30, c31, c32, c33) - } - - @JvmOverloads - fun translate(x: Float = 0f, y: Float = 0f, z: Float = 0f): Matrix4f { - return mul(c30 = x, c31 = y, c32 = z) - } - - fun translate(value: IStruct2f) = translate(value.component1(), value.component2()) - fun translate(value: IStruct3f) = translate(value.component1(), value.component2(), value.component3()) - - fun translate(value: Vector2f) = translate(value.component1(), value.component2()) - fun translate(value: Vector3f) = translate(value.component1(), value.component2(), value.component3()) - - @JvmOverloads - fun preTranslate(x: Float = 0f, y: Float = 0f, z: Float = 0f): Matrix4f { - return mulIntoThis(c30 = x, c31 = y, c32 = z) - } - - fun preTranslate(value: IStruct2f) = preTranslate(value.component1(), value.component2()) - fun preTranslate(value: IStruct3f) = preTranslate(value.component1(), value.component2(), value.component3()) - - fun preTranslate(value: Vector2f) = preTranslate(value.component1(), value.component2()) - fun preTranslate(value: Vector3f) = preTranslate(value.component1(), value.component2(), value.component3()) - - @JvmOverloads - fun scale(x: Float = 1f, y: Float = 1f, z: Float = 1f, w: Float = 1f): Matrix4f { - return mul(c00 = x, c11 = y, c22 = z, c33 = w) - } - - fun scale(value: IStruct2f) = scale(value.component1(), value.component2()) - fun scale(value: IStruct3f) = scale(value.component1(), value.component2(), value.component3()) - fun scale(value: IStruct4f) = scale(value.component1(), value.component2(), value.component3(), value.component3()) - - fun scale(value: Vector2f) = scale(value.component1(), value.component2()) - fun scale(value: Vector3f) = scale(value.component1(), value.component2(), value.component3()) - fun scale(value: Vector4f) = scale(value.component1(), value.component2(), value.component3(), value.component3()) - - @JvmOverloads - fun preScale(x: Float = 1f, y: Float = 1f, z: Float = 1f, w: Float = 1f): Matrix4f { - return mulIntoThis(c00 = x, c11 = y, c22 = z, c33 = w) - } - - fun preScale(value: IStruct2f) = preScale(value.component1(), value.component2()) - fun preScale(value: IStruct3f) = preScale(value.component1(), value.component2(), value.component3()) - fun preScale(value: IStruct4f) = preScale(value.component1(), value.component2(), value.component3(), value.component3()) - - fun preScale(value: Vector2f) = preScale(value.component1(), value.component2()) - fun preScale(value: Vector3f) = preScale(value.component1(), value.component2(), value.component3()) - fun preScale(value: Vector4f) = preScale(value.component1(), value.component2(), value.component3(), value.component3()) - - fun rotateAroundX(angle: Float): Matrix4f { - val cos = cos(angle) - val sin = sin(angle) - - return mul( - c11 = cos, - c21 = -sin, - c12 = sin, - c22 = cos, - ) - } - - fun rotateAroundY(angle: Float): Matrix4f { - val cos = cos(angle) - val sin = sin(angle) - - return mul( - c00 = cos, - c20 = sin, - c02 = -sin, - c22 = cos, - ) - } - - fun rotateAroundZ(angle: Float): Matrix4f { - val cos = cos(angle) - val sin = sin(angle) - - return mul( - c00 = cos, - c10 = -sin, - c01 = sin, - c11 = cos, - ) - } - - fun preRotateAroundX(angle: Float): Matrix4f { - val cos = cos(angle) - val sin = sin(angle) - - return mulIntoThis( - c11 = cos, - c21 = -sin, - c12 = sin, - c22 = cos, - ) - } - - fun preRotateAroundY(angle: Float): Matrix4f { - val cos = cos(angle) - val sin = sin(angle) - - return mulIntoThis( - c00 = cos, - c20 = sin, - c02 = -sin, - c22 = cos, - ) - } - - fun preRotateAroundZ(angle: Float): Matrix4f { - val cos = cos(angle) - val sin = sin(angle) - - return mulIntoThis( - c00 = cos, - c10 = -sin, - c01 = sin, - c11 = cos, - ) - } - - private data class Impl( - override var c00: Float, - override var c01: Float, - override var c02: Float, - override var c03: Float, - override var c10: Float, - override var c11: Float, - override var c12: Float, - override var c13: Float, - override var c20: Float, - override var c21: Float, - override var c22: Float, - override var c23: Float, - override var c30: Float, - override var c31: Float, - override var c32: Float, - override var c33: Float, - ) : Matrix4f() { - override fun toString(): String { - return "Matrix4f" + super.toString() - } - - override fun equals(other: Any?): Boolean { - if (other !is Matrix4f) return false - - return this === other || c00 == other.c00 && - c01 == other.c01 && - c02 == other.c02 && - c03 == other.c03 && - c10 == other.c10 && - c11 == other.c11 && - c12 == other.c12 && - c13 == other.c13 && - c20 == other.c20 && - c21 == other.c21 && - c22 == other.c22 && - c23 == other.c23 && - c30 == other.c30 && - c31 == other.c31 && - c32 == other.c32 && - c33 == other.c33 - } - } - - private class View(private val parent: Matrix4f) : Matrix4f() { - override var c00: Float get() = parent.c00; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c01: Float get() = parent.c01; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c02: Float get() = parent.c02; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c03: Float get() = parent.c03; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c10: Float get() = parent.c10; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c11: Float get() = parent.c11; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c12: Float get() = parent.c12; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c13: Float get() = parent.c13; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c20: Float get() = parent.c20; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c21: Float get() = parent.c21; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c22: Float get() = parent.c22; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c23: Float get() = parent.c23; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c30: Float get() = parent.c30; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c31: Float get() = parent.c31; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c32: Float get() = parent.c32; set(_) { throw UnsupportedOperationException("Read-Only view") } - override var c33: Float get() = parent.c33; set(_) { throw UnsupportedOperationException("Read-Only view") } - - override fun set(column: Int, row: Int, value: Float) { - throw UnsupportedOperationException("Read-Only view") - } - - override fun equals(other: Any?): Boolean { - return other === this || parent == other - } - - override fun hashCode(): Int { - return parent.hashCode() - } - - override fun toString(): String { - return "View = $parent" - } - } - - companion object { - @JvmStatic - fun all(value: Float) = construct4(value, ::columnMajor) - - @JvmStatic - fun zero() = all(0f) - - @JvmStatic - fun identity() = columnMajor() - - @JvmStatic - fun unmodifiable(value: Matrix4f): Matrix4f { - if (value is View) - return value - else - return View(value) - } - - @JvmStatic - fun columnMajor( - c00: Float = 1f, c01: Float = 0f, c02: Float = 0f, c03: Float = 0f, - c10: Float = 0f, c11: Float = 1f, c12: Float = 0f, c13: Float = 0f, - c20: Float = 0f, c21: Float = 0f, c22: Float = 1f, c23: Float = 0f, - c30: Float = 0f, c31: Float = 0f, c32: Float = 0f, c33: Float = 1f, - ): Matrix4f { - return Impl(c00, c01, c02, c03, c10, c11, c12, c13, c20, c21, c22, c23, c30, c31, c32, c33) - } - - @JvmStatic - fun rowMajor( - r00: Float = 1f, r01: Float = 0f, r02: Float = 0f, r03: Float = 0f, - r10: Float = 0f, r11: Float = 1f, r12: Float = 0f, r13: Float = 0f, - r20: Float = 0f, r21: Float = 0f, r22: Float = 1f, r23: Float = 0f, - r30: Float = 0f, r31: Float = 0f, r32: Float = 0f, r33: Float = 1f - ): Matrix4f { - return Impl( - r00, r10, r20, r30, - r01, r11, r21, r31, - r02, r12, r22, r32, - r03, r13, r23, r33 - ) - } - - @JvmStatic - fun from(matrix: Float2DArray, filler: Float) = construct4(matrix, Float2DArray::get, ::columnMajor, filler) - @JvmStatic - fun from(matrix: Float2DArray) = construct4(matrix, Float2DArray::get, ::columnMajor, 0f) - @JvmStatic - fun from(matrix: Matrix4f) = construct4(matrix, Float2DArray::get, ::columnMajor) - - @JvmStatic - fun fromTransposed(matrix: Float2DArray) = construct4(matrix, Float2DArray::get, Companion::rowMajor, 0f) - @JvmStatic - fun fromTransposed(matrix: Float2DArray, filler: Float) = construct4(matrix, Float2DArray::get, Companion::rowMajor, filler) - @JvmStatic - fun fromTransposed(matrix: Matrix4f) = construct4(matrix, Float2DArray::get, Companion::rowMajor) - - @JvmStatic - fun fromColumnMajor(buffer: FloatBuffer) = construct4(buffer, FloatBuffer::get, ::columnMajor) - @JvmStatic - fun fromColumnMajor(buffer: ByteBuffer) = construct4(buffer, ByteBuffer::getFloat, ::columnMajor) - @JvmStatic - fun fromRowMajor(buffer: FloatBuffer) = construct4(buffer, FloatBuffer::get, Companion::rowMajor) - @JvmStatic - fun fromRowMajor(buffer: ByteBuffer) = construct4(buffer, ByteBuffer::getFloat, Companion::rowMajor) - - /** - * Constructs new ortho projection matrix, with Y coordinate flipped (useful for OpenGL GUI drawing). - * - * Inversion of Y means that X 0 Y 0 will be top left position on screen (in OpenGL), not bottom left. - */ - @JvmStatic - fun ortho(left: Float, right: Float, bottom: Float, top: Float, zNear: Float, zFar: Float): Matrix4f { - return rowMajor( - r00 = 2f / (right - left), - r11 = -2f / (top - bottom), - r22 = 2f / (zFar - zNear), - r03 = -(right + left) / (right - left), - r13 = -(top + bottom) / (top - bottom) + 2f, - r23 = -(zFar + zNear) / (zFar - zNear) - ) - } - - /** - * Constructs new ortho projection matrix - */ - @JvmStatic - fun orthoDirect(left: Float, right: Float, bottom: Float, top: Float, zNear: Float, zFar: Float): Matrix4f { - return rowMajor( - r00 = 2f / (right - left), - r11 = 2f / (top - bottom), - r22 = 2f / (zFar - zNear), - r03 = -(right + left) / (right - left), - r13 = -(top + bottom) / (top - bottom), - r23 = -(zFar + zNear) / (zFar - zNear) - ) - } - - /** - * Constructs new perspective matrix - */ - @JvmStatic - fun perspective(fov: Float, zFar: Float, zNear: Float): Matrix4f { - val scale = (1.0 / (tan(Math.toRadians(fov.toDouble()) / 2.0))).toFloat() - val r = zFar - zNear - - return rowMajor( - r00 = scale, - r11 = scale, - r22 = -zFar / r, - r23 = -1f, - r32 = -zFar * zNear / r, - ) - } - - // kotlin compiler bug? it refuses to use TABLESWITCH if these are inlined - const val C00 = (0 or (0 shl 2)) - const val C01 = (0 or (1 shl 2)) - const val C02 = (0 or (2 shl 2)) - const val C03 = (0 or (3 shl 2)) - const val C10 = (1 or (0 shl 2)) - const val C11 = (1 or (1 shl 2)) - const val C12 = (1 or (2 shl 2)) - const val C13 = (1 or (3 shl 2)) - const val C20 = (2 or (0 shl 2)) - const val C21 = (2 or (1 shl 2)) - const val C22 = (2 or (2 shl 2)) - const val C23 = (2 or (3 shl 2)) - const val C30 = (3 or (0 shl 2)) - const val C31 = (3 or (1 shl 2)) - const val C32 = (3 or (2 shl 2)) - const val C33 = (3 or (3 shl 2)) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4fStack.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4fStack.kt deleted file mode 100644 index 60cbd12..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/Matrix4fStack.kt +++ /dev/null @@ -1,55 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -class Matrix4fStack { - private val stack = ArrayDeque() - - init { - stack.addLast(Matrix4f.identity()) - } - - fun clear(top: Matrix4f): Matrix4fStack { - stack.clear() - stack.addLast(top.copy()) - return this - } - - fun push(): Matrix4fStack { - stack.addLast(stack.last().copy()) - return this - } - - fun pop(): Matrix4f { - return stack.removeLast() - } - - fun last(): Matrix4f { - return stack.last() - } - - fun push(matrix: Matrix4f): Matrix4fStack { - stack.addLast(matrix.copy()) - return this - } - - fun identity() = push(Matrix4f.identity()) - fun zero() = push(Matrix4f.all(0f)) - fun all(value: Float) = push(Matrix4f.all(value)) - - inline fun with(block: Matrix4f.() -> T): T { - return try { - push() - block(last()) - } finally { - pop() - } - } - - inline fun with(matrix: Matrix4f, block: Matrix4f.() -> T): T { - return try { - push(matrix) - block(last()) - } finally { - pop() - } - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/MatrixOps.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/MatrixOps.kt deleted file mode 100644 index 56dc2dd..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/matrix/MatrixOps.kt +++ /dev/null @@ -1,518 +0,0 @@ -package ru.dbotthepony.kommons.matrix - -import ru.dbotthepony.kommons.arrays.Array2D -import ru.dbotthepony.kommons.arrays.mulMatrixComponents -import java.nio.Buffer - -private inline fun getOrElse( - get: (F, Int, Int) -> N, - input: F, - column: Int, - row: Int, - orElse: N -): N { - if (column < input.columns && row < input.rows) { - return get(input, column, row) - } else { - return orElse - } -} - -internal inline fun construct4( - from: F, - get: (F, Int, Int) -> N, - factory: ( - N, N, N, N, - N, N, N, N, - N, N, N, N, - N, N, N, N, - ) -> R, - filler: N -): R { - return factory( - getOrElse(get, from, 0, 0, filler), - getOrElse(get, from, 0, 1, filler), - getOrElse(get, from, 0, 2, filler), - getOrElse(get, from, 0, 3, filler), - getOrElse(get, from, 1, 0, filler), - getOrElse(get, from, 1, 1, filler), - getOrElse(get, from, 1, 2, filler), - getOrElse(get, from, 1, 3, filler), - getOrElse(get, from, 2, 0, filler), - getOrElse(get, from, 2, 1, filler), - getOrElse(get, from, 2, 2, filler), - getOrElse(get, from, 2, 3, filler), - getOrElse(get, from, 3, 0, filler), - getOrElse(get, from, 3, 1, filler), - getOrElse(get, from, 3, 2, filler), - getOrElse(get, from, 3, 3, filler), - ) -} - -internal inline fun construct3( - from: F, - get: (F, Int, Int) -> N, - factory: ( - N, N, N, - N, N, N, - N, N, N, - ) -> R, - filler: N -): R { - return factory( - getOrElse(get, from, 0, 0, filler), getOrElse(get, from, 0, 1, filler), getOrElse(get, from, 0, 2, filler), - getOrElse(get, from, 1, 0, filler), getOrElse(get, from, 1, 1, filler), getOrElse(get, from, 1, 2, filler), - getOrElse(get, from, 2, 0, filler), getOrElse(get, from, 2, 1, filler), getOrElse(get, from, 2, 2, filler), - ) -} - -internal inline fun construct2( - from: F, - get: (F, Int, Int) -> N, - factory: ( - N, N, - N, N, - ) -> R, - filler: N -): R { - return factory( - getOrElse(get, from, 0, 0, filler), getOrElse(get, from, 0, 1, filler), - getOrElse(get, from, 1, 0, filler), getOrElse(get, from, 1, 1, filler), - ) -} - -internal inline fun construct4( - from: F, - get: (F, Int, Int) -> N, - factory: ( - N, N, N, N, - N, N, N, N, - N, N, N, N, - N, N, N, N, - ) -> R -): R { - require(from.columns >= 4 && from.rows >= 4) { "Can't use ${from.dimensionsString} matrix to construct 4x4 matrix" } - - return factory( - get(from, 0, 0), get(from, 0, 1), get(from, 0, 2), get(from, 0, 3), - get(from, 1, 0), get(from, 1, 1), get(from, 1, 2), get(from, 1, 3), - get(from, 2, 0), get(from, 2, 1), get(from, 2, 2), get(from, 2, 3), - get(from, 3, 0), get(from, 3, 1), get(from, 3, 2), get(from, 3, 3), - ) -} - -internal inline fun construct4( - value: N, - factory: ( - N, N, N, N, - N, N, N, N, - N, N, N, N, - N, N, N, N, - ) -> R -): R { - return factory( - value, value, value, value, - value, value, value, value, - value, value, value, value, - value, value, value, value, - ) -} - -internal inline fun construct3( - from: F, - get: (F, Int, Int) -> N, - factory: ( - N, N, N, - N, N, N, - N, N, N, - ) -> R -): R { - require(from.columns >= 3 && from.rows >= 3) { "Can't use ${from.dimensionsString} matrix to construct 3x3 matrix" } - - return factory( - get(from, 0, 0), get(from, 0, 1), get(from, 0, 2), - get(from, 1, 0), get(from, 1, 1), get(from, 1, 2), - get(from, 2, 0), get(from, 2, 1), get(from, 2, 2), - ) -} - -internal inline fun construct3( - value: N, - factory: ( - N, N, N, - N, N, N, - N, N, N, - ) -> R -): R { - return factory( - value, value, value, - value, value, value, - value, value, value, - ) -} - -internal inline fun construct2( - from: F, - get: (F, Int, Int) -> N, - factory: ( - N, N, - N, N, - ) -> R -): R { - require(from.columns >= 2 && from.rows >= 2) { "Can't use ${from.dimensionsString} matrix to construct 2x2 matrix" } - - return factory( - get(from, 0, 0), get(from, 0, 1), - get(from, 1, 0), get(from, 1, 1), - ) -} - -internal inline fun construct2( - value: N, - factory: ( - N, N, - N, N, - ) -> R -): R { - return factory( - value, value, - value, value, - ) -} - -internal inline fun construct4( - from: F, - get: (F) -> N, - factory: ( - N, N, N, N, - N, N, N, N, - N, N, N, N, - N, N, N, N, - ) -> R -): R { - return factory( - get(from), get(from), get(from), get(from), - get(from), get(from), get(from), get(from), - get(from), get(from), get(from), get(from), - get(from), get(from), get(from), get(from), - ) -} - -internal inline fun construct3( - from: F, - get: (F) -> N, - factory: ( - N, N, N, - N, N, N, - N, N, N, - ) -> R -): R { - return factory( - get(from), get(from), get(from), - get(from), get(from), get(from), - get(from), get(from), get(from), - ) -} - -internal inline fun construct2( - from: F, - get: (F) -> N, - factory: ( - N, N, - N, N, - ) -> R -): R { - return factory( - get(from), get(from), - get(from), get(from), - ) -} - -internal inline fun operator4( - a: F, b: F, - get: (F, Int, Int) -> N, - operator: (N, N) -> N, - factory: ( - N, N, N, N, - N, N, N, N, - N, N, N, N, - N, N, N, N, - ) -> R -): R { - return factory( - operator(get(a, 0, 0), get(b, 0, 0)), operator(get(a, 0, 1), get(b, 0, 1)), operator(get(a, 0, 2), get(b, 0, 2)), operator(get(a, 0, 3), get(b, 0, 3)), - operator(get(a, 1, 0), get(b, 1, 0)), operator(get(a, 1, 1), get(b, 1, 1)), operator(get(a, 1, 2), get(b, 1, 2)), operator(get(a, 1, 3), get(b, 1, 3)), - operator(get(a, 2, 0), get(b, 2, 0)), operator(get(a, 2, 1), get(b, 2, 1)), operator(get(a, 2, 2), get(b, 2, 2)), operator(get(a, 2, 3), get(b, 2, 3)), - operator(get(a, 3, 0), get(b, 3, 0)), operator(get(a, 3, 1), get(b, 3, 1)), operator(get(a, 3, 2), get(b, 3, 2)), operator(get(a, 3, 3), get(b, 3, 3)), - ) -} - -internal inline fun operator4( - a: F, b: N, - get: (F, Int, Int) -> N, - operator: (N, N) -> N, - factory: ( - N, N, N, N, - N, N, N, N, - N, N, N, N, - N, N, N, N, - ) -> R -): R { - return factory( - operator(get(a, 0, 0), b), operator(get(a, 0, 1), b), operator(get(a, 0, 2), b), operator(get(a, 0, 3), b), - operator(get(a, 1, 0), b), operator(get(a, 1, 1), b), operator(get(a, 1, 2), b), operator(get(a, 1, 3), b), - operator(get(a, 2, 0), b), operator(get(a, 2, 1), b), operator(get(a, 2, 2), b), operator(get(a, 2, 3), b), - operator(get(a, 3, 0), b), operator(get(a, 3, 1), b), operator(get(a, 3, 2), b), operator(get(a, 3, 3), b), - ) -} - -internal inline fun operator3( - a: F, b: F, - get: (F, Int, Int) -> N, - operator: (N, N) -> N, - factory: ( - N, N, N, - N, N, N, - N, N, N, - ) -> R -): R { - return factory( - operator(get(a, 0, 0), get(b, 0, 0)), operator(get(a, 0, 1), get(b, 0, 1)), operator(get(a, 0, 2), get(b, 0, 2)), - operator(get(a, 1, 0), get(b, 1, 0)), operator(get(a, 1, 1), get(b, 1, 1)), operator(get(a, 1, 2), get(b, 1, 2)), - operator(get(a, 2, 0), get(b, 2, 0)), operator(get(a, 2, 1), get(b, 2, 1)), operator(get(a, 2, 2), get(b, 2, 2)), - ) -} - -internal inline fun operator3( - a: F, b: N, - get: (F, Int, Int) -> N, - operator: (N, N) -> N, - factory: ( - N, N, N, - N, N, N, - N, N, N, - ) -> R -): R { - return factory( - operator(get(a, 0, 0), b), operator(get(a, 0, 1), b), operator(get(a, 0, 2), b), - operator(get(a, 1, 0), b), operator(get(a, 1, 1), b), operator(get(a, 1, 2), b), - operator(get(a, 2, 0), b), operator(get(a, 2, 1), b), operator(get(a, 2, 2), b), - ) -} - -internal inline fun operator2( - a: F, b: F, - get: (F, Int, Int) -> N, - operator: (N, N) -> N, - factory: ( - N, N, - N, N, - ) -> R -): R { - return factory( - operator(get(a, 0, 0), get(b, 0, 0)), operator(get(a, 0, 1), get(b, 0, 1)), - operator(get(a, 1, 0), get(b, 1, 0)), operator(get(a, 1, 1), get(b, 1, 1)), - ) -} - -internal inline fun operator2( - a: F, b: N, - get: (F, Int, Int) -> N, - operator: (N, N) -> N, - factory: ( - N, N, - N, N, - ) -> R -): R { - return factory( - operator(get(a, 0, 0), b), operator(get(a, 0, 1), b), - operator(get(a, 1, 0), b), operator(get(a, 1, 1), b), - ) -} - -internal inline fun times4( - a: F, b: F, - get: (F, Int, Int) -> N, - times: (N, N) -> N, - plus: (N, N) -> N, - factory: ( - N, N, N, N, - N, N, N, N, - N, N, N, N, - N, N, N, N, - ) -> R -): R { - return factory( - mulMatrixComponents(a, b, get, times, plus, 0, 0), - mulMatrixComponents(a, b, get, times, plus, 0, 1), - mulMatrixComponents(a, b, get, times, plus, 0, 2), - mulMatrixComponents(a, b, get, times, plus, 0, 3), - mulMatrixComponents(a, b, get, times, plus, 1, 0), - mulMatrixComponents(a, b, get, times, plus, 1, 1), - mulMatrixComponents(a, b, get, times, plus, 1, 2), - mulMatrixComponents(a, b, get, times, plus, 1, 3), - mulMatrixComponents(a, b, get, times, plus, 2, 0), - mulMatrixComponents(a, b, get, times, plus, 2, 1), - mulMatrixComponents(a, b, get, times, plus, 2, 2), - mulMatrixComponents(a, b, get, times, plus, 2, 3), - mulMatrixComponents(a, b, get, times, plus, 3, 0), - mulMatrixComponents(a, b, get, times, plus, 3, 1), - mulMatrixComponents(a, b, get, times, plus, 3, 2), - mulMatrixComponents(a, b, get, times, plus, 3, 3), - ) -} - -internal inline fun times3( - a: F, b: F, - get: (F, Int, Int) -> N, - times: (N, N) -> N, - plus: (N, N) -> N, - factory: ( - N, N, N, - N, N, N, - N, N, N, - ) -> R -): R { - return factory( - mulMatrixComponents(a, b, get, times, plus, 0, 0), - mulMatrixComponents(a, b, get, times, plus, 0, 1), - mulMatrixComponents(a, b, get, times, plus, 0, 2), - mulMatrixComponents(a, b, get, times, plus, 1, 0), - mulMatrixComponents(a, b, get, times, plus, 1, 1), - mulMatrixComponents(a, b, get, times, plus, 1, 2), - mulMatrixComponents(a, b, get, times, plus, 2, 0), - mulMatrixComponents(a, b, get, times, plus, 2, 1), - mulMatrixComponents(a, b, get, times, plus, 2, 2), - ) -} - -internal inline fun times2( - a: F, b: F, - get: (F, Int, Int) -> N, - times: (N, N) -> N, - plus: (N, N) -> N, - factory: ( - N, N, - N, N, - ) -> R -): R { - return factory( - mulMatrixComponents(a, b, get, times, plus, 0, 0), mulMatrixComponents(a, b, get, times, plus, 0, 1), - mulMatrixComponents(a, b, get, times, plus, 1, 0), mulMatrixComponents(a, b, get, times, plus, 1, 1), - ) -} - -internal inline fun operator4( - a: R, b: F, - get: (F, Int, Int) -> N, - set: (R, Int, Int, N) -> Unit, - operator: (N, N) -> N, -): R { - a.requireSizeEquals(b) - set(a, 0, 0, operator(get(a, 0, 0), get(b, 0, 0))) - set(a, 0, 1, operator(get(a, 0, 1), get(b, 0, 1))) - set(a, 0, 2, operator(get(a, 0, 2), get(b, 0, 2))) - set(a, 0, 3, operator(get(a, 0, 3), get(b, 0, 3))) - set(a, 1, 0, operator(get(a, 1, 0), get(b, 1, 0))) - set(a, 1, 1, operator(get(a, 1, 1), get(b, 1, 1))) - set(a, 1, 2, operator(get(a, 1, 2), get(b, 1, 2))) - set(a, 1, 3, operator(get(a, 1, 3), get(b, 1, 3))) - set(a, 2, 0, operator(get(a, 2, 0), get(b, 2, 0))) - set(a, 2, 1, operator(get(a, 2, 1), get(b, 2, 1))) - set(a, 2, 2, operator(get(a, 2, 2), get(b, 2, 2))) - set(a, 2, 3, operator(get(a, 2, 3), get(b, 2, 3))) - set(a, 3, 0, operator(get(a, 3, 0), get(b, 3, 0))) - set(a, 3, 1, operator(get(a, 3, 1), get(b, 3, 1))) - set(a, 3, 2, operator(get(a, 3, 2), get(b, 3, 2))) - set(a, 3, 3, operator(get(a, 3, 3), get(b, 3, 3))) - return a -} - -internal inline fun operator4( - a: R, b: N, - get: (F, Int, Int) -> N, - set: (R, Int, Int, N) -> Unit, - operator: (N, N) -> N, -): R { - set(a, 0, 0, operator(get(a, 0, 0), b)) - set(a, 0, 1, operator(get(a, 0, 1), b)) - set(a, 0, 2, operator(get(a, 0, 2), b)) - set(a, 0, 3, operator(get(a, 0, 3), b)) - set(a, 1, 0, operator(get(a, 1, 0), b)) - set(a, 1, 1, operator(get(a, 1, 1), b)) - set(a, 1, 2, operator(get(a, 1, 2), b)) - set(a, 1, 3, operator(get(a, 1, 3), b)) - set(a, 2, 0, operator(get(a, 2, 0), b)) - set(a, 2, 1, operator(get(a, 2, 1), b)) - set(a, 2, 2, operator(get(a, 2, 2), b)) - set(a, 2, 3, operator(get(a, 2, 3), b)) - set(a, 3, 0, operator(get(a, 3, 0), b)) - set(a, 3, 1, operator(get(a, 3, 1), b)) - set(a, 3, 2, operator(get(a, 3, 2), b)) - set(a, 3, 3, operator(get(a, 3, 3), b)) - return a -} - -internal inline fun operator3( - a: R, b: F, - get: (F, Int, Int) -> N, - set: (R, Int, Int, N) -> Unit, - operator: (N, N) -> N, -): R { - a.requireSizeEquals(b) - set(a, 0, 0, operator(get(a, 0, 0), get(b, 0, 0))) - set(a, 0, 1, operator(get(a, 0, 1), get(b, 0, 1))) - set(a, 0, 2, operator(get(a, 0, 2), get(b, 0, 2))) - set(a, 1, 0, operator(get(a, 1, 0), get(b, 1, 0))) - set(a, 1, 1, operator(get(a, 1, 1), get(b, 1, 1))) - set(a, 1, 2, operator(get(a, 1, 2), get(b, 1, 2))) - set(a, 2, 0, operator(get(a, 2, 0), get(b, 2, 0))) - set(a, 2, 1, operator(get(a, 2, 1), get(b, 2, 1))) - set(a, 2, 2, operator(get(a, 2, 2), get(b, 2, 2))) - return a -} - -internal inline fun operator3( - a: R, b: N, - get: (F, Int, Int) -> N, - set: (R, Int, Int, N) -> Unit, - operator: (N, N) -> N, -): R { - set(a, 0, 0, operator(get(a, 0, 0), b)) - set(a, 0, 1, operator(get(a, 0, 1), b)) - set(a, 0, 2, operator(get(a, 0, 2), b)) - set(a, 1, 0, operator(get(a, 1, 0), b)) - set(a, 1, 1, operator(get(a, 1, 1), b)) - set(a, 1, 2, operator(get(a, 1, 2), b)) - set(a, 2, 0, operator(get(a, 2, 0), b)) - set(a, 2, 1, operator(get(a, 2, 1), b)) - set(a, 2, 2, operator(get(a, 2, 2), b)) - return a -} - -internal inline fun operator2( - a: R, b: F, - get: (F, Int, Int) -> N, - set: (R, Int, Int, N) -> Unit, - operator: (N, N) -> N, -): R { - a.requireSizeEquals(b) - set(a, 0, 0, operator(get(a, 0, 0), get(b, 0, 0))) - set(a, 0, 1, operator(get(a, 0, 1), get(b, 0, 1))) - set(a, 1, 0, operator(get(a, 1, 0), get(b, 1, 0))) - set(a, 1, 1, operator(get(a, 1, 1), get(b, 1, 1))) - return a -} - -internal inline fun operator2( - a: R, b: N, - get: (F, Int, Int) -> N, - set: (R, Int, Int, N) -> Unit, - operator: (N, N) -> N, -): R { - set(a, 0, 0, operator(get(a, 0, 0), b)) - set(a, 0, 1, operator(get(a, 0, 1), b)) - set(a, 1, 0, operator(get(a, 1, 0), b)) - set(a, 1, 1, operator(get(a, 1, 1), b)) - return a -} \ No newline at end of file diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/util/AABB.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/util/AABB.kt deleted file mode 100644 index fdc10d6..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/util/AABB.kt +++ /dev/null @@ -1,230 +0,0 @@ - -@file:Suppress("unused", "LiftReturnOrAssignment", "MemberVisibilityCanBePrivate") - -package ru.dbotthepony.kommons.util - -import ru.dbotthepony.kommons.math.intersectRectangles -import ru.dbotthepony.kommons.math.rectangleContainsRectangle -import ru.dbotthepony.kommons.vector.Vector2d -import kotlin.math.absoluteValue - -/** - * Axis Aligned Bounding Box, represented by two points, [mins] as lowermost corner of BB, - * and [maxs] as uppermost corner of BB - */ -data class AABB(val mins: Vector2d, val maxs: Vector2d) { - init { - require(mins.x <= maxs.x) { "mins.x ${mins.x} is more than maxs.x ${maxs.x}" } - require(mins.y <= maxs.y) { "mins.y ${mins.y} is more than maxs.y ${maxs.y}" } - } - - operator fun plus(other: AABB) = AABB(mins + other.mins, maxs + other.maxs) - operator fun minus(other: AABB) = AABB(mins - other.mins, maxs - other.maxs) - operator fun times(other: AABB) = AABB(mins * other.mins, maxs * other.maxs) - operator fun div(other: AABB) = AABB(mins / other.mins, maxs / other.maxs) - - operator fun plus(other: Vector2d) = AABB(mins + other, maxs + other) - operator fun minus(other: Vector2d) = AABB(mins - other, maxs - other) - operator fun times(other: Vector2d) = AABB(mins * other, maxs * other) - operator fun div(other: Vector2d) = AABB(mins / other, maxs / other) - - operator fun times(other: Double) = AABB(mins * other, maxs * other) - operator fun div(other: Double) = AABB(mins / other, maxs / other) - - val xSpan get() = maxs.x - mins.x - val ySpan get() = maxs.y - mins.y - val centre get() = (mins + maxs) * 0.5 - - val A get() = mins - val B get() = Vector2d(mins.x, maxs.y) - val C get() = maxs - val D get() = Vector2d(maxs.x, mins.y) - - val bottomLeft get() = A - val topLeft get() = B - val topRight get() = C - val bottomRight get() = D - - val width get() = maxs.x - mins.x - val height get() = maxs.y - mins.y - - val extents get() = Vector2d(width * 0.5, height * 0.5) - - val diameter get() = mins.distance(maxs) - val radius get() = diameter / 2.0 - - val perimeter get() = (xSpan + ySpan) * 2.0 - - fun isInside(point: IStruct2d): Boolean { - return point.component1() in mins.x .. maxs.x && point.component2() in mins.y .. maxs.y - } - - fun isInside(x: Double, y: Double): Boolean { - return x in mins.x .. maxs.x && y in mins.y .. maxs.y - } - - operator fun contains(point: IStruct2d) = isInside(point) - - /** - * Checks whenever is this AABB intersect with [other] - * - * This method consider they intersect even if only one of axis are equal - */ - fun intersect(other: AABB): Boolean { - return intersectRectangles(mins, maxs, other.mins, other.maxs) - } - - /** - * Returns whenever [other] is contained (encased) inside this AABB - */ - operator fun contains(other: AABB): Boolean { - return rectangleContainsRectangle(mins, maxs, other.mins, other.maxs) - } - - /** - * Checks whenever is this AABB intersect with [other] - * - * This method DOES NOT consider they intersect if only one of axis are equal - */ - fun intersectWeak(other: AABB): Boolean { - if (maxs.x == other.mins.x || mins.x == other.maxs.x || maxs.y == other.mins.y || mins.y == other.maxs.y) - return false - - return intersectRectangles(mins, maxs, other.mins, other.maxs) - } - - fun intersectionDepth(other: AABB): Vector2d { - val xDepth: Double - val yDepth: Double - - val thisCentre = centre - val otherCentre = other.centre - - if (thisCentre.x > otherCentre.x) { - // считаем, что мы вошли справа - xDepth = mins.x - other.maxs.x - } else { - // считаем, что мы вошли слева - xDepth = maxs.x - other.mins.x - } - - if (thisCentre.y > otherCentre.y) { - // считаем, что мы вошли сверху - yDepth = mins.y - other.maxs.y - } else { - // считаем, что мы вошли снизу - yDepth = maxs.x - other.mins.x - } - - return Vector2d(xDepth, yDepth) - } - - fun distance(other: AABB): Double { - val intersectX: Boolean - val intersectY: Boolean - - if (ySpan <= other.ySpan) - intersectY = mins.y in other.mins.y .. other.maxs.y || maxs.y in other.mins.y .. other.maxs.y - else - intersectY = other.mins.y in mins.y .. maxs.y || other.maxs.y in mins.y .. maxs.y - - if (xSpan <= other.xSpan) - intersectX = mins.x in other.mins.x .. other.maxs.x || maxs.x in other.mins.x .. other.maxs.x - else - intersectX = other.mins.x in mins.x .. maxs.x || other.maxs.x in mins.x .. maxs.x - - if (intersectY && intersectX) { - return 0.0 - } - - if (intersectX) { - return (mins.y - other.maxs.y).absoluteValue.coerceAtMost((maxs.y - other.mins.y).absoluteValue) - } else { - return (mins.x - other.maxs.x).absoluteValue.coerceAtMost((maxs.x - other.mins.x).absoluteValue) - } - } - - fun pushOutFrom(other: AABB): Vector2d { - if (!intersect(other)) - return Vector2d.ZERO - - val depth = intersectionDepth(other) - - if (depth.x.absoluteValue < depth.y.absoluteValue) { - return Vector2d(x = depth.x) - } else { - return Vector2d(y = depth.y) - } - } - - /** - * Returns AABB which contains both AABBs - */ - fun combine(other: AABB): AABB { - if (contains(other)) return this - - val minX = mins.x.coerceAtMost(other.mins.x) - val minY = mins.y.coerceAtMost(other.mins.y) - val maxX = maxs.x.coerceAtLeast(other.maxs.x) - val maxY = maxs.y.coerceAtLeast(other.maxs.y) - - return AABB(Vector2d(minX, minY), Vector2d(maxX, maxY)) - } - - /** - * Returns AABB which contains this AABB and specified point - */ - fun expand(x: Double, y: Double): AABB { - if (isInside(x, y)) - return this - - return AABB( - mins.coerceAtMost(x, y), - maxs.coerceAtLeast(x, y) - ) - } - - fun expand(value: IStruct2d) = expand(value.component1(), value.component2()) - fun padded(value: IStruct2d) = expand(value.component1(), value.component2()) - fun padded(x: Double, y: Double) = expand(x, y) - - /** - * Returns AABB which edges are expanded by [x] and [y] along their normals - */ - fun enlarge(x: Double, y: Double): AABB { - if (x == 0.0 && y == 0.0) return this - - return AABB( - Vector2d(mins.x - x, mins.y - y), - Vector2d(maxs.x + x, maxs.y + y), - ) - } - - companion object { - /** - * Rectangle with given [width] and [height] - */ - fun rectangle(pos: IStruct2d, width: Double, height: Double = width): AABB { - val (x, y) = pos - - return AABB( - Vector2d(x - width / 2.0, y - height / 2.0), - Vector2d(x + width / 2.0, y + height / 2.0), - ) - } - - /** - * Rectangle with given [width] * 2 and [height] * 2 - */ - fun withSide(pos: IStruct2d, width: Double, height: Double = width): AABB { - val (x, y) = pos - - return AABB( - Vector2d(x - width, y - height), - Vector2d(x + width, y + height), - ) - } - - @JvmField val ZERO = AABB(Vector2d.ZERO, Vector2d.ZERO) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/util/AABBi.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/util/AABBi.kt deleted file mode 100644 index b3366f9..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/util/AABBi.kt +++ /dev/null @@ -1,147 +0,0 @@ -package ru.dbotthepony.kommons.util - -import ru.dbotthepony.kommons.math.intersectRectangles -import ru.dbotthepony.kommons.math.rectangleContainsRectangle -import ru.dbotthepony.kommons.vector.Vector2d -import ru.dbotthepony.kommons.vector.Vector2i - -data class AABBi(val mins: Vector2i, val maxs: Vector2i) { - init { - require(mins.x <= maxs.x) { "mins.x ${mins.x} is more than maxs.x ${maxs.x}" } - require(mins.y <= maxs.y) { "mins.y ${mins.y} is more than maxs.y ${maxs.y}" } - } - - operator fun plus(other: AABBi) = AABBi(mins + other.mins, maxs + other.maxs) - operator fun minus(other: AABBi) = AABBi(mins - other.mins, maxs - other.maxs) - operator fun times(other: AABBi) = AABBi(mins * other.mins, maxs * other.maxs) - operator fun div(other: AABBi) = AABBi(mins / other.mins, maxs / other.maxs) - - operator fun plus(other: Vector2i) = AABBi(mins + other, maxs + other) - operator fun minus(other: Vector2i) = AABBi(mins - other, maxs - other) - operator fun times(other: Vector2i) = AABBi(mins * other, maxs * other) - operator fun div(other: Vector2i) = AABBi(mins / other, maxs / other) - - operator fun times(other: Int) = AABBi(mins * other, maxs * other) - operator fun div(other: Int) = AABBi(mins / other, maxs / other) - - val xSpan get() = maxs.x - mins.x - val ySpan get() = maxs.y - mins.y - val centre get() = (mins.toDoubleVector() + maxs.toDoubleVector()) * 0.5 - - val A get() = mins - val B get() = Vector2i(mins.x, maxs.y) - val C get() = maxs - val D get() = Vector2i(maxs.x, mins.y) - - val bottomLeft get() = A - val topLeft get() = B - val topRight get() = C - val bottomRight get() = D - - val width get() = (maxs.x - mins.x) / 2 - val height get() = (maxs.y - mins.y) / 2 - - val diameter get() = mins.distance(maxs) - val radius get() = diameter / 2.0 - - val perimeter get() = (xSpan + ySpan) * 2 - - fun isInside(point: IStruct2i): Boolean { - return point.component1() in mins.x .. maxs.x && point.component2() in mins.y .. maxs.y - } - - fun isInside(x: Int, y: Int): Boolean { - return x in mins.x .. maxs.x && y in mins.y .. maxs.y - } - - operator fun contains(point: IStruct2i) = isInside(point) - - /** - * Checks whenever is this AABBi intersect with [other] - * - * This method consider they intersect even if only one of axis are equal - */ - fun intersect(other: AABBi): Boolean { - return intersectRectangles(mins, maxs, other.mins, other.maxs) - } - - /** - * Returns whenever [other] is contained (encased) inside this AABBi - */ - operator fun contains(other: AABBi): Boolean { - return rectangleContainsRectangle(mins, maxs, other.mins, other.maxs) - } - - /** - * Checks whenever is this AABB intersect with [other] - * - * This method DOES NOT consider they intersect if only one of axis are equal - */ - fun intersectWeak(other: AABBi): Boolean { - if (maxs.x == other.mins.x || mins.x == other.maxs.x || maxs.y == other.mins.y || mins.y == other.maxs.y) - return false - - return intersectRectangles(mins, maxs, other.mins, other.maxs) - } - - fun toDoubleAABB() = AABB(mins.toDoubleVector(), maxs.toDoubleVector()) - - /** - * Returns AABB which contains this AABB and specified point - */ - fun expand(x: Int, y: Int): AABBi { - if (isInside(x, y)) - return this - - return AABBi( - mins.coerceAtMost(x, y), - maxs.coerceAtLeast(x, y) - ) - } - - fun padded(x: Int, y: Int) = expand(x, y) - fun padded(value: IStruct2i) = expand(value.component1(), value.component2()) - fun expand(value: IStruct2i) = expand(value.component1(), value.component2()) - - /** - * Returns AABB which contains both AABBs - */ - fun combine(other: AABBi): AABBi { - if (contains(other)) return this - - val minX = mins.x.coerceAtMost(other.mins.x) - val minY = mins.y.coerceAtMost(other.mins.y) - val maxX = maxs.x.coerceAtLeast(other.maxs.x) - val maxY = maxs.y.coerceAtLeast(other.maxs.y) - - return AABBi(Vector2i(minX, minY), Vector2i(maxX, maxY)) - } - - companion object { - /** - * Rectangle with given [width] and [height] - */ - fun rectangle(pos: IStruct2i, width: Int, height: Int = width): AABBi { - val (x, y) = pos - - return AABBi( - Vector2i(x - width / 2, y - height / 2), - Vector2i(x + width / 2, y + height / 2), - ) - } - - /** - * Rectangle with given [width] * 2 and [height] * 2 - */ - fun withSide(pos: IStruct2i, width: Int, height: Int = width): AABBi { - val (x, y) = pos - - return AABBi( - Vector2i(x - width, y - height), - Vector2i(x + width, y + height), - ) - } - - @JvmField val ZERO = AABBi(Vector2i.ZERO, Vector2i.ZERO) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/ExtraOperators.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/ExtraOperators.kt deleted file mode 100644 index dc4c30e..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/ExtraOperators.kt +++ /dev/null @@ -1,58 +0,0 @@ -package ru.dbotthepony.kommons.vector - -operator fun Int.times(value: Vector2i) = value.times(this) -operator fun Int.div(value: Vector2i) = Vector2i(this / value.x, this / value.y) -operator fun Int.times(value: Vector2d) = value.times(this) -operator fun Int.div(value: Vector2d) = Vector2d(this / value.x, this / value.y) -operator fun Int.times(value: Vector2f) = value.times(this) -operator fun Int.div(value: Vector2f) = Vector2f(this / value.x, this / value.y) -operator fun Int.times(value: Vector3i) = value.times(this) -operator fun Int.div(value: Vector3i) = Vector3i(this / value.x, this / value.y, this / value.z) -operator fun Int.times(value: Vector3d) = value.times(this) -operator fun Int.div(value: Vector3d) = Vector3d(this / value.x, this / value.y, this / value.z) -operator fun Int.times(value: Vector3f) = value.times(this) -operator fun Int.div(value: Vector3f) = Vector3f(this / value.x, this / value.y, this / value.z) -operator fun Int.times(value: Vector4i) = value.times(this) -operator fun Int.div(value: Vector4i) = Vector4i(this / value.x, this / value.y, this / value.z) -operator fun Int.times(value: Vector4d) = value.times(this) -operator fun Int.div(value: Vector4d) = Vector4d(this / value.x, this / value.y, this / value.z) -operator fun Int.times(value: Vector4f) = value.times(this) -operator fun Int.div(value: Vector4f) = Vector4f(this / value.x, this / value.y, this / value.z) - -operator fun Float.times(value: Vector2i) = value.times(this) -operator fun Float.div(value: Vector2i) = Vector2f(this / value.x, this / value.y) -operator fun Float.times(value: Vector2d) = value.times(this) -operator fun Float.div(value: Vector2d) = Vector2d(this / value.x, this / value.y) -operator fun Float.times(value: Vector2f) = value.times(this) -operator fun Float.div(value: Vector2f) = Vector2f(this / value.x, this / value.y) -operator fun Float.times(value: Vector3i) = value.times(this) -operator fun Float.div(value: Vector3i) = Vector3f(this / value.x, this / value.y, this / value.z) -operator fun Float.times(value: Vector3d) = value.times(this) -operator fun Float.div(value: Vector3d) = Vector3d(this / value.x, this / value.y, this / value.z) -operator fun Float.times(value: Vector3f) = value.times(this) -operator fun Float.div(value: Vector3f) = Vector3f(this / value.x, this / value.y, this / value.z) -operator fun Float.times(value: Vector4i) = value.times(this) -operator fun Float.div(value: Vector4i) = Vector4f(this / value.x, this / value.y, this / value.z) -operator fun Float.times(value: Vector4d) = value.times(this) -operator fun Float.div(value: Vector4d) = Vector4d(this / value.x, this / value.y, this / value.z) -operator fun Float.times(value: Vector4f) = value.times(this) -operator fun Float.div(value: Vector4f) = Vector4f(this / value.x, this / value.y, this / value.z) - -operator fun Double.times(value: Vector2i) = value.times(this) -operator fun Double.div(value: Vector2i) = Vector2d(this / value.x, this / value.y) -operator fun Double.times(value: Vector2d) = value.times(this) -operator fun Double.div(value: Vector2d) = Vector2d(this / value.x, this / value.y) -operator fun Double.times(value: Vector2f) = value.times(this) -operator fun Double.div(value: Vector2f) = Vector2d(this / value.x, this / value.y) -operator fun Double.times(value: Vector3i) = value.times(this) -operator fun Double.div(value: Vector3i) = Vector3d(this / value.x, this / value.y, this / value.z) -operator fun Double.times(value: Vector3d) = value.times(this) -operator fun Double.div(value: Vector3d) = Vector3d(this / value.x, this / value.y, this / value.z) -operator fun Double.times(value: Vector3f) = value.times(this) -operator fun Double.div(value: Vector3f) = Vector3d(this / value.x, this / value.y, this / value.z) -operator fun Double.times(value: Vector4i) = value.times(this) -operator fun Double.div(value: Vector4i) = Vector4d(this / value.x, this / value.y, this / value.z) -operator fun Double.times(value: Vector4d) = value.times(this) -operator fun Double.div(value: Vector4d) = Vector4d(this / value.x, this / value.y, this / value.z) -operator fun Double.times(value: Vector4f) = value.times(this) -operator fun Double.div(value: Vector4f) = Vector4d(this / value.x, this / value.y, this / value.z) diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector.kt deleted file mode 100644 index 0ad759e..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector.kt +++ /dev/null @@ -1,119 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import kotlin.math.sqrt - -/** - * Vectors are exclusively immutable - */ -sealed class Vector { - val length: Double get() = sqrt(lengthSquared) - val isValid: Boolean get() = isFinite && !isNaN - - abstract val isFinite: Boolean - abstract val isNaN: Boolean - abstract val lengthSquared: Double - - /** - * @throws IllegalArgumentException if matrix is not finite - */ - inline fun requireIsFinite(lambda: () -> Any) { - if (!isFinite) { - throw IllegalArgumentException(lambda.invoke().toString()) - } - } - - /** - * @throws IllegalArgumentException if matrix is not finite - */ - fun requireIsFinite() { - if (!isFinite) { - throw IllegalArgumentException("Matrix is not finite") - } - } - - /** - * @throws IllegalStateException if matrix is not finite - */ - inline fun checkIsFinite(lambda: () -> Any) { - if (!isFinite) { - throw IllegalStateException(lambda.invoke().toString()) - } - } - - /** - * @throws IllegalStateException if matrix is not finite - */ - fun checkIsFinite() { - if (!isFinite) { - throw IllegalStateException("Matrix is not finite") - } - } - - /** - * @throws IllegalArgumentException if vector has NaN component - */ - inline fun requireNotNaN(lambda: () -> Any) { - if (isNaN) { - throw IllegalArgumentException(lambda.invoke().toString()) - } - } - - /** - * @throws IllegalArgumentException if matrix has NaN component - */ - fun requireNotNaN() { - if (isNaN) { - throw IllegalArgumentException("Matrix has NaN component") - } - } - - /** - * @throws IllegalStateException if matrix has NaN component - */ - inline fun checkNotNaN(lambda: () -> Any) { - if (!isFinite) { - throw IllegalStateException(lambda.invoke().toString()) - } - } - - /** - * @throws IllegalStateException if matrix has NaN component - */ - fun checkNotNaN() { - if (!isFinite) { - throw IllegalStateException("Matrix has NaN component") - } - } - - /** - * @throws IllegalArgumentException if matrix has NaN or infinite component - */ - fun requireIsValid() { - requireIsFinite() - requireNotNaN() - } - - /** - * @throws IllegalStateException if matrix has NaN or infinite component - */ - fun checkIsValid() { - requireIsFinite() - requireNotNaN() - } - - /** - * @throws IllegalArgumentException if matrix has NaN or infinite component - */ - inline fun requireIsValid(lambda: () -> Any) { - requireIsFinite(lambda) - requireNotNaN(lambda) - } - - /** - * @throws IllegalStateException if matrix has NaN or infinite component - */ - inline fun checkIsValid(lambda: () -> Any) { - requireIsFinite(lambda) - requireNotNaN(lambda) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2d.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2d.kt deleted file mode 100644 index 9a0e8a8..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2d.kt +++ /dev/null @@ -1,247 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import ru.dbotthepony.kommons.matrix.Matrix2d -import ru.dbotthepony.kommons.matrix.Matrix3d -import ru.dbotthepony.kommons.matrix.Matrix4d -import ru.dbotthepony.kommons.matrix.Matrix4dStack -import kotlin.math.absoluteValue -import kotlin.math.acos -import kotlin.math.atan2 -import kotlin.math.cos -import kotlin.math.sin -import kotlin.math.sqrt - -data class Vector2d( - val x: Double = 0.0, - val y: Double = 0.0, -) : IStruct2d, Vector() { - constructor(value: IStruct2d) : this(value.component1(), value.component2()) - constructor(value: Vector2d) : this(value.x, value.y) - - override val lengthSquared: Double - get() = x * x + y * y - - override val isFinite: Boolean - get() = x.isFinite() && y.isFinite() - override val isNaN: Boolean - get() = x.isNaN() || y.isNaN() - - val unitVector: Vector2d get() { - var length = lengthSquared - if (length == 0.0 || length == 1.0) return this - length = sqrt(length) - return Vector2d(x / length, y / length) - } - - val absoluteValue: Vector2d get() { - val x = x.absoluteValue - val y = y.absoluteValue - if (x != this.x || y != this.y) return Vector2d(x, y) - return this - } - - val r get() = x - val g get() = y - - val s get() = x - val t get() = y - - fun plus(x: Double = 0.0, y: Double = 0.0) = Vector2d(this.x + x, this.y + y) - fun minus(x: Double = 0.0, y: Double = 0.0) = Vector2d(this.x - x, this.y - y) - fun times(x: Double = 1.0, y: Double = 1.0) = Vector2d(this.x * x, this.y * y) - fun div(x: Double = 1.0, y: Double = 1.0) = Vector2d(this.x / x, this.y / y) - - operator fun plus(value: IStruct2d): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2d): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value) - operator fun minus(value: Double) = minus(value, value) - operator fun times(value: Double) = times(value, value) - operator fun div(value: Double) = div(value, value) - - fun plus(x: Int = 0, y: Int = 0) = Vector2d(this.x + x, this.y + y) - fun minus(x: Int = 0, y: Int = 0) = Vector2d(this.x - x, this.y - y) - fun times(x: Int = 1, y: Int = 1) = Vector2d(this.x * x, this.y * y) - fun div(x: Int = 1, y: Int = 1) = Vector2d(this.x / x, this.y / y) - - operator fun plus(value: IStruct2i): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2i): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value) - operator fun minus(value: Int) = minus(value, value) - operator fun times(value: Int) = times(value, value) - operator fun div(value: Int) = div(value, value) - - fun plus(x: Float = 0f, y: Float = 0f) = Vector2d(this.x + x, this.y + y) - fun minus(x: Float = 0f, y: Float = 0f) = Vector2d(this.x - x, this.y - y) - fun times(x: Float = 1f, y: Float = 1f) = Vector2d(this.x * x, this.y * y) - fun div(x: Float = 1f, y: Float = 1f) = Vector2d(this.x / x, this.y / y) - - operator fun plus(value: IStruct2f): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2f): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value) - operator fun minus(value: Float) = minus(value, value) - operator fun times(value: Float) = times(value, value) - operator fun div(value: Float) = div(value, value) - - operator fun unaryMinus(): Vector2d = Vector2d(-x, -y) - - override fun equals(other: Any?): Boolean { - return other is Vector2d && x == other.x && y == other.y - } - - override fun hashCode(): Int { - var x = x.hashCode().rotateLeft(16) xor y.hashCode() - // avalanche bits using murmur3 hash - x = x xor (x ushr 16) - x *= -0x7a143595 - x = x xor (x ushr 13) - x *= -0x3d4d51cb - x = x xor (x ushr 16) - return x - } - - override fun toString(): String { - return "[$x, $y]" - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2d): Double { - return x * other.component2() - other.component1() * y - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2f): Double { - return x * other.component2() - other.component1() * y - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2i): Double { - return x * other.component2() - other.component1() * y - } - - fun dot(x: Double, y: Double) = this.x * x + this.y * y - fun dot(value: IStruct2d): Double { val (x, y) = value; return dot(x, y) } - fun dot(value: Vector2d): Double { val (x, y) = value; return dot(x, y) } - - fun distanceSquared(x: Double, y: Double): Double { - val dx = (this.x - x).toDouble() - val dy = (this.y - y).toDouble() - return dx * dx + dy * dy - } - - fun distanceSquared(value: IStruct2d): Double { val (x, y) = value; return distanceSquared(x, y) } - fun distanceSquared(value: Vector2d): Double { val (x, y) = value; return distanceSquared(x, y) } - fun distance(x: Double, y: Double) = sqrt(distanceSquared(x, y)) - fun distance(value: IStruct2d): Double { val (x, y) = value; return sqrt(distanceSquared(x, y)) } - fun distance(value: Vector2d): Double { val (x, y) = value; return sqrt(distanceSquared(x, y)) } - - fun coerceAtLeast(x: Double, y: Double) = Vector2d(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y)) - fun coerceAtMost(x: Double, y: Double) = Vector2d(this.x.coerceAtMost(x), this.y.coerceAtMost(y)) - - fun coerceIn(minimum: Vector2d, maximum: Vector2d) = Vector2d( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y)) - - fun coerceIn(minimum: IStruct2d, maximum: IStruct2d) = Vector2d( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2())) - - fun coerceAtLeast(value: IStruct2d): Vector2d { val (x, y) = value; return coerceAtLeast(x, y) } - fun coerceAtMost(value: IStruct2d): Vector2d { val (x, y) = value; return coerceAtMost(x, y) } - fun coerceAtLeast(value: Vector2d): Vector2d { val (x, y) = value; return coerceAtLeast(x, y) } - fun coerceAtMost(value: Vector2d): Vector2d { val (x, y) = value; return coerceAtMost(x, y) } - - fun rotate(angle: Double): Vector2d { - val s = sin(angle) - val c = cos(angle) - - return Vector2d(x * c - s * y, s * x + c * y) - } - - fun toAngle(zeroAngle: Vector2d): Double { - val dot = unitVector.dot(zeroAngle.unitVector) - - return if (y > 0.0) { - acos(dot) - } else { - -acos(dot) - } - } - - fun toAngle(zeroAngle: IStruct2d): Double { - return toAngle(Vector2d(zeroAngle)) - } - - fun toAngle(): Double { - return atan2(y, x) - } - - operator fun times(value: Matrix4d): Vector2d { - return Vector2d( - x * value.c00 + y * value.c10 + value.c30, - x * value.c01 + y * value.c11 + value.c31, - ) - } - - operator fun times(value: Matrix3d): Vector2d { - return Vector2d( - x * value.c00 + y * value.c10 + value.c20, - x * value.c01 + y * value.c11 + value.c21, - ) - } - - operator fun times(value: Matrix2d): Vector2d { - return Vector2d( - x * value.c00 + y * value.c10, - x * value.c01 + y * value.c11, - ) - } - - operator fun times(value: Matrix4dStack) = times(value.last()) - - fun toDoubleVector() = this - fun toFloatVector() = Vector2f(x.toFloat(), y.toFloat()) - - companion object { - @JvmField val ZERO = Vector2d() - @JvmField val POSITIVE_X = Vector2d(x = 1.0) - @JvmField val NEGATIVE_X = Vector2d(x = -1.0) - @JvmField val POSITIVE_Y = Vector2d(y = 1.0) - @JvmField val NEGATIVE_Y = Vector2d(y = -1.0) - - @JvmField val POSITIVE_XY = Vector2d(1.0, 1.0) - @JvmField val NEGATIVE_XY = Vector2d(-1.0, -1.0) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2f.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2f.kt deleted file mode 100644 index 57dccbc..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2f.kt +++ /dev/null @@ -1,247 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import ru.dbotthepony.kommons.matrix.Matrix2f -import ru.dbotthepony.kommons.matrix.Matrix3f -import ru.dbotthepony.kommons.matrix.Matrix4f -import ru.dbotthepony.kommons.matrix.Matrix4fStack -import kotlin.math.absoluteValue -import kotlin.math.acos -import kotlin.math.atan2 -import kotlin.math.cos -import kotlin.math.sin -import kotlin.math.sqrt - -data class Vector2f( - val x: Float = 0f, - val y: Float = 0f, -) : IStruct2f, Vector() { - constructor(value: IStruct2f) : this(value.component1(), value.component2()) - constructor(value: Vector2f) : this(value.x, value.y) - - override val lengthSquared: Double - get() = x.toDouble() * x + y.toDouble() * y - - override val isFinite: Boolean - get() = x.isFinite() && y.isFinite() - override val isNaN: Boolean - get() = x.isNaN() || y.isNaN() - - val unitVector: Vector2f get() { - var length = lengthSquared.toFloat() - if (length == 0f || length == 1f) return this - length = sqrt(length) - return Vector2f(x / length, y / length) - } - - val absoluteValue: Vector2f get() { - val x = x.absoluteValue - val y = y.absoluteValue - if (x != this.x || y != this.y) return Vector2f(x, y) - return this - } - - val r get() = x - val g get() = y - - val s get() = x - val t get() = y - - fun plus(x: Float = 0f, y: Float = 0f) = Vector2f(this.x + x, this.y + y) - fun minus(x: Float = 0f, y: Float = 0f) = Vector2f(this.x - x, this.y - y) - fun times(x: Float = 1f, y: Float = 1f) = Vector2f(this.x * x, this.y * y) - fun div(x: Float = 1f, y: Float = 1f) = Vector2f(this.x / x, this.y / y) - - operator fun plus(value: IStruct2f): Vector2f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector2f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector2f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector2f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2f): Vector2f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector2f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector2f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector2f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value) - operator fun minus(value: Float) = minus(value, value) - operator fun times(value: Float) = times(value, value) - operator fun div(value: Float) = div(value, value) - - fun plus(x: Int = 0, y: Int = 0) = Vector2f(this.x + x, this.y + y) - fun minus(x: Int = 0, y: Int = 0) = Vector2f(this.x - x, this.y - y) - fun times(x: Int = 1, y: Int = 1) = Vector2f(this.x * x, this.y * y) - fun div(x: Int = 1, y: Int = 1) = Vector2f(this.x / x, this.y / y) - - operator fun plus(value: IStruct2i): Vector2f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector2f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector2f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector2f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2i): Vector2f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector2f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector2f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector2f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value) - operator fun minus(value: Int) = minus(value, value) - operator fun times(value: Int) = times(value, value) - operator fun div(value: Int) = div(value, value) - - fun plus(x: Double = 0.0, y: Double = 0.0) = Vector2d(this.x + x, this.y + y) - fun minus(x: Double = 0.0, y: Double = 0.0) = Vector2d(this.x - x, this.y - y) - fun times(x: Double = 1.0, y: Double = 1.0) = Vector2d(this.x * x, this.y * y) - fun div(x: Double = 1.0, y: Double = 1.0) = Vector2d(this.x / x, this.y / y) - - operator fun plus(value: IStruct2d): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2d): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value) - operator fun minus(value: Double) = minus(value, value) - operator fun times(value: Double) = times(value, value) - operator fun div(value: Double) = div(value, value) - - operator fun unaryMinus(): Vector2f = Vector2f(-x, -y) - - override fun equals(other: Any?): Boolean { - return other is Vector2f && x == other.x && y == other.y - } - - override fun hashCode(): Int { - var x = x.hashCode().rotateLeft(16) xor y.hashCode() - // avalanche bits using murmur3 hash - x = x xor (x ushr 16) - x *= -0x7a143595 - x = x xor (x ushr 13) - x *= -0x3d4d51cb - x = x xor (x ushr 16) - return x - } - - override fun toString(): String { - return "[$x, $y]" - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2f): Float { - return x * other.component2() - other.component1() * y - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2i): Float { - return x * other.component2() - other.component1() * y - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2d): Double { - return x * other.component2() - other.component1() * y - } - - fun dot(x: Float, y: Float) = this.x * x + this.y * y - fun dot(value: IStruct2f): Float { val (x, y) = value; return dot(x, y) } - fun dot(value: Vector2f): Float { val (x, y) = value; return dot(x, y) } - - fun distanceSquared(x: Float, y: Float): Double { - val dx = (this.x - x).toDouble() - val dy = (this.y - y).toDouble() - return dx * dx + dy * dy - } - - fun distanceSquared(value: IStruct2f): Double { val (x, y) = value; return distanceSquared(x, y) } - fun distanceSquared(value: Vector2f): Double { val (x, y) = value; return distanceSquared(x, y) } - fun distance(x: Float, y: Float) = sqrt(distanceSquared(x, y)) - fun distance(value: IStruct2f): Double { val (x, y) = value; return sqrt(distanceSquared(x, y)) } - fun distance(value: Vector2f): Double { val (x, y) = value; return sqrt(distanceSquared(x, y)) } - - fun coerceAtLeast(x: Float, y: Float) = Vector2f(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y)) - fun coerceAtMost(x: Float, y: Float) = Vector2f(this.x.coerceAtMost(x), this.y.coerceAtMost(y)) - - fun coerceIn(minimum: Vector2f, maximum: Vector2f) = Vector2f( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y)) - - fun coerceIn(minimum: IStruct2f, maximum: IStruct2f) = Vector2f( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2())) - - fun coerceAtLeast(value: IStruct2f): Vector2f { val (x, y) = value; return coerceAtLeast(x, y) } - fun coerceAtMost(value: IStruct2f): Vector2f { val (x, y) = value; return coerceAtMost(x, y) } - fun coerceAtLeast(value: Vector2f): Vector2f { val (x, y) = value; return coerceAtLeast(x, y) } - fun coerceAtMost(value: Vector2f): Vector2f { val (x, y) = value; return coerceAtMost(x, y) } - - fun rotate(angle: Float): Vector2f { - val s = sin(angle) - val c = cos(angle) - - return Vector2f(x * c - s * y, s * x + c * y) - } - - fun toAngle(zeroAngle: Vector2f): Float { - val dot = unitVector.dot(zeroAngle.unitVector) - - return if (y > 0.0) { - acos(dot) - } else { - -acos(dot) - } - } - - fun toAngle(zeroAngle: IStruct2f): Float { - return toAngle(Vector2f(zeroAngle)) - } - - fun toAngle(): Float { - return atan2(y, x) - } - - operator fun times(value: Matrix4f): Vector2f { - return Vector2f( - x * value.c00 + y * value.c10 + value.c30, - x * value.c01 + y * value.c11 + value.c31, - ) - } - - operator fun times(value: Matrix3f): Vector2f { - return Vector2f( - x * value.c00 + y * value.c10 + value.c20, - x * value.c01 + y * value.c11 + value.c21, - ) - } - - operator fun times(value: Matrix2f): Vector2f { - return Vector2f( - x * value.c00 + y * value.c10, - x * value.c01 + y * value.c11, - ) - } - - operator fun times(value: Matrix4fStack) = times(value.last()) - - fun toDoubleVector() = Vector2d(x.toDouble(), y.toDouble()) - fun toFloatVector() = this - - companion object { - @JvmField val ZERO = Vector2f() - @JvmField val POSITIVE_X = Vector2f(x = 1.0f) - @JvmField val NEGATIVE_X = Vector2f(x = -1.0f) - @JvmField val POSITIVE_Y = Vector2f(y = 1.0f) - @JvmField val NEGATIVE_Y = Vector2f(y = -1.0f) - - @JvmField val POSITIVE_XY = Vector2f(1.0f, 1.0f) - @JvmField val NEGATIVE_XY = Vector2f(-1.0f, -1.0f) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2i.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2i.kt deleted file mode 100644 index ae00bb6..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector2i.kt +++ /dev/null @@ -1,176 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import kotlin.math.sqrt - -data class Vector2i( - val x: Int = 0, - val y: Int = 0, -) : IStruct2i, Vector() { - constructor(value: IStruct2i) : this(value.component1(), value.component2()) - constructor(value: Vector2i) : this(value.x, value.y) - - override val lengthSquared: Double - get() = x.toDouble() * x + y.toDouble() * y - - override val isFinite: Boolean - get() = true - override val isNaN: Boolean - get() = false - - val r get() = x - val g get() = y - - val s get() = x - val t get() = y - - fun plus(x: Int = 0, y: Int = 0) = Vector2i(this.x + x, this.y + y) - fun minus(x: Int = 0, y: Int = 0) = Vector2i(this.x - x, this.y - y) - fun times(x: Int = 1, y: Int = 1) = Vector2i(this.x * x, this.y * y) - fun div(x: Int = 1, y: Int = 1) = Vector2i(this.x / x, this.y / y) - - operator fun plus(value: IStruct2i): Vector2i { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector2i { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector2i { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector2i { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2i): Vector2i { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector2i { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector2i { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector2i { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value) - operator fun minus(value: Int) = minus(value, value) - operator fun times(value: Int) = times(value, value) - operator fun div(value: Int) = div(value, value) - - fun plus(x: Double = 0.0, y: Double = 0.0) = Vector2d(this.x + x, this.y + y) - fun minus(x: Double = 0.0, y: Double = 0.0) = Vector2d(this.x - x, this.y - y) - fun times(x: Double = 1.0, y: Double = 1.0) = Vector2d(this.x * x, this.y * y) - fun div(x: Double = 1.0, y: Double = 1.0) = Vector2d(this.x / x, this.y / y) - - operator fun plus(value: IStruct2d): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2d): Vector2d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector2d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector2d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector2d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value) - operator fun minus(value: Double) = minus(value, value) - operator fun times(value: Double) = times(value, value) - operator fun div(value: Double) = div(value, value) - - fun plus(x: Float = 0f, y: Float = 0f) = Vector2f(this.x + x, this.y + y) - fun minus(x: Float = 0f, y: Float = 0f) = Vector2f(this.x - x, this.y - y) - fun times(x: Float = 1f, y: Float = 1f) = Vector2f(this.x * x, this.y * y) - fun div(x: Float = 1f, y: Float = 1f) = Vector2f(this.x / x, this.y / y) - - operator fun plus(value: IStruct2f): Vector2f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector2f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector2f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector2f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector2f): Vector2f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector2f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector2f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector2f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value) - operator fun minus(value: Float) = minus(value, value) - operator fun times(value: Float) = times(value, value) - operator fun div(value: Float) = div(value, value) - - operator fun unaryMinus(): Vector2i = Vector2i(-x, -y) - - override fun equals(other: Any?): Boolean { - return other is Vector2i && x == other.x && y == other.y - } - - override fun hashCode(): Int { - var x = x.rotateLeft(16) xor y - // avalanche bits using murmur3 hash - x = x xor (x ushr 16) - x *= -0x7a143595 - x = x xor (x ushr 13) - x *= -0x3d4d51cb - x = x xor (x ushr 16) - return x - } - - override fun toString(): String { - return "[$x, $y]" - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2f): Float { - return x * other.component2() - other.component1() * y - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2i): Int { - return x * other.component2() - other.component1() * y - } - - /** - * 2D vector cross product (Z coordinate) - */ - fun cross(other: IStruct2d): Double { - return x * other.component2() - other.component1() * y - } - - fun dot(x: Int, y: Int) = this.x * x + this.y * y - fun dot(value: IStruct2i): Int { val (x, y) = value; return dot(x, y) } - fun dot(value: Vector2i): Int { val (x, y) = value; return dot(x, y) } - - fun distanceSquared(x: Int, y: Int): Double { - val dx = (this.x - x).toDouble() - val dy = (this.y - y).toDouble() - return dx * dx + dy * dy - } - - fun distanceSquared(value: IStruct2i): Double { val (x, y) = value; return distanceSquared(x, y) } - fun distanceSquared(value: Vector2i): Double { val (x, y) = value; return distanceSquared(x, y) } - fun distance(x: Int, y: Int) = sqrt(distanceSquared(x, y)) - fun distance(value: IStruct2i): Double { val (x, y) = value; return sqrt(distanceSquared(x, y)) } - fun distance(value: Vector2i): Double { val (x, y) = value; return sqrt(distanceSquared(x, y)) } - - fun coerceAtLeast(x: Int, y: Int) = Vector2i(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y)) - fun coerceAtMost(x: Int, y: Int) = Vector2i(this.x.coerceAtMost(x), this.y.coerceAtMost(y)) - - fun coerceIn(minimum: Vector2i, maximum: Vector2i) = Vector2i( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y)) - - fun coerceIn(minimum: IStruct2i, maximum: IStruct2i) = Vector2i( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2())) - - fun coerceAtLeast(value: IStruct2i): Vector2i { val (x, y) = value; return coerceAtLeast(x, y) } - fun coerceAtMost(value: IStruct2i): Vector2i { val (x, y) = value; return coerceAtMost(x, y) } - fun coerceAtLeast(value: Vector2i): Vector2i { val (x, y) = value; return coerceAtLeast(x, y) } - fun coerceAtMost(value: Vector2i): Vector2i { val (x, y) = value; return coerceAtMost(x, y) } - - fun toDoubleVector() = Vector2d(x.toDouble(), y.toDouble()) - fun toFloatVector() = Vector2f(x.toFloat(), y.toFloat()) - - companion object { - @JvmField val ZERO = Vector2i() - @JvmField val POSITIVE_X = Vector2i(x = 1) - @JvmField val NEGATIVE_X = Vector2i(x = -1) - @JvmField val POSITIVE_Y = Vector2i(y = 1) - @JvmField val NEGATIVE_Y = Vector2i(y = -1) - - @JvmField val POSITIVE_XY = Vector2i(1, 1) - @JvmField val NEGATIVE_XY = Vector2i(-1, -1) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3d.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3d.kt deleted file mode 100644 index 21df5e6..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3d.kt +++ /dev/null @@ -1,227 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import ru.dbotthepony.kommons.util.IStruct3d -import ru.dbotthepony.kommons.util.IStruct3f -import ru.dbotthepony.kommons.util.IStruct3i -import ru.dbotthepony.kommons.matrix.Matrix3d -import ru.dbotthepony.kommons.matrix.Matrix4d -import ru.dbotthepony.kommons.matrix.Matrix4dStack -import kotlin.math.absoluteValue -import kotlin.math.sqrt - -data class Vector3d( - val x: Double = 0.0, - val y: Double = 0.0, - val z: Double = 0.0, -) : IStruct3d, Vector() { - constructor(value: IStruct2d) : this(value.component1(), value.component2()) - constructor(value: Vector2d) : this(value.x, value.y) - constructor(value: IStruct2d, z: Double) : this(value.component1(), value.component2(), z) - constructor(value: Vector2d, z: Double) : this(value.x, value.y, z) - constructor(value: IStruct3d) : this(value.component1(), value.component2(), value.component3()) - constructor(value: Vector3d) : this(value.x, value.y, value.z) - - override val lengthSquared: Double - get() = x * x + y * y + z * z - - override val isFinite: Boolean - get() = x.isFinite() && y.isFinite() && z.isFinite() - override val isNaN: Boolean - get() = x.isNaN() || y.isNaN() || z.isNaN() - - val unitVector: Vector3d get() { - var length = lengthSquared - if (length == 0.0 || length == 1.0) return this - length = sqrt(length) - return Vector3d(x / length, y / length, z / length) - } - - val absoluteValue: Vector3d get() { - val x = x.absoluteValue - val y = y.absoluteValue - val z = z.absoluteValue - if (x != this.x || y != this.y || z != this.z) return Vector3d(x, y, z) - return this - } - - val r get() = x - val g get() = y - val b get() = z - - val s get() = x - val t get() = y - val p get() = z - - fun plus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0) = Vector3d(this.x + x, this.y + y, this.z + z) - fun minus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0) = Vector3d(this.x - x, this.y - y, this.z - z) - fun times(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0) = Vector3d(this.x * x, this.y * y, this.z * z) - fun div(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0) = Vector3d(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3d): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3d): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3d): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3d): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2d): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3d): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3d): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3d): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3d): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2d): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value, value) - operator fun minus(value: Double) = minus(value, value, value) - operator fun times(value: Double) = times(value, value, value) - operator fun div(value: Double) = div(value, value, value) - - fun plus(x: Int = 0, y: Int = 0, z: Int = 0) = Vector3d(this.x + x, this.y + y, this.z + z) - fun minus(x: Int = 0, y: Int = 0, z: Int = 0) = Vector3d(this.x - x, this.y - y, this.z - z) - fun times(x: Int = 1, y: Int = 1, z: Int = 1) = Vector3d(this.x * x, this.y * y, this.z * z) - fun div(x: Int = 1, y: Int = 1, z: Int = 1) = Vector3d(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3i): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3i): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3i): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3i): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2i): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3i): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3i): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3i): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3i): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2i): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value, value) - operator fun minus(value: Int) = minus(value, value, value) - operator fun times(value: Int) = times(value, value, value) - operator fun div(value: Int) = div(value, value, value) - - fun plus(x: Float = 0f, y: Float = 0f, z: Float = 0f) = Vector3d(this.x + x, this.y + y, this.z + z) - fun minus(x: Float = 0f, y: Float = 0f, z: Float = 0f) = Vector3d(this.x - x, this.y - y, this.z - z) - fun times(x: Float = 1f, y: Float = 1f, z: Float = 1f) = Vector3d(this.x * x, this.y * y, this.z * z) - fun div(x: Float = 1f, y: Float = 1f, z: Float = 1f) = Vector3d(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3f): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3f): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3f): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3f): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2f): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3f): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3f): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3f): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3f): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2f): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value, value) - operator fun minus(value: Float) = minus(value, value, value) - operator fun times(value: Float) = times(value, value, value) - operator fun div(value: Float) = div(value, value, value) - - operator fun unaryMinus(): Vector3d = Vector3d(-x, -y, -z) - - fun dot(x: Double, y: Double, z: Double) = this.x * x + this.y * y + this.z * z - fun dot(value: IStruct3d): Double { val (x, y, z) = value; return dot(x, y, z) } - fun dot(value: Vector3d): Double { val (x, y, z) = value; return dot(x, y, z) } - - fun distanceSquared(x: Double, y: Double, z: Double): Double { - val dx = (this.x - x) - val dy = (this.y - y) - val dz = (this.z - z) - return dx * dx + dy * dy + dz * dz - } - - fun distanceSquared(value: IStruct3d): Double { val (x, y, z) = value; return distanceSquared(x, y, z) } - fun distanceSquared(value: Vector3d): Double { val (x, y, z) = value; return distanceSquared(x, y, z) } - fun distance(x: Double, y: Double, z: Double) = sqrt(distanceSquared(x, y, z)) - fun distance(value: IStruct3d): Double { val (x, y, z) = value; return sqrt(distanceSquared(x, y, z)) } - fun distance(value: Vector3d): Double { val (x, y, z) = value; return sqrt(distanceSquared(x, y, z)) } - - fun coerceAtLeast(x: Double, y: Double, z: Double) = Vector3d(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y), this.z.coerceAtLeast(z)) - fun coerceAtMost(x: Double, y: Double, z: Double) = Vector3d(this.x.coerceAtMost(x), this.y.coerceAtMost(y), this.z.coerceAtMost(z)) - - fun coerceIn(minimum: Vector3d, maximum: Vector3d) = Vector3d( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y), - this.z.coerceIn(minimum.z, maximum.z)) - - fun coerceIn(minimum: IStruct3d, maximum: IStruct3d) = Vector3d( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2()), - this.z.coerceIn(minimum.component3(), maximum.component3())) - - fun coerceAtLeast(value: IStruct3d): Vector3d { val (x, y, z) = value; return coerceAtLeast(x, y, z) } - fun coerceAtMost(value: IStruct3d): Vector3d { val (x, y, z) = value; return coerceAtMost(x, y, z) } - fun coerceAtLeast(value: Vector3d): Vector3d { val (x, y, z) = value; return coerceAtLeast(x, y, z) } - fun coerceAtMost(value: Vector3d): Vector3d { val (x, y, z) = value; return coerceAtMost(x, y, z) } - - fun cross(x: Double, y: Double, z: Double): Vector3d { - return Vector3d( - this.y * z - this.z * y, - this.z * x - this.x * z, - this.x * y - this.y * x, - ) - } - - fun cross(value: IStruct3d): Vector3d { val (x, y, z) = value; return cross(x, y, z) } - fun cross(value: Vector3d): Vector3d { val (x, y, z) = value; return cross(x, y, z) } - - operator fun times(value: Matrix4d): Vector3d { - return Vector3d( - x * value.c00 + y * value.c10 + z * value.c20 + value.c30, - x * value.c01 + y * value.c11 + z * value.c21 + value.c31, - x * value.c02 + y * value.c12 + z * value.c22 + value.c32, - ) - } - - operator fun times(value: Matrix3d): Vector3d { - return Vector3d( - x * value.c00 + y * value.c10 + z * value.c20, - x * value.c01 + y * value.c11 + z * value.c21, - x * value.c02 + y * value.c12 + z * value.c22, - ) - } - - operator fun times(value: Matrix4dStack) = times(value.last()) - - fun toDoubleVector() = this - fun toFloatVector() = Vector3f(x.toFloat(), y.toFloat(), z.toFloat()) - - override fun toString(): String { - return "[$x, $y, $z]" - } - - companion object { - @JvmField val ZERO = Vector3d() - @JvmField val POSITIVE_X = Vector3d(x = 1.0) - @JvmField val NEGATIVE_X = Vector3d(x = -1.0) - @JvmField val POSITIVE_Y = Vector3d(y = 1.0) - @JvmField val NEGATIVE_Y = Vector3d(y = -1.0) - @JvmField val POSITIVE_Z = Vector3d(z = 1.0) - @JvmField val NEGATIVE_Z = Vector3d(z = -1.0) - - @JvmField val POSITIVE_XYZ = Vector3d(1.0, 1.0, 1.0) - @JvmField val NEGATIVE_XYZ = Vector3d(-1.0, -1.0, -1.0) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3f.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3f.kt deleted file mode 100644 index a796219..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3f.kt +++ /dev/null @@ -1,227 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import ru.dbotthepony.kommons.util.IStruct3d -import ru.dbotthepony.kommons.util.IStruct3f -import ru.dbotthepony.kommons.util.IStruct3i -import ru.dbotthepony.kommons.matrix.Matrix3f -import ru.dbotthepony.kommons.matrix.Matrix4f -import ru.dbotthepony.kommons.matrix.Matrix4fStack -import kotlin.math.absoluteValue -import kotlin.math.sqrt - -data class Vector3f( - val x: Float = 0f, - val y: Float = 0f, - val z: Float = 0f, -) : IStruct3f, Vector() { - constructor(value: IStruct2f) : this(value.component1(), value.component2()) - constructor(value: Vector2f) : this(value.x, value.y) - constructor(value: IStruct2f, z: Float) : this(value.component1(), value.component2(), z) - constructor(value: Vector2f, z: Float) : this(value.x, value.y, z) - constructor(value: IStruct3f) : this(value.component1(), value.component2(), value.component3()) - constructor(value: Vector3f) : this(value.x, value.y, value.z) - - override val lengthSquared: Double - get() = x.toDouble() * x + y.toDouble() * y + z.toDouble() * z - - override val isFinite: Boolean - get() = x.isFinite() && y.isFinite() && z.isFinite() - override val isNaN: Boolean - get() = x.isNaN() || y.isNaN() || z.isNaN() - - val unitVector: Vector3f get() { - var length = lengthSquared.toFloat() - if (length == 0f || length == 1f) return this - length = sqrt(length) - return Vector3f(x / length, y / length, z / length) - } - - val absoluteValue: Vector3f get() { - val x = x.absoluteValue - val y = y.absoluteValue - val z = z.absoluteValue - if (x != this.x || y != this.y || z != this.z) return Vector3f(x, y, z) - return this - } - - val r get() = x - val g get() = y - val b get() = z - - val s get() = x - val t get() = y - val p get() = z - - fun plus(x: Float = 0f, y: Float = 0f, z: Float = 0f) = Vector3f(this.x + x, this.y + y, this.z + z) - fun minus(x: Float = 0f, y: Float = 0f, z: Float = 0f) = Vector3f(this.x - x, this.y - y, this.z - z) - fun times(x: Float = 1f, y: Float = 1f, z: Float = 1f) = Vector3f(this.x * x, this.y * y, this.z * z) - fun div(x: Float = 1f, y: Float = 1f, z: Float = 1f) = Vector3f(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3f): Vector3f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3f): Vector3f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3f): Vector3f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3f): Vector3f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2f): Vector3f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector3f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector3f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector3f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3f): Vector3f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3f): Vector3f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3f): Vector3f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3f): Vector3f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2f): Vector3f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector3f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector3f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector3f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value, value) - operator fun minus(value: Float) = minus(value, value, value) - operator fun times(value: Float) = times(value, value, value) - operator fun div(value: Float) = div(value, value, value) - - fun plus(x: Int = 0, y: Int = 0, z: Int = 0) = Vector3f(this.x + x, this.y + y, this.z + z) - fun minus(x: Int = 0, y: Int = 0, z: Int = 0) = Vector3f(this.x - x, this.y - y, this.z - z) - fun times(x: Int = 1, y: Int = 1, z: Int = 1) = Vector3f(this.x * x, this.y * y, this.z * z) - fun div(x: Int = 1, y: Int = 1, z: Int = 1) = Vector3f(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3i): Vector3f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3i): Vector3f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3i): Vector3f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3i): Vector3f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2i): Vector3f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector3f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector3f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector3f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3i): Vector3f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3i): Vector3f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3i): Vector3f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3i): Vector3f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2i): Vector3f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector3f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector3f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector3f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value, value) - operator fun minus(value: Int) = minus(value, value, value) - operator fun times(value: Int) = times(value, value, value) - operator fun div(value: Int) = div(value, value, value) - - fun plus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0) = Vector3d(this.x + x, this.y + y, this.z + z) - fun minus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0) = Vector3d(this.x - x, this.y - y, this.z - z) - fun times(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0) = Vector3d(this.x * x, this.y * y, this.z * z) - fun div(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0) = Vector3d(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3d): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3d): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3d): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3d): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2d): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3d): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3d): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3d): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3d): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2d): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value, value) - operator fun minus(value: Double) = minus(value, value, value) - operator fun times(value: Double) = times(value, value, value) - operator fun div(value: Double) = div(value, value, value) - - operator fun unaryMinus(): Vector3f = Vector3f(-x, -y, -z) - - fun dot(x: Float, y: Float, z: Float) = this.x * x + this.y * y + this.z * z - fun dot(value: IStruct3f): Float { val (x, y, z) = value; return dot(x, y, z) } - fun dot(value: Vector3f): Float { val (x, y, z) = value; return dot(x, y, z) } - - fun distanceSquared(x: Float, y: Float, z: Float): Double { - val dx = (this.x - x).toDouble() - val dy = (this.y - y).toDouble() - val dz = (this.z - z).toDouble() - return dx * dx + dy * dy + dz * dz - } - - fun distanceSquared(value: IStruct3f): Double { val (x, y, z) = value; return distanceSquared(x, y, z) } - fun distanceSquared(value: Vector3f): Double { val (x, y, z) = value; return distanceSquared(x, y, z) } - fun distance(x: Float, y: Float, z: Float) = sqrt(distanceSquared(x, y, z)) - fun distance(value: IStruct3f): Double { val (x, y, z) = value; return sqrt(distanceSquared(x, y, z)) } - fun distance(value: Vector3f): Double { val (x, y, z) = value; return sqrt(distanceSquared(x, y, z)) } - - fun coerceAtLeast(x: Float, y: Float, z: Float) = Vector3f(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y), this.z.coerceAtLeast(z)) - fun coerceAtMost(x: Float, y: Float, z: Float) = Vector3f(this.x.coerceAtMost(x), this.y.coerceAtMost(y), this.z.coerceAtMost(z)) - - fun coerceIn(minimum: Vector3f, maximum: Vector3f) = Vector3f( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y), - this.z.coerceIn(minimum.z, maximum.z)) - - fun coerceIn(minimum: IStruct3f, maximum: IStruct3f) = Vector3f( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2()), - this.z.coerceIn(minimum.component3(), maximum.component3())) - - fun coerceAtLeast(value: IStruct3f): Vector3f { val (x, y, z) = value; return coerceAtLeast(x, y, z) } - fun coerceAtMost(value: IStruct3f): Vector3f { val (x, y, z) = value; return coerceAtMost(x, y, z) } - fun coerceAtLeast(value: Vector3f): Vector3f { val (x, y, z) = value; return coerceAtLeast(x, y, z) } - fun coerceAtMost(value: Vector3f): Vector3f { val (x, y, z) = value; return coerceAtMost(x, y, z) } - - fun cross(x: Float, y: Float, z: Float): Vector3f { - return Vector3f( - this.y * z - this.z * y, - this.z * x - this.x * z, - this.x * y - this.y * x, - ) - } - - fun cross(value: IStruct3f): Vector3f { val (x, y, z) = value; return cross(x, y, z) } - fun cross(value: Vector3f): Vector3f { val (x, y, z) = value; return cross(x, y, z) } - - operator fun times(value: Matrix4f): Vector3f { - return Vector3f( - x * value.c00 + y * value.c10 + z * value.c20 + value.c30, - x * value.c01 + y * value.c11 + z * value.c21 + value.c31, - x * value.c02 + y * value.c12 + z * value.c22 + value.c32, - ) - } - - operator fun times(value: Matrix3f): Vector3f { - return Vector3f( - x * value.c00 + y * value.c10 + z * value.c20, - x * value.c01 + y * value.c11 + z * value.c21, - x * value.c02 + y * value.c12 + z * value.c22, - ) - } - - operator fun times(value: Matrix4fStack) = times(value.last()) - - fun toDoubleVector() = Vector3d(x.toDouble(), y.toDouble(), z.toDouble()) - fun toFloatVector() = this - - override fun toString(): String { - return "[$x, $y, $z]" - } - - companion object { - @JvmField val ZERO = Vector3f() - @JvmField val POSITIVE_X = Vector3f(x = 1.0f) - @JvmField val NEGATIVE_X = Vector3f(x = -1.0f) - @JvmField val POSITIVE_Y = Vector3f(y = 1.0f) - @JvmField val NEGATIVE_Y = Vector3f(y = -1.0f) - @JvmField val POSITIVE_Z = Vector3f(z = 1.0f) - @JvmField val NEGATIVE_Z = Vector3f(z = -1.0f) - - @JvmField val POSITIVE_XYZ = Vector3f(1.0f, 1.0f, 1f) - @JvmField val NEGATIVE_XYZ = Vector3f(-1.0f, -1.0f, -1f) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3i.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3i.kt deleted file mode 100644 index eb22674..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector3i.kt +++ /dev/null @@ -1,190 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import ru.dbotthepony.kommons.util.IStruct3d -import ru.dbotthepony.kommons.util.IStruct3f -import ru.dbotthepony.kommons.util.IStruct3i -import kotlin.math.sqrt - -data class Vector3i( - val x: Int = 0, - val y: Int = 0, - val z: Int = 0, -) : IStruct3i, Vector() { - constructor(value: IStruct2i) : this(value.component1(), value.component2()) - constructor(value: Vector2i) : this(value.x, value.y) - constructor(value: IStruct2i, z: Int) : this(value.component1(), value.component2(), z) - constructor(value: Vector2i, z: Int) : this(value.x, value.y, z) - constructor(value: IStruct3i) : this(value.component1(), value.component2(), value.component3()) - constructor(value: Vector3i) : this(value.x, value.y, value.z) - - override val lengthSquared: Double - get() = x.toDouble() * x + y.toDouble() * y + z.toDouble() * z - - override val isFinite: Boolean - get() = true - override val isNaN: Boolean - get() = false - - val r get() = x - val g get() = y - val b get() = z - - val s get() = x - val t get() = y - val p get() = z - - fun plus(x: Int = 0, y: Int = 0, z: Int = 0) = Vector3i(this.x + x, this.y + y, this.z + z) - fun minus(x: Int = 0, y: Int = 0, z: Int = 0) = Vector3i(this.x - x, this.y - y, this.z - z) - fun times(x: Int = 1, y: Int = 1, z: Int = 1) = Vector3i(this.x * x, this.y * y, this.z * z) - fun div(x: Int = 1, y: Int = 1, z: Int = 1) = Vector3i(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3i): Vector3i { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3i): Vector3i { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3i): Vector3i { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3i): Vector3i { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2i): Vector3i { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector3i { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector3i { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector3i { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3i): Vector3i { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3i): Vector3i { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3i): Vector3i { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3i): Vector3i { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2i): Vector3i { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector3i { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector3i { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector3i { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value, value) - operator fun minus(value: Int) = minus(value, value, value) - operator fun times(value: Int) = times(value, value, value) - operator fun div(value: Int) = div(value, value, value) - - fun plus(x: Float = 0f, y: Float = 0f, z: Float = 0f) = Vector3f(this.x + x, this.y + y, this.z + z) - fun minus(x: Float = 0f, y: Float = 0f, z: Float = 0f) = Vector3f(this.x - x, this.y - y, this.z - z) - fun times(x: Float = 1f, y: Float = 1f, z: Float = 1f) = Vector3f(this.x * x, this.y * y, this.z * z) - fun div(x: Float = 1f, y: Float = 1f, z: Float = 1f) = Vector3f(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3f): Vector3f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3f): Vector3f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3f): Vector3f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3f): Vector3f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2f): Vector3f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector3f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector3f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector3f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3f): Vector3f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3f): Vector3f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3f): Vector3f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3f): Vector3f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2f): Vector3f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector3f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector3f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector3f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value, value) - operator fun minus(value: Float) = minus(value, value, value) - operator fun times(value: Float) = times(value, value, value) - operator fun div(value: Float) = div(value, value, value) - - fun plus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0) = Vector3d(this.x + x, this.y + y, this.z + z) - fun minus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0) = Vector3d(this.x - x, this.y - y, this.z - z) - fun times(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0) = Vector3d(this.x * x, this.y * y, this.z * z) - fun div(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0) = Vector3d(this.x / x, this.y / y, this.z / z) - - operator fun plus(value: IStruct3d): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3d): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3d): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3d): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2d): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector3d): Vector3d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3d): Vector3d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3d): Vector3d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3d): Vector3d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2d): Vector3d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector3d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector3d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector3d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value, value) - operator fun minus(value: Double) = minus(value, value, value) - operator fun times(value: Double) = times(value, value, value) - operator fun div(value: Double) = div(value, value, value) - - operator fun unaryMinus(): Vector3i = Vector3i(-x, -y, -z) - - fun dot(x: Int, y: Int, z: Int) = this.x * x + this.y * y + this.z * z - fun dot(value: IStruct3i): Int { val (x, y, z) = value; return dot(x, y, z) } - fun dot(value: Vector3i): Int { val (x, y, z) = value; return dot(x, y, z) } - - fun distanceSquared(x: Int, y: Int, z: Int): Double { - val dx = (this.x - x).toDouble() - val dy = (this.y - y).toDouble() - val dz = (this.z - z).toDouble() - return dx * dx + dy * dy + dz * dz - } - - fun distanceSquared(value: IStruct3i): Double { val (x, y, z) = value; return distanceSquared(x, y, z) } - fun distanceSquared(value: Vector3i): Double { val (x, y, z) = value; return distanceSquared(x, y, z) } - fun distance(x: Int, y: Int, z: Int) = sqrt(distanceSquared(x, y, z)) - fun distance(value: IStruct3i): Double { val (x, y, z) = value; return sqrt(distanceSquared(x, y, z)) } - fun distance(value: Vector3i): Double { val (x, y, z) = value; return sqrt(distanceSquared(x, y, z)) } - - fun coerceAtLeast(x: Int, y: Int, z: Int) = Vector3i(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y), this.z.coerceAtLeast(z)) - fun coerceAtMost(x: Int, y: Int, z: Int) = Vector3i(this.x.coerceAtMost(x), this.y.coerceAtMost(y), this.z.coerceAtMost(z)) - - fun coerceIn(minimum: Vector3i, maximum: Vector3i) = Vector3i( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y), - this.z.coerceIn(minimum.z, maximum.z)) - - fun coerceIn(minimum: IStruct3i, maximum: IStruct3i) = Vector3i( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2()), - this.z.coerceIn(minimum.component3(), maximum.component3())) - - fun coerceAtLeast(value: IStruct3i): Vector3i { val (x, y, z) = value; return coerceAtLeast(x, y, z) } - fun coerceAtMost(value: IStruct3i): Vector3i { val (x, y, z) = value; return coerceAtMost(x, y, z) } - fun coerceAtLeast(value: Vector3i): Vector3i { val (x, y, z) = value; return coerceAtLeast(x, y, z) } - fun coerceAtMost(value: Vector3i): Vector3i { val (x, y, z) = value; return coerceAtMost(x, y, z) } - - fun cross(x: Int, y: Int, z: Int): Vector3i { - return Vector3i( - this.y * z - this.z * y, - this.z * x - this.x * z, - this.x * y - this.y * x, - ) - } - - fun cross(value: IStruct3i): Vector3i { val (x, y, z) = value; return cross(x, y, z) } - fun cross(value: Vector3i): Vector3i { val (x, y, z) = value; return cross(x, y, z) } - - fun toDoubleVector() = Vector3d(x.toDouble(), y.toDouble(), z.toDouble()) - fun toFloatVector() = Vector3f(x.toFloat(), y.toFloat(), z.toFloat()) - - override fun toString(): String { - return "[$x, $y, $z]" - } - - companion object { - @JvmField val ZERO = Vector3i() - @JvmField val POSITIVE_X = Vector3i(x = 1) - @JvmField val NEGATIVE_X = Vector3i(x = -1) - @JvmField val POSITIVE_Y = Vector3i(y = 1) - @JvmField val NEGATIVE_Y = Vector3i(y = -1) - @JvmField val POSITIVE_Z = Vector3i(z = 1) - @JvmField val NEGATIVE_Z = Vector3i(z = -1) - - @JvmField val POSITIVE_XYZ = Vector3i(1, 1, 1) - @JvmField val NEGATIVE_XYZ = Vector3i(-1, -1, -1) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4d.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4d.kt deleted file mode 100644 index d6aeb29..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4d.kt +++ /dev/null @@ -1,247 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import ru.dbotthepony.kommons.util.IStruct3d -import ru.dbotthepony.kommons.util.IStruct3f -import ru.dbotthepony.kommons.util.IStruct3i -import ru.dbotthepony.kommons.util.IStruct4d -import ru.dbotthepony.kommons.util.IStruct4f -import ru.dbotthepony.kommons.util.IStruct4i -import ru.dbotthepony.kommons.matrix.Matrix4d -import ru.dbotthepony.kommons.matrix.Matrix4dStack -import kotlin.math.absoluteValue -import kotlin.math.sqrt - -data class Vector4d( - val x: Double = 0.0, - val y: Double = 0.0, - val z: Double = 0.0, - val w: Double = 0.0, -) : IStruct4d, Vector() { - constructor(value: IStruct2d) : this(value.component1(), value.component2()) - constructor(value: Vector2d) : this(value.x, value.y) - constructor(value: IStruct2d, z: Double) : this(value.component1(), value.component2(), z) - constructor(value: Vector2d, z: Double) : this(value.x, value.y, z) - constructor(value: IStruct2d, z: Double, w: Double) : this(value.component1(), value.component2(), z, w) - constructor(value: Vector2d, z: Double, w: Double) : this(value.x, value.y, z, w) - constructor(value: IStruct3d) : this(value.component1(), value.component2(), value.component3()) - constructor(value: Vector3d) : this(value.x, value.y, value.z) - constructor(value: IStruct3d, w: Double) : this(value.component1(), value.component2(), value.component3(), w) - constructor(value: Vector3d, w: Double) : this(value.x, value.y, value.z, w) - constructor(value: IStruct4d) : this(value.component1(), value.component2(), value.component3(), value.component4()) - constructor(value: Vector4d) : this(value.x, value.y, value.z, value.w) - - override val lengthSquared: Double - get() = x * x + y * y + z * z + w * w - - override val isFinite: Boolean - get() = x.isFinite() && y.isFinite() && z.isFinite() && w.isFinite() - override val isNaN: Boolean - get() = x.isNaN() || y.isNaN() || z.isNaN() || w.isNaN() - - val unitVector: Vector4d get() { - var length = lengthSquared - if (length == 0.0 || length == 1.0) return this - length = sqrt(length) - return Vector4d(x / length, y / length, z / length, w / length) - } - - val absoluteValue: Vector4d get() { - val x = x.absoluteValue - val y = y.absoluteValue - val z = z.absoluteValue - val w = w.absoluteValue - if (x != this.x || y != this.y || z != this.z || w != this.w) return Vector4d(x, y, z, w) - return this - } - - val r get() = x - val g get() = y - val b get() = z - val a get() = w - - val s get() = x - val t get() = y - val p get() = z - val q get() = w - - fun plus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0, w: Double = 0.0) = Vector4d(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0, w: Double = 0.0) = Vector4d(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0, w: Double = 1.0) = Vector4d(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0, w: Double = 1.0) = Vector4d(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3d): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3d): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3d): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3d): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2d): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4d): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4d): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4d): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4d): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3d): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3d): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3d): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3d): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2d): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value, value, value) - operator fun minus(value: Double) = minus(value, value, value, value) - operator fun times(value: Double) = times(value, value, value, value) - operator fun div(value: Double) = div(value, value, value, value) - - fun plus(x: Int = 0, y: Int = 0, z: Int = 0, w: Int = 0) = Vector4d(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Int = 0, y: Int = 0, z: Int = 0, w: Int = 0) = Vector4d(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Int = 1, y: Int = 1, z: Int = 1, w: Int = 1) = Vector4d(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Int = 1, y: Int = 1, z: Int = 1, w: Int = 1) = Vector4d(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4i): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4i): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4i): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4i): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3i): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3i): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3i): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3i): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2i): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4i): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4i): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4i): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4i): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3i): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3i): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3i): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3i): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2i): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value, value, value) - operator fun minus(value: Int) = minus(value, value, value, value) - operator fun times(value: Int) = times(value, value, value, value) - operator fun div(value: Int) = div(value, value, value, value) - - fun plus(x: Float = 0f, y: Float = 0f, z: Float = 0f, w: Float = 0f) = Vector4d(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Float = 0f, y: Float = 0f, z: Float = 0f, w: Float = 0f) = Vector4d(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Float = 1f, y: Float = 1f, z: Float = 1f, w: Float = 1f) = Vector4d(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Float = 1f, y: Float = 1f, z: Float = 1f, w: Float = 1f) = Vector4d(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4f): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4f): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4f): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4f): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3f): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3f): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3f): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3f): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2f): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4f): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4f): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4f): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4f): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3f): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3f): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3f): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3f): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2f): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value, value, value) - operator fun minus(value: Float) = minus(value, value, value, value) - operator fun times(value: Float) = times(value, value, value, value) - operator fun div(value: Float) = div(value, value, value, value) - - operator fun unaryMinus(): Vector4d = Vector4d(-x, -y, -z, -w) - - fun dot(x: Double, y: Double, z: Double, w: Double) = this.x * x + this.y * y + this.z * z + this.w * w - fun dot(value: IStruct4d): Double { val (x, y, z, w) = value; return dot(x, y, z, w) } - fun dot(value: Vector4d): Double { val (x, y, z, w) = value; return dot(x, y, z, w) } - - fun distanceSquared(x: Double, y: Double, z: Double, w: Double): Double { - val dx = (this.x - x) - val dy = (this.y - y) - val dz = (this.z - z) - val dw = (this.w - w) - return dx * dx + dy * dy + dz * dz + dw * dw - } - - fun distanceSquared(value: IStruct4d): Double { val (x, y, z, w) = value; return distanceSquared(x, y, z, w) } - fun distanceSquared(value: Vector4d): Double { val (x, y, z, w) = value; return distanceSquared(x, y, z, w) } - fun distance(x: Double, y: Double, z: Double, w: Double) = sqrt(distanceSquared(x, y, z, w)) - fun distance(value: IStruct4d): Double { val (x, y, z, w) = value; return sqrt(distanceSquared(x, y, z, w)) } - fun distance(value: Vector4d): Double { val (x, y, z, w) = value; return sqrt(distanceSquared(x, y, z, w)) } - - fun coerceAtLeast(x: Double, y: Double, z: Double, w: Double) = Vector4d(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y), this.z.coerceAtLeast(z), this.w.coerceAtLeast(w)) - fun coerceAtMost(x: Double, y: Double, z: Double, w: Double) = Vector4d(this.x.coerceAtMost(x), this.y.coerceAtMost(y), this.z.coerceAtMost(z), this.w.coerceAtMost(w)) - - fun coerceIn(minimum: Vector4d, maximum: Vector4d) = Vector4d( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y), - this.z.coerceIn(minimum.z, maximum.z), - this.w.coerceIn(minimum.w, maximum.w)) - - fun coerceIn(minimum: IStruct4d, maximum: IStruct4d) = Vector4d( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2()), - this.z.coerceIn(minimum.component3(), maximum.component3()), - this.w.coerceIn(minimum.component4(), maximum.component4())) - - fun coerceAtLeast(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return coerceAtLeast(x, y, z, w) } - fun coerceAtMost(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return coerceAtMost(x, y, z, w) } - fun coerceAtLeast(value: Vector4d): Vector4d { val (x, y, z, w) = value; return coerceAtLeast(x, y, z, w) } - fun coerceAtMost(value: Vector4d): Vector4d { val (x, y, z, w) = value; return coerceAtMost(x, y, z, w) } - - operator fun times(value: Matrix4d): Vector4d { - return Vector4d( - x * value.c00 + y * value.c10 + z * value.c20 + w * value.c30, - x * value.c01 + y * value.c11 + z * value.c21 + w * value.c31, - x * value.c02 + y * value.c12 + z * value.c22 + w * value.c32, - x * value.c03 + y * value.c13 + z * value.c23 + w * value.c33, - ) - } - - operator fun times(value: Matrix4dStack) = times(value.last()) - - fun toDoubleVector() = this - fun toFloatVector() = Vector4f(x.toFloat(), y.toFloat(), z.toFloat(), w.toFloat()) - - override fun toString(): String { - return "[$x, $y, $z, $w]" - } - - companion object { - @JvmField val ZERO = Vector4d() - @JvmField val POSITIVE_X = Vector4d(x = 1.0) - @JvmField val NEGATIVE_X = Vector4d(x = -1.0) - @JvmField val POSITIVE_Y = Vector4d(y = 1.0) - @JvmField val NEGATIVE_Y = Vector4d(y = -1.0) - @JvmField val POSITIVE_Z = Vector4d(z = 1.0) - @JvmField val NEGATIVE_Z = Vector4d(z = -1.0) - @JvmField val POSITIVE_W = Vector4d(w = 1.0) - @JvmField val NEGATIVE_W = Vector4d(w = -1.0) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4f.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4f.kt deleted file mode 100644 index c1748ee..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4f.kt +++ /dev/null @@ -1,249 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import ru.dbotthepony.kommons.util.IStruct3d -import ru.dbotthepony.kommons.util.IStruct3f -import ru.dbotthepony.kommons.util.IStruct3i -import ru.dbotthepony.kommons.util.IStruct4d -import ru.dbotthepony.kommons.util.IStruct4f -import ru.dbotthepony.kommons.util.IStruct4i -import ru.dbotthepony.kommons.matrix.Matrix4f -import ru.dbotthepony.kommons.matrix.Matrix4fStack -import kotlin.math.absoluteValue -import kotlin.math.sqrt - -data class Vector4f( - val x: Float = 0f, - val y: Float = 0f, - val z: Float = 0f, - val w: Float = 0f, -) : IStruct4f, Vector() { - constructor(value: IStruct2f) : this(value.component1(), value.component2()) - constructor(value: Vector2f) : this(value.x, value.y) - constructor(value: IStruct2f, z: Float) : this(value.component1(), value.component2(), z) - constructor(value: Vector2f, z: Float) : this(value.x, value.y, z) - constructor(value: IStruct2f, z: Float, w: Float) : this(value.component1(), value.component2(), z, w) - constructor(value: Vector2f, z: Float, w: Float) : this(value.x, value.y, z, w) - constructor(value: IStruct3f) : this(value.component1(), value.component2(), value.component3()) - constructor(value: Vector3f) : this(value.x, value.y, value.z) - constructor(value: IStruct3f, w: Float) : this(value.component1(), value.component2(), value.component3(), w) - constructor(value: Vector3f, w: Float) : this(value.x, value.y, value.z, w) - constructor(value: IStruct4f) : this(value.component1(), value.component2(), value.component3(), value.component4()) - constructor(value: Vector4f) : this(value.x, value.y, value.z, value.w) - - override val lengthSquared: Double - get() = x.toDouble() * x + y.toDouble() * y + z.toDouble() * z + w.toDouble() * w - - override val isFinite: Boolean - get() = x.isFinite() && y.isFinite() && z.isFinite() && w.isFinite() - override val isNaN: Boolean - get() = x.isNaN() || y.isNaN() || z.isNaN() || w.isNaN() - - val unitVector: Vector4f - get() { - var length = lengthSquared.toFloat() - if (length == 0f || length == 1f) return this - length = sqrt(length) - return Vector4f(x / length, y / length, z / length, w / length) - } - - val absoluteValue: Vector4f - get() { - val x = x.absoluteValue - val y = y.absoluteValue - val z = z.absoluteValue - val w = w.absoluteValue - if (x != this.x || y != this.y || z != this.z || w != this.w) return Vector4f(x, y, z, w) - return this - } - - val r get() = x - val g get() = y - val b get() = z - val a get() = w - - val s get() = x - val t get() = y - val p get() = z - val q get() = w - - fun plus(x: Float = 0f, y: Float = 0f, z: Float = 0f, w: Float = 0f) = Vector4f(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Float = 0f, y: Float = 0f, z: Float = 0f, w: Float = 0f) = Vector4f(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Float = 1f, y: Float = 1f, z: Float = 1f, w: Float = 1f) = Vector4f(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Float = 1f, y: Float = 1f, z: Float = 1f, w: Float = 1f) = Vector4f(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3f): Vector4f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3f): Vector4f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3f): Vector4f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3f): Vector4f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2f): Vector4f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector4f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector4f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector4f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4f): Vector4f { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4f): Vector4f { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4f): Vector4f { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4f): Vector4f { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3f): Vector4f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3f): Vector4f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3f): Vector4f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3f): Vector4f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2f): Vector4f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector4f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector4f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector4f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value, value, value) - operator fun minus(value: Float) = minus(value, value, value, value) - operator fun times(value: Float) = times(value, value, value, value) - operator fun div(value: Float) = div(value, value, value, value) - - fun plus(x: Int = 0, y: Int = 0, z: Int = 0, w: Int = 0) = Vector4f(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Int = 0, y: Int = 0, z: Int = 0, w: Int = 0) = Vector4f(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Int = 1, y: Int = 1, z: Int = 1, w: Int = 1) = Vector4f(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Int = 1, y: Int = 1, z: Int = 1, w: Int = 1) = Vector4f(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4i): Vector4f { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4i): Vector4f { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4i): Vector4f { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4i): Vector4f { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3i): Vector4f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3i): Vector4f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3i): Vector4f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3i): Vector4f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2i): Vector4f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector4f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector4f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector4f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4i): Vector4f { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4i): Vector4f { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4i): Vector4f { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4i): Vector4f { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3i): Vector4f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3i): Vector4f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3i): Vector4f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3i): Vector4f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2i): Vector4f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector4f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector4f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector4f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value, value, value) - operator fun minus(value: Int) = minus(value, value, value, value) - operator fun times(value: Int) = times(value, value, value, value) - operator fun div(value: Int) = div(value, value, value, value) - - fun plus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0, w: Double = 0.0) = Vector4d(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0, w: Double = 0.0) = Vector4d(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0, w: Double = 1.0) = Vector4d(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0, w: Double = 1.0) = Vector4d(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3d): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3d): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3d): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3d): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2d): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4d): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4d): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4d): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4d): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3d): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3d): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3d): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3d): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2d): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value, value, value) - operator fun minus(value: Double) = minus(value, value, value, value) - operator fun times(value: Double) = times(value, value, value, value) - operator fun div(value: Double) = div(value, value, value, value) - - operator fun unaryMinus(): Vector4f = Vector4f(-x, -y, -z, -w) - - fun dot(x: Float, y: Float, z: Float, w: Float) = this.x * x + this.y * y + this.z * z + this.w * w - fun dot(value: IStruct4f): Float { val (x, y, z, w) = value; return dot(x, y, z, w) } - fun dot(value: Vector4f): Float { val (x, y, z, w) = value; return dot(x, y, z, w) } - - fun distanceSquared(x: Float, y: Float, z: Float, w: Float): Double { - val dx = (this.x - x).toDouble() - val dy = (this.y - y).toDouble() - val dz = (this.z - z).toDouble() - val dw = (this.w - w).toDouble() - return dx * dx + dy * dy + dz * dz + dw * dw - } - - fun distanceSquared(value: IStruct4f): Double { val (x, y, z, w) = value; return distanceSquared(x, y, z, w) } - fun distanceSquared(value: Vector4f): Double { val (x, y, z, w) = value; return distanceSquared(x, y, z, w) } - fun distance(x: Float, y: Float, z: Float, w: Float) = sqrt(distanceSquared(x, y, z, w)) - fun distance(value: IStruct4f): Double { val (x, y, z, w) = value; return sqrt(distanceSquared(x, y, z, w)) } - fun distance(value: Vector4f): Double { val (x, y, z, w) = value; return sqrt(distanceSquared(x, y, z, w)) } - - fun coerceAtLeast(x: Float, y: Float, z: Float, w: Float) = Vector4f(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y), this.z.coerceAtLeast(z), this.w.coerceAtLeast(w)) - fun coerceAtMost(x: Float, y: Float, z: Float, w: Float) = Vector4f(this.x.coerceAtMost(x), this.y.coerceAtMost(y), this.z.coerceAtMost(z), this.w.coerceAtMost(w)) - - fun coerceIn(minimum: Vector4f, maximum: Vector4f) = Vector4f( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y), - this.z.coerceIn(minimum.z, maximum.z), - this.w.coerceIn(minimum.w, maximum.w)) - - fun coerceIn(minimum: IStruct4f, maximum: IStruct4f) = Vector4f( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2()), - this.z.coerceIn(minimum.component3(), maximum.component3()), - this.w.coerceIn(minimum.component4(), maximum.component4())) - - fun coerceAtLeast(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return coerceAtLeast(x, y, z, w) } - fun coerceAtMost(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return coerceAtMost(x, y, z, w) } - fun coerceAtLeast(value: Vector4f): Vector4f { val (x, y, z, w) = value; return coerceAtLeast(x, y, z, w) } - fun coerceAtMost(value: Vector4f): Vector4f { val (x, y, z, w) = value; return coerceAtMost(x, y, z, w) } - - operator fun times(value: Matrix4f): Vector4f { - return Vector4f( - x * value.c00 + y * value.c10 + z * value.c20 + w * value.c30, - x * value.c01 + y * value.c11 + z * value.c21 + w * value.c31, - x * value.c02 + y * value.c12 + z * value.c22 + w * value.c32, - x * value.c03 + y * value.c13 + z * value.c23 + w * value.c33, - ) - } - - operator fun times(value: Matrix4fStack) = times(value.last()) - - fun toDoubleVector() = Vector4d(x.toDouble(), y.toDouble(), z.toDouble(), w.toDouble()) - fun toFloatVector() = this - - override fun toString(): String { - return "[$x, $y, $z, $w]" - } - - companion object { - @JvmField val ZERO = Vector4f() - @JvmField val POSITIVE_X = Vector4f(x = 1.0f) - @JvmField val NEGATIVE_X = Vector4f(x = -1.0f) - @JvmField val POSITIVE_Y = Vector4f(y = 1.0f) - @JvmField val NEGATIVE_Y = Vector4f(y = -1.0f) - @JvmField val POSITIVE_Z = Vector4f(z = 1.0f) - @JvmField val NEGATIVE_Z = Vector4f(z = -1.0f) - @JvmField val POSITIVE_W = Vector4f(w = 1.0f) - @JvmField val NEGATIVE_W = Vector4f(w = -1.0f) - } -} diff --git a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4i.kt b/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4i.kt deleted file mode 100644 index e030263..0000000 --- a/linear-algebra/src/main/kotlin/ru/dbotthepony/kommons/vector/Vector4i.kt +++ /dev/null @@ -1,217 +0,0 @@ -package ru.dbotthepony.kommons.vector - -import ru.dbotthepony.kommons.util.IStruct2d -import ru.dbotthepony.kommons.util.IStruct2f -import ru.dbotthepony.kommons.util.IStruct2i -import ru.dbotthepony.kommons.util.IStruct3d -import ru.dbotthepony.kommons.util.IStruct3f -import ru.dbotthepony.kommons.util.IStruct3i -import ru.dbotthepony.kommons.util.IStruct4d -import ru.dbotthepony.kommons.util.IStruct4f -import ru.dbotthepony.kommons.util.IStruct4i -import kotlin.math.sqrt - -data class Vector4i( - val x: Int = 0, - val y: Int = 0, - val z: Int = 0, - val w: Int = 0, -) : IStruct4i, Vector() { - constructor(value: IStruct2i) : this(value.component1(), value.component2()) - constructor(value: Vector2i) : this(value.x, value.y) - constructor(value: IStruct2i, z: Int) : this(value.component1(), value.component2(), z) - constructor(value: Vector2i, z: Int) : this(value.x, value.y, z) - constructor(value: IStruct2i, z: Int, w: Int) : this(value.component1(), value.component2(), z, w) - constructor(value: Vector2i, z: Int, w: Int) : this(value.x, value.y, z, w) - constructor(value: IStruct3i) : this(value.component1(), value.component2(), value.component3()) - constructor(value: Vector3i) : this(value.x, value.y, value.z) - constructor(value: IStruct3i, w: Int) : this(value.component1(), value.component2(), value.component3(), w) - constructor(value: Vector3i, w: Int) : this(value.x, value.y, value.z, w) - constructor(value: IStruct4i) : this(value.component1(), value.component2(), value.component3(), value.component4()) - constructor(value: Vector4i) : this(value.x, value.y, value.z, value.w) - - override val lengthSquared: Double - get() = x.toDouble() * x + y.toDouble() * y + z.toDouble() * z + w.toDouble() * w - - override val isFinite: Boolean - get() = true - override val isNaN: Boolean - get() = false - - val r get() = x - val g get() = y - val b get() = z - val a get() = w - - val s get() = x - val t get() = y - val p get() = z - val q get() = w - - fun plus(x: Int = 0, y: Int = 0, z: Int = 0, w: Int = 0) = Vector4i(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Int = 0, y: Int = 0, z: Int = 0, w: Int = 0) = Vector4i(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Int = 1, y: Int = 1, z: Int = 1, w: Int = 1) = Vector4i(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Int = 1, y: Int = 1, z: Int = 1, w: Int = 1) = Vector4i(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4i): Vector4i { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4i): Vector4i { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4i): Vector4i { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4i): Vector4i { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3i): Vector4i { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3i): Vector4i { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3i): Vector4i { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3i): Vector4i { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2i): Vector4i { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2i): Vector4i { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2i): Vector4i { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2i): Vector4i { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4i): Vector4i { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4i): Vector4i { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4i): Vector4i { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4i): Vector4i { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3i): Vector4i { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3i): Vector4i { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3i): Vector4i { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3i): Vector4i { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2i): Vector4i { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2i): Vector4i { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2i): Vector4i { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2i): Vector4i { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Int) = plus(value, value, value, value) - operator fun minus(value: Int) = minus(value, value, value, value) - operator fun times(value: Int) = times(value, value, value, value) - operator fun div(value: Int) = div(value, value, value, value) - - fun plus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0, w: Double = 0.0) = Vector4d(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0, w: Double = 0.0) = Vector4d(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0, w: Double = 1.0) = Vector4d(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Double = 1.0, y: Double = 1.0, z: Double = 1.0, w: Double = 1.0) = Vector4d(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4d): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3d): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3d): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3d): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3d): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2d): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2d): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2d): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2d): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4d): Vector4d { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4d): Vector4d { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4d): Vector4d { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4d): Vector4d { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3d): Vector4d { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3d): Vector4d { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3d): Vector4d { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3d): Vector4d { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2d): Vector4d { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2d): Vector4d { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2d): Vector4d { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2d): Vector4d { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Double) = plus(value, value, value, value) - operator fun minus(value: Double) = minus(value, value, value, value) - operator fun times(value: Double) = times(value, value, value, value) - operator fun div(value: Double) = div(value, value, value, value) - - fun plus(x: Float = 0f, y: Float = 0f, z: Float = 0f, w: Float = 0f) = Vector4f(this.x + x, this.y + y, this.z + z, this.w + w) - fun minus(x: Float = 0f, y: Float = 0f, z: Float = 0f, w: Float = 0f) = Vector4f(this.x - x, this.y - y, this.z - z, this.w - w) - fun times(x: Float = 1f, y: Float = 1f, z: Float = 1f, w: Float = 1f) = Vector4f(this.x * x, this.y * y, this.z * z, this.w * w) - fun div(x: Float = 1f, y: Float = 1f, z: Float = 1f, w: Float = 1f) = Vector4f(this.x / x, this.y / y, this.z / z, this.w / w) - - operator fun plus(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: IStruct4f): Vector4f { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: IStruct3f): Vector4f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: IStruct3f): Vector4f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: IStruct3f): Vector4f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: IStruct3f): Vector4f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: IStruct2f): Vector4f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: IStruct2f): Vector4f { val (x, y) = value; return minus(x, y) } - operator fun times(value: IStruct2f): Vector4f { val (x, y) = value; return times(x, y) } - operator fun div(value: IStruct2f): Vector4f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Vector4f): Vector4f { val (x, y, z, w) = value; return plus(x, y, z, w) } - operator fun minus(value: Vector4f): Vector4f { val (x, y, z, w) = value; return minus(x, y, z, w) } - operator fun times(value: Vector4f): Vector4f { val (x, y, z, w) = value; return times(x, y, z, w) } - operator fun div(value: Vector4f): Vector4f { val (x, y, z, w) = value; return div(x, y, z, w) } - operator fun plus(value: Vector3f): Vector4f { val (x, y, z) = value; return plus(x, y, z) } - operator fun minus(value: Vector3f): Vector4f { val (x, y, z) = value; return minus(x, y, z) } - operator fun times(value: Vector3f): Vector4f { val (x, y, z) = value; return times(x, y, z) } - operator fun div(value: Vector3f): Vector4f { val (x, y, z) = value; return div(x, y, z) } - operator fun plus(value: Vector2f): Vector4f { val (x, y) = value; return plus(x, y) } - operator fun minus(value: Vector2f): Vector4f { val (x, y) = value; return minus(x, y) } - operator fun times(value: Vector2f): Vector4f { val (x, y) = value; return times(x, y) } - operator fun div(value: Vector2f): Vector4f { val (x, y) = value; return div(x, y) } - - operator fun plus(value: Float) = plus(value, value, value, value) - operator fun minus(value: Float) = minus(value, value, value, value) - operator fun times(value: Float) = times(value, value, value, value) - operator fun div(value: Float) = div(value, value, value, value) - - operator fun unaryMinus(): Vector4i = Vector4i(-x, -y, -z, -w) - - fun dot(x: Int, y: Int, z: Int, w: Int) = this.x * x + this.y * y + this.z * z + this.w * w - fun dot(value: IStruct4i): Int { val (x, y, z, w) = value; return dot(x, y, z, w) } - fun dot(value: Vector4i): Int { val (x, y, z, w) = value; return dot(x, y, z, w) } - - fun distanceSquared(x: Int, y: Int, z: Int, w: Int): Double { - val dx = (this.x - x).toDouble() - val dy = (this.y - y).toDouble() - val dz = (this.z - z).toDouble() - val dw = (this.w - w).toDouble() - return dx * dx + dy * dy + dz * dz + dw * dw - } - - fun distanceSquared(value: IStruct4i): Double { val (x, y, z, w) = value; return distanceSquared(x, y, z, w) } - fun distanceSquared(value: Vector4i): Double { val (x, y, z, w) = value; return distanceSquared(x, y, z, w) } - fun distance(x: Int, y: Int, z: Int, w: Int) = sqrt(distanceSquared(x, y, z, w)) - fun distance(value: IStruct4i): Double { val (x, y, z, w) = value; return sqrt(distanceSquared(x, y, z, w)) } - fun distance(value: Vector4i): Double { val (x, y, z, w) = value; return sqrt(distanceSquared(x, y, z, w)) } - - fun coerceAtLeast(x: Int, y: Int, z: Int, w: Int) = Vector4i(this.x.coerceAtLeast(x), this.y.coerceAtLeast(y), this.z.coerceAtLeast(z), this.w.coerceAtLeast(w)) - fun coerceAtMost(x: Int, y: Int, z: Int, w: Int) = Vector4i(this.x.coerceAtMost(x), this.y.coerceAtMost(y), this.z.coerceAtMost(z), this.w.coerceAtMost(w)) - - fun coerceIn(minimum: Vector4i, maximum: Vector4i) = Vector4i( - this.x.coerceIn(minimum.x, maximum.x), - this.y.coerceIn(minimum.y, maximum.y), - this.z.coerceIn(minimum.z, maximum.z), - this.w.coerceIn(minimum.w, maximum.w)) - - fun coerceIn(minimum: IStruct4i, maximum: IStruct4i) = Vector4i( - this.x.coerceIn(minimum.component1(), maximum.component1()), - this.y.coerceIn(minimum.component2(), maximum.component2()), - this.z.coerceIn(minimum.component3(), maximum.component3()), - this.w.coerceIn(minimum.component4(), maximum.component4())) - - fun coerceAtLeast(value: IStruct4i): Vector4i { val (x, y, z, w) = value; return coerceAtLeast(x, y, z, w) } - fun coerceAtMost(value: IStruct4i): Vector4i { val (x, y, z, w) = value; return coerceAtMost(x, y, z, w) } - fun coerceAtLeast(value: Vector4i): Vector4i { val (x, y, z, w) = value; return coerceAtLeast(x, y, z, w) } - fun coerceAtMost(value: Vector4i): Vector4i { val (x, y, z, w) = value; return coerceAtMost(x, y, z, w) } - - fun toDoubleVector() = Vector4d(x.toDouble(), y.toDouble(), z.toDouble(), w.toDouble()) - fun toFloatVector() = Vector4f(x.toFloat(), y.toFloat(), z.toFloat(), w.toFloat()) - - override fun toString(): String { - return "[$x, $y, $z, $w]" - } - - companion object { - @JvmField val ZERO = Vector4i() - @JvmField val POSITIVE_X = Vector4i(x = 1) - @JvmField val NEGATIVE_X = Vector4i(x = -1) - @JvmField val POSITIVE_Y = Vector4i(y = 1) - @JvmField val NEGATIVE_Y = Vector4i(y = -1) - @JvmField val POSITIVE_Z = Vector4i(z = 1) - @JvmField val NEGATIVE_Z = Vector4i(z = -1) - @JvmField val POSITIVE_W = Vector4i(w = 1) - @JvmField val NEGATIVE_W = Vector4i(w = -1) - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 602a7e7..be6a8e5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -22,6 +22,4 @@ plugins { rootProject.name = "kommons" include("guava") include("gson") -include("linear-algebra") -include("gson-linear-algebra") include("kommons-mc")