The distinctive design of the accordion lamp may look simple to rig, but don’t be fooled. As the lamp expands or contract the joints at each end of the arms moves in a circular motion, rendering the standard constrains useless.
The accordion lamp consists of a series of individual arms which are mounted in pairs creating an X-Shape. Rotating any of the arms will cause all arms to rotate which either expand or contract the lamp. Start by open the scene Accordion_Lamp.scn. The scene consists of a number of null objects and the arms, which are parented under the null representing their respective centre joint.
Select the Center1 null, press [Ctrl] + [K] to open its Local Transform PPG. Right-click on the animation icon (the green divot) for the X Axis Position and choose Set Expression... The arms are distributed linearly between the base (the part attached to the wall mount) and the lamp and since there are 4 pairs we know that the first joint should be located at 1/8 of the distance to the End null. In the Editing Pane of the Expression Editor, enter 1/8*End.kine.local.posx and click the Apply button. Open the Local Transform PPG for the Center2, right-click on animation icon for the X Axis and enter 3/8*End.kine.local.posx as expression. Repeat the procedure for the Center3 (5/8*End.kine.local.posx) and Center4 (7/8*End.kine.local.posx) nulls.
To determine the Y position of the top joint of the arm (the arm’s rotation) you need another null object, but foremost you need Pythagorean Theorem. The theorem states that if you know the length of two sides of a right-angled triangle you can calculate the length of the third side (a2 + b2 = c2). The length of side a is the distance between the wall mount and the Center1 null. The length of side b is the distance between the center joint and the top joint of the arm, in this case 3.5 units. Select the Top_Joint1 null and open its Local Transform PPG. Right-click on the animation icon for the Y Position and choose Set Expression… Enter sqrt( pow( 3.5, 2 ) - pow( Center1.kine.global.posx, 2 )) in the editing pane and click the Apply button to apply the expression.
For the Top_Joint2 you must not only calculate the Y position but also the X position as this will change as the lamp expand or contract. Open the Top_Joint2’s Transform PPG and apply an expression to the X position. The joint will always be located at the middle of the Center1 and Center2 nulls, which you can calculate by adding their X positions and then divide it by 2. Enter ( Center1.kine.local.posx + Center2.kine.local.posx ) / 2 and click the Apply button. Close the Expression Editor and apply an expression to the Y Position. The length of side b is still 3.5 in this triangle, but side a equals half the distance between Center1 and Center2. Enter sqrt( pow( 3.5, 2 ) - pow( ( ctr_dist( Center1.kine.global.pos, Center2.kine.global.pos ) / 2 ), 2 ) ) and click the Apply button.
Select the Arm01 and from the Main Command Panel > Constrain menu choose Direction and pick the TopJoint1 null. Select Arm02, apply a Direction constraint but this time pick the TopJoint2 null. Repeat the last two steps for the Top_Joint3 and 4 and their respective arms.
The project files used in this tutorial can be found at: http://dl.dropbox.com/u/3834689/CaffeineAbuse/AccordionLampRig.zip
Once you’ve calculated the rotation for the first arm, you’ve essentially calculated the rotation for all arms. Rather than using the theorem and contains you can simply add an equal expression to the subsequent arms Z rotation, Arm01.kine.local.rotz to the odd arms and –Arm1.kine.local.rotz to the even.