Helical Axis calculation and animation
Input: filtered xyz points and marker location file - same files as used for calculating absoluteTform files
User input process and Calculations:
Start the process by typing "helicalMaya" into Matlab. This launches the first script for calculating the helical axes.
User is asked to select the xyzpts file and marker location file. Next, a prompt appears asking for the downsample rate. If the user wants to use all the points in the calculations, enter a value of 1. If the user wants to downsample the data, then enter the desired rate of downsampling. For example, if the user puts in 10, the downsample goes through the xyzpts data and takes every 10th point and uses it in the helical axes calculations. Note that the absoluteTform file (or the xyzpts file) need to be downsampled separately as well to have the bone animation match the helical axes animations.
User is prompted to select the markers for the proximal bone from a list, then the distal bone markers form a second list. This is similar to the absoluteTform process - the marker position data is appended to the first none Nan frame of the xyzpts data and the markers the user specified are assigned to the proximal and distal bones (indexed for later use).
User is asked to enter a velocity window. This will be used in the helicalAxesCalc script to calculate the instantaneous velocity. This value was initial set at 25 as that is the approximate length of one pig chewing cycle.
The global transforms are calculated for both bones. This is the same process used in the SVD rigid body procedure. The svdrigid script is called in the process and outputs the rotation and translation for each bone at each time step. This is a relative transform. The transform is put into the RTto4x4 script to turn it into a transform matrix and then is turned into an absolute transformation matrix using the same calculations as the rigidBody script, though the rigidBody script itself is not called. Now, the two bones have absolute transform matrices in global coordinates as they would if they were each run through the absoulteTform process, but left as 4x4 matrices rather than being turned into 1x16 Maya matrices.
The motion of the distal bone relative to the proximal is calculated by multiplying the inverse matrix of the proximal bone and the distal bone matrix together. This is done in the relativeBone2Bone script. This data is not actually outputted or used later in the script. It could be used to make an animation of the distal bone relative to the proximal, which is an option in IHAvis. A similar process occurs next where the xyzpts are multiplied by the inverse proximal bone matrix in the relativeMarkers2Bone script. This outputs xyz point data relative to the proximal bone. This is what is used to calculate the helical axes. At this point, the axes coming out of this script are the helical axes relative to the proximal bone (so would need to be put in an animation where the distal bone moves relative to the proximal to make sense). However, this will change later.
With the relative marker data, marker positions, marker assignments to bones and velocity window size, the helicalAxesCalc script is called.
In the helicalAxesCalc script, the marker assignments to bones are used to crop out the data columns that belong to the proximal and distal bones. The velocity window size is divided in half (and rounded if a decimal). This divided velocity window is used to define an area for calculating the instantaneous velocity. The halved velocity window is added and subtracted from the current frame to create an end and start point, respectively, for the velocity to be calculated. This is suppose to center the velocity calculation about the current frame, but this will not actually occur until the current frame is equal to ½ the velocity window size. So, at each frame the value of the point at the frame number ½ the velocity window size less than the current frame is subtracted from the point value at the frame number ½ the velocity window size greater than the current frame, then divided by the number of frames between these two points (usually this is equal to the velocity window size). This might be a place to improve the script - find a new way to calculate the instantaneous velocity more accurately.
Using the locations of the markers, the centroid is calculated for each bone. The location of the centroid is calculated by averaging the xyz position of all the markers in each bone for each frame. Thus it is the location of the center point of the shape defined by the makers in the bone over time. Next, the average landmark velocity is calculated in the same way the centroid was calculated except using the average velocity calculated earlier rather than the raw xyz points. With the centroids, the landmark inertia matrix is calculated. Then, the landmark velocity moment matrix is calculated with the centroids and the average landmark velocity. All of these calculations follow the methods of Sommer and Buczek 1990. From the landmark inertia matrix and landmark velocity moment matrix, the angular velocity vector is calculated also via the methods of Sommer and Buczek 1990. This vector is then normalized and used later to calculate the orientation of the helical axis. To calculate the location of a point on the helical axis and the sliding velocity, the methods of Sommer and Buczek 1990 is used. The angular velocity vector (V), normalized angular velocity vector (M), point on the axis (P) and the sliding velocity (S) are output and sent back to the helicalMaya script.
In the helicalMaya script, the outputs V, M and P from the helicalAxesCalc script are transformed back to world space. This is done via a script called relativeMarkers2Global, which uses the proximal bone transforms to undo what was done in the relativeMarkers2Bone script. The point on the helical axis is saved as it is - three numbers representing the xyz position. The angular velocity is added to the location of the point, and then the proximal bone location (from the transform) is subtracted. This is saved as a xyz point used to orient the helical axis. The sliding velocity is a small number, so it is multiplied by 100 to make it large enough to import into Maya without crashing. It is also repeated 3 times, so it can be imported as a xyz point. The final output of the Matlab scripts is a file with 9 columns - the xyz position of the point on the helical axis, the xyz position of the vector representing the orientation of the axis, and the sliding velocity of the axis three times.
The script to import the helical axis file is linked in the impdata2 script. The latest shelf button for importing data calls this script. The impdata2 user interface is the same as the impdata interface, but there is now an option to import helical axes in data type. The import process is a modified version of the xyz data point import procedure. The user selects the file and clicks import. The user is asked to name the axis. The script creates three locators, as occurs with the xyz import procedure. The three point locators are grouped under the name of the imported file. The script also calls another script, HelcialObject, which creates two cylinders which will be animated by the three points. The first cylinder is purple with a sphere on one end. It is given the name the user typed in. The second is wider and yellow. It is parented to the first cylinder and has the same name with "slider" appended to it.
The purple and yellow cylinders are point constrained by the locator representing the point on the helical axis. The cylinders are aim constrained by the locator representing the directional vector of the helical axis. The yellow cylinder is animated to have its Z axis scale with the sliding velocity, so it shrinks and lengthens.