Consequent rotations changing the axis of rotation

When dealing with rotation sequences, it’s often said that each rotation rotates the coordinate system thus affecting the subsequent rotations by changing their axes (their frame of reference).
I’ve found that hard to grasp at first for the following reason: if you rotate a point “A” around some axis by some angle to result in point “B” then why is it any different from starting with point “B” in the first place?

Let’s say you rotate point A = (1, 0, 0) around the Y axis 90 degrees arriving at B = (0, 0, -1). Now with that rotation you supposedly have rotated everything around Y by 90 degrees, including the axes so for example the Z axis has rotated into the original X axis). If you next rotate around Z that will rotate around the new Z axis (the original X axis) and not the original Z axis. But how is that different from starting with point B in the first place and rotating around Z without any previous rotations? How does the second rotation “know” about the first one?

The answer to this simple (or stupid) question is that of course it doesn’t, and rotations don’t rotate the axes.
Assume we have this rotation sequence: X, Y, Z. We can look at this one of two ways:
1. First rotate around the original X axis, then the rotated Y axis, finally around the rotated Z axis (that we rotated twice with the first 2 rotations).
2. Or first rotate around the original Z axis, then the original Y axis, finally around the original X axis.
These 2 ways are equivalent and it’s only a matter of how you think about it. Note the order of axes in the second version is reversed and it uses the original (fixed) axes. This is true generally: if you reverse the order of axes, you can switch between using fixed vs. rotated ones.
The first one is called “Intrinsic”, the second one is called “Extrinsic” and it’s described pretty well on Wikipedia (see conversion between the two):

What happens is that if you look at rotation sequences in the “correct” (or actual) order ie. the order in which they are mathematically executed one after another then the axes remain fixed of course. If you look at it in reversed order then you have to look at it like each rotation changes the axes for upcoming rotations.
Why is the first (intrinsic) method used frequently? Sometimes it’s easier to orient your object thinking about rotations like they change the orientation of the coordinate system, after the first rotation you don’t want to think about the original axis but rather the object’s local axes, that are the rotated ones.
Another reason is that when working with transformations, eg. rotation matrices (but the same applies to quaternions), you usually do this (pseudo code):

// start with the identity matrix
rotationMatrix = new Matrix4();
// right multiply rotationMatrix by rotationMatrixAroundX, then Y, then Z:
rotationMatrix = rotationMatrix * rotationMatrixAroundX;
rotationMatrix = rotationMatrix * rotationMatrixAroundY;
rotationMatrix = rotationMatrix * rotationMatrixAroundZ;

Eventually when you apply the rotation to a point (typically in the vertex shader), you do this:

pos = rotationMatrix * localPos;

so what you actually do is this:

pos = rotationMatrixAroundX * rotationMatrixAroundY * rotationMatrixAroundZ * localPos;

You can see that the actual order in which rotations are applied is: Z, Y, X (because rotationMatrixAroundZ is closest to the point) which is the reversed order in which you multiplied the rotation matrix. This is the result of you right multiplying (post-multiplying) the rotation matrix to calculate the rotation result matrix and left multiplying the point with this result matrix. If you used left multiply (pre-multiply) when multiplying the matrices, the order would be reversed.
Again, you can look at this in the actual execution order of Z, Y, X with all axis remaining fixed or in the order of X, Y, Z while each rotation changes the axes for subsequent rotations.

This is not a matter only for rotation matrices, the same idea applies when using quaternions if you’re thinking in rotation sequences around some axes (eg. when using Euler angles).

If you use three.js you can rotate an object simply like this:

mesh.rotation.x = angleXInRadians;
mesh.rotation.y = angleYInRadians;
mesh.rotation.z = angleZInRadians;

The actual order of execution in three.js is: Z, Y, X (it doesn’t matter in what order you set the rotation properties). Here’s a demo to play with:!/c-cs291/l-91073092/m-123949249

