In this example we will practice using the sinus function in conjunction with the Range Mapper. We will use the fan scene from the section about rotation and create an oscillating motion for the fan blades.
Principle and setup
The mechanical principle which causes a fan’s blades to oscillate is called crank or connecting rod mechanics. A wheel inside the fan head rotates slowly. Attached to this wheel is a moveable rod whose opposing end is connected to the base of the fan. This produces an oscillation that very accurately reflects a sinus. The mechanical function itself will be disregarded from this point on - what counts is the result (as usual when working in 3D). This is why we can use a sinus function in conjunction with a Range Mapper to make our fan blades oscillate.
First, let’s open the scene you saved from the rotation tutorial:
In order to be able to control the rotation as well as the oscillation of the fan blades we will have to add User Data. In the "Fan" Null Object’s attributes, select Manage User Data … from the
Add another User Data item. Set its Data Type to Separator as well and name it "Oscillation".
Next we need to add to User Data items for the oscillation itself: the oscillation frequency and its amplitude. The latter defines how far the fan will oscillate to each side.
Add a User Data item and name it "Frequency". Leave its Data Type set to Float and Units set to Real.
Add another User Data item, name it "Amplitude" and set its Unit parameter to Degree.
Click on the OK button to close the window. The User Data information can now be viewed in the fan’s Attribute Manager settings.
Expanding the Expression
Double-click on the XPresso tag to open the XPresso Editor window. It contains the Expression that we created in our rotation example.
First we will, of course, require access to our newly-created User Data items. To do so we will create an output Port for our "Fan" Object Node.
We will now create the oscillating movement. Fortunately we will not have to do the math ourselves. This will be done by a special Trigonometric Node that we will now create (XPresso/Calculate).
We want the fan head to oscillate back and forth while the animation runs. This means that the oscillating movement must correlate to the length of the animation. For this we need a Time Node, which was already added in the section about rotation. This Node outputs the current animation time in seconds via its Real output Port. This temporal value must be multiplied by the desired frequency in order to define how quickly the fan hed should oscillate. Create a new Math Node (XPresso/Calculate). In its Attribute Manager settings, set Function to Multiply. Connect the Node’s lower input Port with the "Fan" Object Node’s Frequency output Port. Connect the new Math Node’s output Port to the Trigonometric Node’s input Port.
As you my remember from math class, a sinus oscillation repeats itself after a period equal to Pi. In order to get a realistic oscillation frequency we must first multiply the temporal value by Pi. To do so we must create another Math Node and set its Function to Multiply as well. We will also create a Constant Node and set its Constant value to PI. Connect the new Math Node’s lower input Port with the Constant Node’s output Port and the Math Node’s upper input Port with the Time Node’s output Port. Connect the Math Node’s output Port with the previously created Math Node’s remaining input Port.
The Trigonometric Node’s output Port now supplies us with a smooth oscillating movement with exactly the right frequency, which we defined in the User Data settings. However, the values of this oscillation only range from 1 to -1 and we must convert them so they reflect the value range of our amplitude. This is were the Range Mapper Node comes in. With it a value range can be carried over to another region and will be able to convert the sinus range of 1 - -1 to the correct amplitude range. Create a Range Mapper Node (XPresso/Calculate) and connect its input Port with the Trigonometric Node’s output Port.
If we take a look at the Range Mapper Node’s parameters in the Attribute Manager we will see that the Input Lowerand Input Upper values are set to 0 and 1, respectively, and don’t yet reflect the value range of our sinus function. Therefore, change these values to -1 and 1, respectively. We now have to set the Output Lower and Output Upper values in accordance with the amplitude values. Don’t forget to set the Output Range parameter to Degree since we want to control the rotation of the fan head using these values.
Create two new input Ports for the Range Mapper Node: Output Lower and Output Upper. Connect the Output Upper input Port with the "Fan" Object Node’s Amplitude output Port.
By connecting the Output Upper Port with the Amplitude Port the fan head can rotate through the maximum amplitude range in a single direction. As long as the Output Lower value is equal to 0° this will only work in one direction (e.g., if Amplitude=45° the fan head will only oscillate between 0° and 45°). However, we want the fan head to oscillate in both directions (e.g., -45° - 45°, which means the negative amplitude must be used as the Output Lower value). To achieve this we will create a new Negate Node (XPresso/Calculate). Connect the "Fan" Node’s Amplitude output Port with the Negate Node’s input Port; connect the Negate Node’s output Port with the Range Mapper Node’s Output Lower Port.
All that remains to be done is to pass on the result that the Range Mapper Node produces to the fan head. To do so, select the "Head" Null Object in the Object Manager and drag it into the XPresso Editor window. A new Object Node named "Head" will automatically be created. Create a new Rotation.H input Port for this Node (Coordinates/Rotation) and connect this Port with the Range Mapper Node’s output Port.
We can now close the XPresso Editor window. If we set the "Fan" Null Object’s Frequency value to 0.5 and its Amplitude value to 45° the fan head will oscillate back and forth.