Open vincentmarchetti opened 8 months ago
I don't think I'm a huge fan of option 2. My preference here would be for us to avoid inferred properties, especially where it's difficult for an end user to immediately calculate the inferred value. I think for option 2, with the angle of rotation being the magnitude of the vector, that vector magnitude is an inferred value that will be pretty hard for end users to easily gauge.
I could see two possible ways to solve this:
We decide on a single approach that is going to be the easiest/most intuitive for end-users to work with. I think that a Euler transform probably meets that target, even if it creates some headaches in edge cases. I would think the rotation axes would be world (or local coordinate space) fixed, like for other transforms. If we are worried about things like Gimbal lock, I'm still wondering if we could allow users to specify the ordering of rotations, since changing up rotation order could help with that.
We add two separate rotation transforms, a RotateEulerTransform
and a RotateQuaternionTransform
. This way there is a transform that non-3D specialists can easily wrap their heads around, and one for 3D specialists who want to be very specific about things or who want to avoid any edge cases from Euler Transforms.
This was discussed during the TSG meeting on April 3rd. There was some general support for going for an initial "readable"/"simple" solution of RotateTransform specifying an Euler transform with a rotation ordering of XYZ (this ordering is the Three.js default) until we reach practical examples where this is insufficient. In contrast to this, there was also a point that if we are going for "simplest," the simplest solution is quaternions, and that quaternions are both extremely simple and also largely unreadable for most users.
A specific choice for the RotateTransform specification was implemented in the manifesto-3d code https://github.com/IIIF-Commons/manifesto-3d at commit 5e64e05; merged into master branch Aug 14 2024.
The xyz components of an IIIF RotateTransform instance are interpreted as Euler angle rotations in XYZ order, using fixed XYZ axes for each step. This is the ThreeJS standard.
Threejs-math utilitiies allow conversion to quaternion and axis-angle representations of a rotation.
I am suggesting clarifying the description of the RotateTransform. From what is in the existing document ( document temp-draft-4.md in the eds branch) it is unclear what is the geometric action of a RotateTransform that has non-zero values for several components, for example:
{ "type": "RotateTransform", "x": 69.28, "y": 69.28, "z": 69.28 }
There would be two plausible ways to interpret this
As an Euler angle description; that is the geometric interpretation might be "rotate about the z axis by 69.3 degrees, then about the (rotated) y axis by 69.3 degree, then again by the (doubly rotated) z axis by 69.3 " . This definition would need to be filled out by specifying which axes are rotated, in what order, and whether the rotation axis are world fixed or body fixed. This is the world of Euler and Tait-Bryan angles.
The geometric interpretation would be : "do a single rotation, counterclockwise, about the axis whose direction is that of the vector with those x,y,z coordinates and whose angle of rotation in degrees is the length of the vector" In the example above, the direction of the vector is the direction from corner to opposite corner of a cube with one corner at the origin; the length of the vector is (close to) 120.0 degrees. This rotation would rotate the x axis onto the y axis,the y axis onto the z axis, and the z axis onto the x axis.
I recommend that the 2nd choice, be chosen for the IIIF Presentation API in 3 dimensions.