forked from kscience/kmath
Add vector product to Euclidean3DSpace
This commit is contained in:
parent
db61f71440
commit
4871baf0e5
@ -9,7 +9,7 @@ kotlin.native.ignoreDisabledTargets=true
|
|||||||
org.gradle.configureondemand=true
|
org.gradle.configureondemand=true
|
||||||
org.gradle.jvmargs=-Xmx4096m
|
org.gradle.jvmargs=-Xmx4096m
|
||||||
|
|
||||||
toolsVersion=0.14.2-kotlin-1.8.10
|
toolsVersion=0.14.3-kotlin-1.8.20-RC
|
||||||
|
|
||||||
|
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
|
@ -78,8 +78,11 @@ public object Euclidean3DSpace : GeometrySpace<DoubleVector3D>, ScaleOperations<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun vector(x: Double, y: Double, z: Double): DoubleVector3D =
|
||||||
|
Vector3DImpl(x, y, z)
|
||||||
|
|
||||||
public fun vector(x: Number, y: Number, z: Number): DoubleVector3D =
|
public fun vector(x: Number, y: Number, z: Number): DoubleVector3D =
|
||||||
Vector3DImpl(x.toDouble(), y.toDouble(), z.toDouble())
|
vector(x.toDouble(), y.toDouble(), z.toDouble())
|
||||||
|
|
||||||
override val zero: DoubleVector3D by lazy { vector(0.0, 0.0, 0.0) }
|
override val zero: DoubleVector3D by lazy { vector(0.0, 0.0, 0.0) }
|
||||||
|
|
||||||
@ -100,6 +103,48 @@ public object Euclidean3DSpace : GeometrySpace<DoubleVector3D>, ScaleOperations<
|
|||||||
override fun DoubleVector3D.dot(other: DoubleVector3D): Double =
|
override fun DoubleVector3D.dot(other: DoubleVector3D): Double =
|
||||||
x * other.x + y * other.y + z * other.z
|
x * other.x + y * other.y + z * other.z
|
||||||
|
|
||||||
|
private fun leviCivita(i: Int, j: Int, k: Int): Int = when {
|
||||||
|
// even permutation
|
||||||
|
i == 0 && j == 1 && k == 2 -> 1
|
||||||
|
i == 1 && j == 2 && k == 0 -> 1
|
||||||
|
i == 2 && j == 0 && k == 1 -> 1
|
||||||
|
// odd permutations
|
||||||
|
i == 2 && j == 1 && k == 0 -> -1
|
||||||
|
i == 0 && j == 2 && k == 1 -> -1
|
||||||
|
i == 1 && j == 0 && k == 2 -> -1
|
||||||
|
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute vector product of [first] and [second]. The basis assumed to be right-handed if [rightBasis] is true and
|
||||||
|
* left-handed otherwise
|
||||||
|
*/
|
||||||
|
public fun vectorProduct(
|
||||||
|
first: DoubleVector3D,
|
||||||
|
second: DoubleVector3D,
|
||||||
|
rightBasis: Boolean = true,
|
||||||
|
): DoubleVector3D {
|
||||||
|
var x = 0.0
|
||||||
|
var y = 0.0
|
||||||
|
var z = 0.0
|
||||||
|
|
||||||
|
for (j in (0..2)) {
|
||||||
|
for (k in (0..2)) {
|
||||||
|
x += leviCivita(0, j, k) * first[j] * second[k]
|
||||||
|
y += leviCivita(1, j, k) * first[j] * second[k]
|
||||||
|
z += leviCivita(2, j, k) * first[j] * second[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vector(x, y, z) * (if (rightBasis) 1 else -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vector product with right basis
|
||||||
|
*/
|
||||||
|
public infix fun DoubleVector3D.cross(other: DoubleVector3D): Vector3D<Double> = vectorProduct(this, other)
|
||||||
|
|
||||||
public val xAxis: DoubleVector3D = vector(1.0, 0.0, 0.0)
|
public val xAxis: DoubleVector3D = vector(1.0, 0.0, 0.0)
|
||||||
public val yAxis: DoubleVector3D = vector(0.0, 1.0, 0.0)
|
public val yAxis: DoubleVector3D = vector(0.0, 1.0, 0.0)
|
||||||
public val zAxis: DoubleVector3D = vector(0.0, 0.0, 1.0)
|
public val zAxis: DoubleVector3D = vector(0.0, 0.0, 1.0)
|
||||||
|
@ -57,23 +57,39 @@ internal class Euclidean3DSpaceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun add() {
|
fun add() = with(Euclidean3DSpace) {
|
||||||
with(Euclidean3DSpace) {
|
assertVectorEquals(
|
||||||
assertVectorEquals(
|
vector(1.0, -2.0, 0.001),
|
||||||
vector(1.0, -2.0, 0.001),
|
vector(1.0, -2.0, 0.001) + zero
|
||||||
vector(1.0, -2.0, 0.001) + zero
|
)
|
||||||
)
|
assertVectorEquals(
|
||||||
assertVectorEquals(
|
vector(8.0, -3.0, 3.001),
|
||||||
vector(8.0, -3.0, 3.001),
|
vector(1.0, 2.0, 3.0) + vector(7.0, -5.0, 0.001)
|
||||||
vector(1.0, 2.0, 3.0) + vector(7.0, -5.0, 0.001)
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun multiply() {
|
fun multiply() = with(Euclidean3DSpace) {
|
||||||
with(Euclidean3DSpace) {
|
assertVectorEquals(vector(2.0, -4.0, 0.0), vector(1.0, -2.0, 0.0) * 2)
|
||||||
assertVectorEquals(vector(2.0, -4.0, 0.0), vector(1.0, -2.0, 0.0) * 2)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun vectorProduct() = with(Euclidean3DSpace) {
|
||||||
|
assertVectorEquals(zAxis, vectorProduct(xAxis, yAxis))
|
||||||
|
assertVectorEquals(zAxis, xAxis cross yAxis)
|
||||||
|
assertVectorEquals(-zAxis, vectorProduct(yAxis, xAxis))
|
||||||
|
assertVectorEquals(zAxis, vectorProduct(yAxis, xAxis, rightBasis = false))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun doubleVectorProduct() = with(Euclidean3DSpace) {
|
||||||
|
val a = vector(1, 2, -3)
|
||||||
|
val b = vector(-1, 0, 1)
|
||||||
|
val c = vector(4, 5, 6)
|
||||||
|
|
||||||
|
val res = a cross (b cross c)
|
||||||
|
val expected = b * (a dot c) - c * (a dot b)
|
||||||
|
assertVectorEquals(expected, res)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user