minor fix to Root rotations

This commit is contained in:
Alexander Nozik 2023-09-16 12:27:09 +03:00
parent 6a801f9999
commit 92bfb173d8
4 changed files with 20 additions and 17 deletions

View File

@ -5,12 +5,17 @@ import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.parseAsName
import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.plus
import space.kscience.dataforge.names.withIndex 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.MutableVisionContainer
import space.kscience.visionforge.isEmpty import space.kscience.visionforge.isEmpty
import space.kscience.visionforge.set import space.kscience.visionforge.set
import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.*
import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY 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() private val volumesName = Name.EMPTY //"volumes".asName()
@ -28,12 +33,10 @@ private data class RootToSolidContext(
val colorCache: MutableMap<Meta, String> = mutableMapOf(), val colorCache: MutableMap<Meta, String> = mutableMapOf(),
) )
// converting to XYZ to TaitBryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix // apply rotation from a matrix
private fun Solid.rotate(rot: DoubleArray) { private fun Solid.rotate(rot: DoubleArray) {
val xAngle = atan2(-rot[5], rot[8]) val matrix = VirtualMatrix(3, 3) { i, j -> rot[i * 3 + j] }
val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2))) quaternion = Quaternion.fromRotationMatrix(matrix)
val zAngle = atan2(-rot[1], rot[0])
rotation = Float32Vector3D(xAngle, yAngle, zAngle)
} }
private fun Solid.translate(trans: DoubleArray) { private fun Solid.translate(trans: DoubleArray) {

View File

@ -15,13 +15,13 @@ import kotlin.math.sin
fun main() = serve { fun main() = serve {
val azimuth = 60.degrees // val azimuth = 60.degrees
val inclination = 15.degrees // val inclination = 15.degrees
val direction = with(QuaternionField) { // val direction = with(QuaternionField) {
Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) * // Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) *
Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis) // Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis)
} // }
//val direction2 = Quaternion.fromEuler(Angle.zero, Angle.piDiv2 - inclination, -azimuth, RotationOrder.ZYX) //val direction2 = Quaternion.fromEuler(Angle.zero, Angle.piDiv2 - inclination, -azimuth, RotationOrder.ZYX)
@ -43,7 +43,7 @@ fun main() = serve {
solidGroup("frame") { solidGroup("frame") {
z = 60 z = 60
val antenna = solidGroup("antenna") { solidGroup("antenna") {
axes(200) axes(200)
tube(40, 10, 30) tube(40, 10, 30)
sphereLayer(100, 95, theta = PI / 6) { sphereLayer(100, 95, theta = PI / 6) {

View File

@ -206,7 +206,7 @@ public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f)
/** /**
* Raw quaternion value defined in properties * Raw quaternion value defined in properties
*/ */
public var Solid.quaternionValue: Quaternion? public var Solid.quaternionOrNull: Quaternion?
get() = properties.getValue(ROTATION_KEY)?.list?.let { get() = properties.getValue(ROTATION_KEY)?.list?.let {
require(it.size == 4) { "Quaternion must be a number array of 4 elements" } 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) 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 * Quaternion value including information from euler angles
*/ */
public var Solid.quaternion: Quaternion public var Solid.quaternion: Quaternion
get() = quaternionValue ?: Quaternion.fromEuler( get() = quaternionOrNull ?: Quaternion.fromEuler(
rotationX.radians, rotationX.radians,
rotationY.radians, rotationY.radians,
rotationZ.radians, rotationZ.radians,
rotationOrder rotationOrder
) )
set(value) { set(value) {
quaternionValue = value quaternionOrNull = value
} }
public var Solid.scaleX: Number by float(X_SCALE_KEY, 1f) public var Solid.scaleX: Number by float(X_SCALE_KEY, 1f)

View File

@ -41,7 +41,7 @@ public fun Object3D.updatePosition(vision: Vision) {
if (vision is Solid) { if (vision is Solid) {
position.set(vision.x, vision.y, vision.z) position.set(vision.x, vision.y, vision.z)
val quaternion = vision.quaternionValue val quaternion = vision.quaternionOrNull
if (quaternion != null) { if (quaternion != null) {
setRotationFromQuaternion( setRotationFromQuaternion(