Showing posts with label functions. Show all posts
Showing posts with label functions. Show all posts

Tuesday, 22 April 2014

Lesson 11: Multiple animations (part 3)

In the previous lesson, we looked at a sequential animation where a pair of doors opened, followed by a drawbar sliding across. But the animation only worked in one direction because the opening doors were linked to the onClick handler so they always began first, even when reversing the animation. Now we shall look at how to make the animation sequence work correctly in both directions in a copy of the last version (now called "DC7").

The principle then is to have one animation, the Timeline, and link each door and the drawbar to this attribute. Let's start by examining the values we are working with.

Door 1 (LeftAngle) begins at -90 when open and ends at 0 when closed
Door 2 (RightAngle) begins at -90 when open and ends at -180 when closed
The Drawbar (BarPosition) begins at -210 when drawn back and ends at -5 when closed
The Timeline will go from 0 to 100 in 1.1 seconds.

As a chart, this is:

Time 0 seconds 0.5 seconds 0.6 seconds 1.1 seconds
Timeline 0 45% 55% 100%
LeftAngle -90 0 0 0
RightAngle -90 -180 -180 -180
BarPosition -210 -210 -210 -5
Process Start doors End doors Starts bar End bar

Notes: the % in the Timeline isn't included when we enter actual values, it's just there to show that the Timeline is like a counter going from 0 to 100% (completed). The Process when reversed, would be "End Doors - Start Doors - End Drawbar - Start Drawbar".

