forked from kscience/kmath
Basic geometry
This commit is contained in:
parent
30730f1051
commit
1015e238f1
@ -3,6 +3,8 @@ package scientifik.kmath.operations
|
||||
fun <T> Space<T>.sum(data: Iterable<T>): T = data.fold(zero) { left, right -> add(left, right) }
|
||||
fun <T> Space<T>.sum(data: Sequence<T>): T = data.fold(zero) { left, right -> add(left, right) }
|
||||
|
||||
fun <T : Any, S : Space<T>> Iterable<T>.sumWith(space: S): T = space.sum(this)
|
||||
|
||||
//TODO optimized power operation
|
||||
fun <T> RingOperations<T>.power(arg: T, power: Int): T {
|
||||
var res = arg
|
||||
|
9
kmath-geometry/build.gradle.kts
Normal file
9
kmath-geometry/build.gradle.kts
Normal file
@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
}
|
||||
|
||||
kotlin.sourceSets.commonMain {
|
||||
dependencies {
|
||||
api(project(":kmath-core"))
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package scientifik.kmath.geometry
|
||||
|
||||
import scientifik.kmath.linear.Point
|
||||
import scientifik.kmath.operations.SpaceElement
|
||||
import scientifik.kmath.operations.invoke
|
||||
import kotlin.math.sqrt
|
||||
|
||||
|
||||
interface Vector2D : Point<Double>, Vector, SpaceElement<Vector2D, Vector2D, Euclidean2DSpace> {
|
||||
val x: Double
|
||||
val y: Double
|
||||
|
||||
override val size: Int get() = 2
|
||||
|
||||
override fun get(index: Int): Double = when (index) {
|
||||
1 -> x
|
||||
2 -> y
|
||||
else -> error("Accessing outside of point bounds")
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<Double> = listOf(x, y).iterator()
|
||||
|
||||
override val context: Euclidean2DSpace get() = Euclidean2DSpace
|
||||
|
||||
override fun unwrap(): Vector2D = this
|
||||
|
||||
override fun Vector2D.wrap(): Vector2D = this
|
||||
}
|
||||
|
||||
val Vector2D.r: Double get() = Euclidean2DSpace.run { sqrt(norm()) }
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y)
|
||||
|
||||
private data class Vector2DImpl(
|
||||
override val x: Double,
|
||||
override val y: Double
|
||||
) : Vector2D
|
||||
|
||||
/**
|
||||
* 2D Euclidean space
|
||||
*/
|
||||
object Euclidean2DSpace : GeometrySpace<Vector2D> {
|
||||
fun Vector2D.norm(): Double = sqrt(x * x + y * y)
|
||||
|
||||
override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm()
|
||||
|
||||
override fun add(a: Vector2D, b: Vector2D): Vector2D =
|
||||
Vector2D(a.x + b.x, a.y + b.y)
|
||||
|
||||
override fun multiply(a: Vector2D, k: Number): Vector2D =
|
||||
Vector2D(a.x * k.toDouble(), a.y * k.toDouble())
|
||||
|
||||
override val zero: Vector2D = Vector2D(0.0, 0.0)
|
||||
|
||||
override fun Vector2D.dot(other: Vector2D): Double =
|
||||
x * other.x + y * other.y
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package scientifik.kmath.geometry
|
||||
|
||||
import scientifik.kmath.linear.Point
|
||||
import scientifik.kmath.operations.SpaceElement
|
||||
import kotlin.math.sqrt
|
||||
|
||||
|
||||
interface Vector3D : Point<Double>, Vector, SpaceElement<Vector3D, Vector3D, Euclidean3DSpace> {
|
||||
val x: Double
|
||||
val y: Double
|
||||
val z: Double
|
||||
|
||||
override val size: Int get() = 3
|
||||
|
||||
override fun get(index: Int): Double = when (index) {
|
||||
1 -> x
|
||||
2 -> y
|
||||
3 -> z
|
||||
else -> error("Accessing outside of point bounds")
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<Double> = listOf(x, y, z).iterator()
|
||||
|
||||
override val context: Euclidean3DSpace get() = Euclidean3DSpace
|
||||
|
||||
override fun unwrap(): Vector3D = this
|
||||
|
||||
override fun Vector3D.wrap(): Vector3D = this
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun Vector3D(x: Double, y: Double, z: Double): Vector3D = Vector3DImpl(x, y, z)
|
||||
|
||||
val Vector3D.r: Double get() = Euclidean3DSpace.run { sqrt(norm()) }
|
||||
|
||||
private data class Vector3DImpl(
|
||||
override val x: Double,
|
||||
override val y: Double,
|
||||
override val z: Double
|
||||
) : Vector3D
|
||||
|
||||
object Euclidean3DSpace : GeometrySpace<Vector3D> {
|
||||
override val zero: Vector3D = Vector3D(0.0, 0.0, 0.0)
|
||||
|
||||
fun Vector3D.norm(): Double = sqrt(x * x + y * y + z * z)
|
||||
|
||||
override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm()
|
||||
|
||||
override fun add(a: Vector3D, b: Vector3D): Vector3D =
|
||||
Vector3D(a.x + b.x, a.y + b.y, a.z + b.z)
|
||||
|
||||
override fun multiply(a: Vector3D, k: Number): Vector3D =
|
||||
Vector3D(a.x * k.toDouble(), a.y * k.toDouble(), a.z * k.toDouble())
|
||||
|
||||
override fun Vector3D.dot(other: Vector3D): Double =
|
||||
x * other.x + y * other.y + z * other.z
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package scientifik.kmath.geometry
|
||||
|
||||
import scientifik.kmath.operations.Space
|
||||
|
||||
interface Vector
|
||||
|
||||
interface GeometrySpace<V: Vector>: Space<V> {
|
||||
/**
|
||||
* L2 distance
|
||||
*/
|
||||
fun V.distanceTo(other: V): Double
|
||||
|
||||
/**
|
||||
* Scalar product
|
||||
*/
|
||||
infix fun V.dot(other: V): Double
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package scientifik.kmath.geometry
|
||||
|
||||
data class Line<V: Vector>(val base: V, val direction: V)
|
||||
|
||||
typealias Line2D = Line<Vector2D>
|
||||
typealias Line3D = Line<Vector3D>
|
@ -0,0 +1,4 @@
|
||||
package scientifik.kmath.geometry
|
||||
|
||||
interface ReferenceFrame {
|
||||
}
|
@ -41,5 +41,6 @@ include(
|
||||
":kmath-io",
|
||||
":kmath-dimensions",
|
||||
":kmath-for-real",
|
||||
":kmath-geometry",
|
||||
":examples"
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user