From 92bfb173d8b49cb8b951a1b3f665ec310188069c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 16 Sep 2023 12:27:09 +0300 Subject: [PATCH] minor fix to Root rotations --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 15 +++++++++------ demo/playground/src/jvmMain/kotlin/antenna.kt | 14 +++++++------- .../space/kscience/visionforge/solid/Solid.kt | 6 +++--- .../visionforge/solid/three/ThreeFactory.kt | 2 +- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 07112c06..ef72de52 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -5,12 +5,17 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.withIndex +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.geometry.fromRotationMatrix +import space.kscience.kmath.linear.VirtualMatrix import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.isEmpty import space.kscience.visionforge.set import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY -import kotlin.math.* +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin private val volumesName = Name.EMPTY //"volumes".asName() @@ -28,12 +33,10 @@ private data class RootToSolidContext( val colorCache: MutableMap = mutableMapOf(), ) -// converting to XYZ to Tait–Bryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix +// apply rotation from a matrix private fun Solid.rotate(rot: DoubleArray) { - val xAngle = atan2(-rot[5], rot[8]) - val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2))) - val zAngle = atan2(-rot[1], rot[0]) - rotation = Float32Vector3D(xAngle, yAngle, zAngle) + val matrix = VirtualMatrix(3, 3) { i, j -> rot[i * 3 + j] } + quaternion = Quaternion.fromRotationMatrix(matrix) } private fun Solid.translate(trans: DoubleArray) { diff --git a/demo/playground/src/jvmMain/kotlin/antenna.kt b/demo/playground/src/jvmMain/kotlin/antenna.kt index 6e9b759b..5ec997f7 100644 --- a/demo/playground/src/jvmMain/kotlin/antenna.kt +++ b/demo/playground/src/jvmMain/kotlin/antenna.kt @@ -15,13 +15,13 @@ import kotlin.math.sin fun main() = serve { - val azimuth = 60.degrees - val inclination = 15.degrees +// val azimuth = 60.degrees +// val inclination = 15.degrees - val direction = with(QuaternionField) { - Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) * - Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis) - } +// val direction = with(QuaternionField) { +// Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) * +// Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis) +// } //val direction2 = Quaternion.fromEuler(Angle.zero, Angle.piDiv2 - inclination, -azimuth, RotationOrder.ZYX) @@ -43,7 +43,7 @@ fun main() = serve { solidGroup("frame") { z = 60 - val antenna = solidGroup("antenna") { + solidGroup("antenna") { axes(200) tube(40, 10, 30) sphereLayer(100, 95, theta = PI / 6) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 8b719b54..f33573d7 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -206,7 +206,7 @@ public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f) /** * Raw quaternion value defined in properties */ -public var Solid.quaternionValue: Quaternion? +public var Solid.quaternionOrNull: Quaternion? get() = properties.getValue(ROTATION_KEY)?.list?.let { require(it.size == 4) { "Quaternion must be a number array of 4 elements" } Quaternion(it[0].float, it[1].float, it[2].float, it[3].float) @@ -229,14 +229,14 @@ public var Solid.quaternionValue: Quaternion? * Quaternion value including information from euler angles */ public var Solid.quaternion: Quaternion - get() = quaternionValue ?: Quaternion.fromEuler( + get() = quaternionOrNull ?: Quaternion.fromEuler( rotationX.radians, rotationY.radians, rotationZ.radians, rotationOrder ) set(value) { - quaternionValue = value + quaternionOrNull = value } public var Solid.scaleX: Number by float(X_SCALE_KEY, 1f) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 46e3d41b..122a2c30 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -41,7 +41,7 @@ public fun Object3D.updatePosition(vision: Vision) { if (vision is Solid) { position.set(vision.x, vision.y, vision.z) - val quaternion = vision.quaternionValue + val quaternion = vision.quaternionOrNull if (quaternion != null) { setRotationFromQuaternion(