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.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<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) {
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) {

View File

@ -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) {

View File

@ -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)

View File

@ -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(