The first thing to do is to remove all the formulas and functions from the main "DC7" attributes (but leave the formulas in the subcomponents linking the Doors' RotZ to LeftAngle and RightAngle, and the Drawbar X position to BarPosition). Your Components Attributes window should look like this:

Now we add the single animation to the onClick attribute:

ANIMATECUSTOM("Timeline",1.1,0,0,0,100)

This is almost the same as the one we used in the previous lesson except that Timeline is now going from 0 (%) to 100 (%) and the easing is zero-zero since I want no change in acceleration. Clicking on the component now seems to have no effect but, if you make the Timeline visible, you can see it changing from 0 to 100 and back on each click.

(If you have forgotten how to make an attribute visible, click on the Details button on the right of the Timeline which looks like a menu combined with an arrow (see image below). Change "Display Rule" to "Users can see this attribute" and Apply. Now, if you have the Component Options window open when you click, you can see the value of the Timeline changing.)

The Details button, used to make the Timeline attribute visible


The formulas

Now for the formulas. If we start with the left door, we see that when Timeline is zero, LeftAngle must equal -90 and, when Timeline is 45, it must equal 0. If we add 90 first to get rid of the negative numbers (which can be confusing) we find that


0 Timeline = 0 LeftAngle
45 Timeline = 90 LeftAngle

and the formula is therefore:

LeftAngle = (Timeline * 2) - 90

(The brackets aren't necessary because of the rules of algebra but they make things clearer.)

When working out a formula, remember to add some intermediate angles in the calculation to check. In this case. 22.5 would be halfway along the Timeline and the LeftAngle would be -45 which, when I check the calculation, works out correctly. This is where the spreadsheet comes in useful.

The formula that we need to enter in the LeftAngle then is:

=IF(Timeline>45,0,Timeline*2-90)

Meaning: if the Timeline is greater than 45, set it to zero (closed), else animate it.
 Enter this, click on the component and you should see the left door open and close.

Note: the fact that the Timeline value is exactly half the LeftAngle is coincidence. It makes it a bit easier but isn't important.

For the second door, we need:

0 Timeline = -90 RightAngle
45 Timeline = -180 RightAngle

A formula I worked out for this is:

RightAngle = 0 - ( 90 + ( Timeline * 2 ) )

 thus

=IF( Timeline>45, -180, 0-(90+(Timeline*2)) )

So now, clicking the model opens both Doors.

Note that, after the Doors open, the animation runs on for 0.6 seconds with nothing apparently happening so don't click again too soon after the first click. Allow the animation time to finish.

Finally the Drawbar where we need:

55 Timeline = -210 BarPosition
100 Timeline = -5 BarPosition

Thanks to Excel, I find that the formula is:

BarPosition = (4.5556 * Timeline) - 460.5

so the formula for BarPosition is:

=IF(Timeline<55,-210,4.5556*Timeline-460.5)

Now, click on the component and two animations work together, both opening and closing.
The final settings:

Creating timelines and linking multiple animations is tricky, involving caeful maths and logical thinking, but the results can be very pleasing.

The final model is available on 3D Warehouse at https://3dwarehouse.sketchup.com/model.html?id=u9644e7be-7be5-4764-a2e6-785d96c41259

Monday, 21 April 2014

Lesson 10: Multiple animations (part 2)

Sequential animations

While simultaneous animations are easily produced by placing them together in an attribute, the sequential animation is more complicated. Basically one animation, often an abstract custom attribute, is begun as normal, usually by an onClick formula, while the others are controlled by accessing the value of the first.

As an example, let's elaborate the opening doors we created in Lesson 9. In castles, the main doors were often secured by sliding a wooden beam across when closed so we shall add this to the twin doors. Our animation will consist of the two doors closing and then, once the doors are closed, the drawbar will slide across.

First duplicate the two door component we created in "DC5" and rename it as "DC6". Within the component, create a rectangle named "Drawbar" and position it in the final, closed position as below. Add the X attribute to the Drawbar and make a note of its value.

 Next we need to move the elements to their 'start' postion, so change the Doors' "RotZ" values so they are both open (remembering that we are changing the custom attributes "LeftAngle" and "RightAngle", not the RotZ directly). Then change the Drawbar's X position so that it is drawn back as shown below.


The first animation is straightforward, keeping the existing "onClick" to rotate the doors. The second animation involves the Drawbar sliding across by changing the object's X position. But we don't want this to happen until the doors are closed so how do we accomplish this? One technique is to create a custom attribute which will have a timeline and the animations are based on this, determining their values from this attribute. In this case, because the doors start at the same time as we click it, we can leave them as they are, but the moving of the Drawbar will need to controlled by this.

Before we create anything though, we need to get out a pen and paper (or spreadsheet) and work out some timings. The doors use the Animate function which occurs over half a second so let's say the Drawbar animation will start at 0.6 seconds (to allow a more realistic slight pause between the actions). The Drawbar animation can also take half a second so the total length of the full animation is 0.5 + 0.1 + 0.5 = 1.1 seconds.

In my model, the X position of the Drawbar is -210 when withdrawn and -5 when closed so, putting these together in a table:

Time 0 secs 0.6 secs 1.1 secs
Drawbar X -210 -210 -5
Timeline -456 -210 -5

Now comes the complicated part of working out a formula. I worked out the Timeline figures so that the Drawbar X position matches the Timeline but, obviously we don't want the Drawbar to move until the Timeline reaches -210 so we need to add an IF formula which says (in English):

If Timeline is less than -210, Drawbar position is -210, else Drawbar position is equal to Timeline.

As a SketchUp formula, it is (notice no quote marks around the attribute names:

=IF(Timeline<-210,-210,Timeline)

Finally we simply link the Drawbar position to the Timeline.

The final formulas are shown below:

You may have noticed the CUSTOMANIMATION that controls the Timeline animation. Because we want an odd number, 1.1 seconds, we can't use the standard ANIMATION types so have to use a CUSTOMANIMATION. The parameters for this formula are, compared to the normal ANIMATION:

ANIMATION(attribute, state1, state2 ...)

CUSTOMANIMATION(attribute, time, easein, easeout, state1, state2 ...)

The only thing that might be puzzling is the easein and easeout. These determine the acceleration of the animation with 0 being the fastest and 100 being slowest. The default easein and easeout for an animation is 0 and 100 which means the animation starts fast and slows down, rather like a ball being thrown in the air. Values of 100 and 0 would mean it starts slowly and speeds up (like a rocket taking off).

The details we enter are:

ANIMATECUSTOM("Timeline",1.1,0,100,0,-456,-5,-456)

which means the Timeline value changes over 1.1 seconds, starting quickly and slowing down, going from -456 to -5 on the first click, then back to -456 on the second click.
If you click on the component now, you should see doors open and then, after a pause, the drawbar slide across.

The reverse  animation doesn't work properly with the doors opening before the Drawbar has slid back but, to have the animation working both ways requires a more complicated arrangement. For this to work, you would have to link the animations of both the Drawbar and the two doors to the position of the Timeline which is much more complicated. Maybe you can think about how to achieve this. I shall show my method in the next lesson.


The completed component is available on 3D Warehouse at https://3dwarehouse.sketchup.com/model.html?id=ud59967fd-643b-4621-aeb5-d1cbbbc9fb19

Tuesday, 1 April 2014

Lesson 7: Dynamic copies

Previous lessons have looked at simple dynamics such as changing a single attribute but this lesson will tackle something more complicated and which can sometimes take a while to get your head around – dynamic copies.
As an example, imagine a ladder with 10 rungs spaced 50 cm apart. If you double the length of the ladder, you don't want 10 rungs spaced a metre apart, you want 20 rungs spaced 50 cm apart. Similar needs come with sets of stairs, fences, furniture with multiple drawers.

For this tutorial, we shall again keep things simple so you can understand the principles without getting confused by details. Start by creating a block 100 x 50 x 200 on each side, group it and name it "Wall". Then create a step 50 x 10 x 30, make it a component (because it will be repeated, unlike the wall), and name it "Step". Position the step at the bottom edge of the block (see below), then select both and make it in to a component "DC4".


 Notice that we have only made one rung. All the others will be handled and duplicated automatically by formulas but, before we do that, we shall add a couple of custom attributes. Under the DC4 component, add two custom attributes: "TotalHeight" and "Spacing". The first determines the total height of the component so enter "50" for the moment. Then, under the Wall element, add the attribute LenZ and enter into its box the formula:

=DC4!totalHeight

The height of the Wall is now linked to TotalHeight so we can change the height of the subcomponent Wall from the main DC4 component. The Spacing attribute determines how far apart the steps are so enter 50 at the moment (so we have one step per 50 cm of wall height).

If we now enter 100 into TotalHeight, we should see that the wall gets higher but nothing else happens. We need to handle the duplication of the steps to allow for the extra height and this is determined by the attribute called "Copies" (under OnClick in the popup menu). So add the Copies attribute to the Step element (since we are making copies of the Step and enter the formula:

=DC4!totalHeight/DC4!Spacing

This means that the height of the wall is divided by Spacing to determine the number  of total steps. If you try different values in TotalHeight, you should see the value in Copies change:

TotalHeight Formula Copies
50 50/50 = 1
100 100/50 = 2
150 150/50 = 3

So the number of steps is increasing with the height of the Wall. Wait, you protest, I can only see one Step! Well there really are the same number of Steps to match the Copies value but they are all in the same location as the original Step so you can't see them. What we need to do now is change the Y and Z positions of the copies of the Step so that they are positioned separately. This is handled by a new, read-only attribute which is not normally visible called COPY. This holds the number of each copy so the original Step is numbered 0, the next 1, then 2, and so on. If you view the X, Y and Z positions of the Step, you see that it shows X=100, Y=0 and Z=0. If we start with the vertical position of each Step, we already have the Spacing so we simply set the Z position to:

=DC4!Spacing*COPY

The results would be:

COPY No. Formula Z Position
0 50*0 = 0
1 50*1 = 50
2 50*2 = 100
etc.

After entering this formula, you should see the steps suddenly appear next to the wall.


 You can change the horizontal position as well by adding the same formula to the Y position. Now, as you change the TotalHeight, you will see Steps magically appear or disappear.
  
TIP if you double-click and open the component after these copies have been made and select one of the them, you will see the COPY number in the attributes (below)


If your component isn't working, here are the settings below:
Obviously the positioning isn't quite right and here comes the mathematical bit. You need to adjust the formulas to space things correctly, maybe adding on an offset or allowing for the thickness of the step. One of the best ways to go about this is a sort of reverse engineering – draw the final component on paper, working out what the positions of each step would be and work out a formula which would produce that. A spreadsheet comes in very useful here.
Sketch diagram of the finished dimensions

The final formulas which space the Steps correctly are:


Y position = (200-30)/Copies*Copy
Z position = (DC4!totalHeight-10)/Copies*Copy

As before, the component, DC4, is available on 3D Warehouse at

https://3dwarehouse.sketchup.com/model.html?id=udd41c4eb-9a36-43ea-81fa-c49421426634

Wednesday, 12 March 2014

Lesson 4: Creating an opening and closing window

In the previous lesson we found out how to enter simple formulas so let's put this into operation by creating our first "real" dynamic component. Note that most of the components we create will be simple shapes, not realistic furniture or doors. This is so we can concentrate on how the DC works and not what it looks like. Once you learn the principles, you can then take them into an actual wardrobe or car or window.

Entering spreadsheet functions

The formulas we have entered up to now have been simple ones such as "=LenX/3". But, as anyone who has used a spreadsheet knows, there are dozens of more complicated formulas (functions) which you can enter. SketchUp has many of these and some of them you will use regularly. You don't have to enter these by hand though. They are all available in the Attributes window.

Open the Attributes window and create a component or group. Select it. At the top of the window, you will see two tabs: Info and Functions. You might think (I certainly did at first) that changing these tabs would change the whole Attribute window but it actually only changes the grey area immediately below (as you can see in the images below).



"Info" is selected by default and gives you information on the attribute that you select or are in. But if you click on "Functions", you see a drop-down menu with "Select a spreadsheet function..." and a button ("insert") beside it. To add a function, add any attribute to your component, and, with the attribute field empty of any contents and the cursor within it, select any function from the drop-down menu and click "insert". The function should be entered into the attribute field. (As you progress, you will learn many of these functions and you can type them in by hand.)

Obviously you cannot just use any old function in any position. Many only work with numbers so could not be used in text attributes like "Summary". The above operation was just to show how to select and insert a function.

Creating an opening window

So now let's go onto creating a real dynamic component. We shall create something which is very simple but very compelling to watch: an opening and closing panel.

If you've downloaded some DCs, you might have found this already: a car or a wardrobe with an opening door, or an opening window. All this is is a change in the rotation attribute (usually RotZ) of the door/window.

So start a new document and create the two shapes below, a wall and a window. The sizes are unimportant as long as the window is exactly the same size as the hole in the wall. Notice also that the objects do not have any depth (LenY) – they are just two dimensional objects. For this example, it is actually easier not to have any depth but it doesn't matter too much if it has. Make sure each is a separate group or component name "wall" and "window". (You name a group by choosing "Entity Info" from the Window menu or right-click menu, and entering something into the name field.)


Now move the window so that is fits exactly into the hole in the wall (it should snap into place). Then select both objects and create a component (call it "DC1"). Open the attribute window and select the component.

Up to now we have been dealing with one group/component at a time but this time you will see a nested component. Dynamic components are usually composed of other smaller groups or components (which I call sub-components). You can have individual shapes (non-groups/components) within a dynamic component but you have no control over their attributes so you will normally make every separate object within a DC either a group or component.

If you have used the names I suggested, you should see the three objects in the attribute window, with the primary component ("DC1") at the top and "window" and "wall" indented beneath (to show that they are sub-components of DC1.

TIP You can change the name given to the objects by double-clicking on the name in the attributes window – very handy if you have several identical sub-components such as wheels.

First test it by expanding the "window" sub-component and add the attribute "RotZ". It should be zero. Now enter "-45" and press return. The window should open towards you. (Negative numbers rotate clockwise, positive rotate anticlockwise.) Undo or enter zero so the window is closed again.

Now we need to add the ability to open and close the window with the Interact (pointing finger) tool. Basically we want to set the RotZ to -45 on the first click, then -90 on the second click, and back to zero on the third. For this we need to use the OnClick attribute. The OnClick attribute controls what happens when you click with the Interact tool. So, in the window sub-component, add the attribute "onClick".

Note that we added it to the "window" sub-component. This means that you have to click on the window to open it. We could have added it to the "DC1" primary component and then we could have clicked anywhere on the wall or window to open it. But that would cause problems if we wanted another animated object in our component so we normally add the onClick to the thing to be animated.

With the cursor in the onClick attribute field, click on Functions at the top, select "SET(attribute, state1, state2, ...stateN)" near the bottom of the menu and click insert. This function is used to change any attribute, in this case by clicking. Change the default text in the onClick attribute to show exactly this and press return:

SET("RotZ",-45,-90,0)

A VERY IMPORTANT NOTE: The attribute in the SET function (RotZ) must be enclosed in quote marks or it won't work. If you click on an attribute name to enter it without typing, the quotes will not be added. If your animation doesn't work, always check first to see if you have missed out the quotes.

A LESS IMPORTANT NOTE: Notice that SET doesn't have an equals in front of it. It is a behaviour, not a formula.

If you now select the Interact tool and click on the window, it should change with every click from closed, to half open, to open, and back to close. (Note that we entered -45, -90, and 0; when SketchUp gets to the zero and we click again, it automatically goes back to the first value and shows -45.)

If it doesn't work, check that your attributes look like the screen below:



If you still can't get it to work, I have uploaded the component to the 3D Warehouse at https://3dwarehouse.sketchup.com/model.html?id=ubf42b594-eb3a-493b-b384-ce8225658b5c (with a bit of texture) so you can download it and see how it differs from yours.

Other Animations

The problem with this component at the moment is that the window jumps open rather than through a nice smooth animation. To improve it, we can use one of the animation functions (ANIMATE, ANIMATEFAST, ANIMATESLOW AND ANIMATECUSTOM). All, apart from the last, have the same structure. You could delete the SET function we have used and insert one of the animate function, or simply type "ANIMATE" where it presently says "SET". That is:

ANIMATE("RotZ",-45,-90,0)

If you do this (remembering the quote marks around the attribute), you should see the window open and close smoothly when you click on it.

The differences between these functions are:
SET  Attribute jumps between values. Best for attributes with no intermediate values (such as HIDDEN attribute which is either true or false), or where you aren't interested in smooth animations.
ANIMATE Attribute changes evenly over half a second.
ANIMATEFAST Attribute changes evenly over a quarter of a second. 
ANIMATESLOW Attribute changes evenly over one second.
ANIMATECUSTOM Allows you to customise the animation, changing the speed and the easing (acceleration).

Try changing the function to each of these animations (you may want to leave the ANIMATECUSTOM to a later date) to see their effects.

You can see how just a single line in one attribute can create a pleasing effect. We can also use these functions for more elaborate animations such as sliding doors, cars which drive by themselves and complicated movements. But, for now, just play around with different shapes and animations until you are happy with this procedure.