IIIF / api

Source for API and model specifications documents (api and model)
http://iiif.io/api
105 stars 54 forks source link

Definition of RotateTransform in the draft 3D API #2285

Open vincentmarchetti opened 4 months ago

vincentmarchetti commented 4 months ago

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

  1. 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.

  2. 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.

JulieWinchester commented 3 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:

  1. 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.

  2. 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.

JulieWinchester commented 3 months ago

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.