You can see that if you look at this the “Intrinsic” way, you can rotate first around X, which rotates all other axes, then you can rotate around the new Y (call it Y’) which rotates the new Z (z’) to yet another new Z (Z”) and finally you can rotate around that Z”.
Or you can look at it in the actual order (“Extrinsic” way), so first rotate around Z which doesn’t rotate any axes, then rotate around the (original, unrotated) Y axis, finally rotate around the original X axis.

I plan to write another post on something related with more examples (especially if there’s interest).

Binding issue with spark DataGrid’s selectedItem property

I was working with the spark DataGrid component for a Flex project and I wanted to bind a button’s enabled property to the DataGrid’s selectedItem (or selectedIndex) property so that the user can only click on the button if the selectedItem is not null. The code would look something like this:
<s:Button enabled="{myDataGrid.selectedItem}" />

I figured this would be as simple as it sounds, but I encountered some problems with it, particularly in 2 scenarios:

  1. When I delete the currently selected item by removing it from the dataprovider, the binding on selectedItem will not trigger and the button will remain in enabled=”true” state.
  2. When I assign a new dataProvider to the DataGrid while it has an item currently selected, the same thing happens: the getter method for selectedItem will not get updated for binding.

Interesting is that the selectedItem (selectedIndex, etc) properties are actually accurate at all times, but for some reason their getter methods are not always updated.
Note that the AdvancedDataGrid and the mx version of DataGrid doesn’t seem to have this issue, they work fine. The DataGrid I encounter this problem with is the spark one that comes with Flex SDK 4.5.1.
I made a quick fix to solve this problem.

You can see the original version on the left side with the issues, and the fixed one on the right. If you select an item on the left version and click on either the remove or the change button then the remove button will still be enabled and the selectedIndex will point to the previously selected item despite there’s no currently selected item. You can also trace the selectedItem and selectedIndex properties to see that their values are actually correct, they are just not getting updated for the use of binding.

[kml_flashembed movie=”” width=”490″ height=”357″ /]
It’s easy to apply a quick fix for these, the idea is to dispatch the FlexEvent.VALUE_COMMIT Event when needed. I extended the DataGrid class to come up with a reusable solution (until Adobe fixes this). Here’s how for the above scenarios respectively:

1. By overriding the set dataProvider setter method, you can add an EventListener on the dataProvider for its CollectionEvent.COLLECTION_CHANGE Event, and in that handler if a row was removed you just dispatch the VALUE_COMMIT FlexEvent which in turn will cause the required properties to be updated for binding.

2. In the same dataProvider setter method you can assign null to the selectedItem prior to calling super.dataProvider = value;
In this case, since you have the old dataProvider at the time of setting the selectedItem (so the selectedItem is not null yet) this will trigger the VALUE_COMMIT Event to be dispatched.
selectedItem = null;
super.dataProvider = value;

2.B Alternatively there’s another workaround. We can set selectedItem to null after the dataProvider is set. In this case though we need to manually dispatch the VALUE_COMMIT Event because the selectedItem is set to null after the dataProvider is set and at that point the Grid’s clearSelection method finds as the selection hasn’t changed (because selectedItem is already null after setting dataProvider to a new value) so it won’t dispatch the VALUE_COMMIT Event.
We still need to set selectedItem to null even though it’s already null because otherwise the selectedIndex and other corresponding properties wouldn’t get updated for binding (only the selectedItem property).
super.dataProvider = value;
selectedItem = null;
dispatchEvent( new FlexEvent(FlexEvent.VALUE_COMMIT) );

Here’s the BindableDataGrid class in place of the spark DataGrid that includes these fixes:

Update: Another scenario has been found thanks to MrBen:
If you remove the currently selected item by assigning a filterFunction to the dataProvider and calling refresh on it to update the view the usual issue happens: the selectedItem and selectedIndex properties have their correct values but their getter methods will not get updated. It’s easy to fix this though, we just need to dispatch the VALUE_COMMIT Event when refreshing is called on the dataProvider. The BindableDataGrid is updated to have this fix too.