In this tutorial, we will be using several new objects to perform 
procedural drawing with the 
lcd object.  The 
counter object will provide enumerated step processing, the 
line object will allow us to create smoothed output, and the 
scale object will allow us to change the range of output. Finally, we will introduce a few mathematical objects that will help us create some common shapes that require simple trigonometry.
 
We often use programmatic and procedural constructs to perform tasks in our programs; these can present new opportunities for graphic display, but can also be used any time we need to count through a set of numbers, create a numerical trajectory, or scale values.  Whether used for audio visualization, controller feedback or just an interesting bit of art, procedural code can serve as both a useful tool and an inspiration.
Take a look at the tutorial patcher.  This patch has a few areas that help us understand some new objects, and another large drawing patch.  At the top-left is a small patch that demonstrates the 
counter object. When we click on the left 
button, the object produces numeric output that increments by 
1 for each 
bang message it receives.  When the output reaches 
9, the next 
bang will reset the output to 
0.  The arguments we've provided here to the 
counter provide the 
minimum and 
maximum numbers for the output.  When the object hits its maximum, it will loop back again to the minimum number.  This allows us to use 
counter to create 
loops of values.
 
The 
counter object is somewhat unusual in that it can accept a variable number of arguments:
•	If you have 
one argument, it sets the 
maximum value of the 
counter.
•	If you have 
two arguments, they set the 
minimum and 
maximum values of the 
counter.
•	If you have 
three arguments, they set the 
direction, 
minimum and 
maximum values of the 
counter.
 
Our test patch for 
counter includes an additional 
button (colored blue) and two 
number boxes to set values of the object. This is a great opportunity to use the 
assistance on inlets to find out what they do.  If we 
unlock the patch and hover over the third inlet (which has both a 
button and 
number box connected), the assistance says “Resets Counter to Number on Next Clock”. This lets us change the current value of the 
counter while it is running.
 
If we change the 
number box to 
5 then hit the first 
button, we see that the output is the number 
5 – regardless of what the previous value was. This is how we set the state of the 
counter on the fly.  Clicking on the second (blue) 
button (which sends the 
bang message) will reset the value to the minimum: 
0 in this case.
 
The 
number box on the right allows us to change the maximum value on the fly.  This would be useful for drawing situations where you might need to change the size of the drawing area, or when you are sequencing an effect and need to change the number of steps.  When we change this value and repeatedly hit the 
button, we see that the new maximum value is honored.
 
The drawing patch has a section labeled 
1; this is where we use the 
counter object to procedurally draw in the 
lcd object.  When we start the 
metro (using the connected 
toggle object), we see that the patch begins drawing small circles in the 
lcd, with the color gradually changing as it progresses.  When the drawing reaches the bottom of the 
lcd, it restarts drawing at the top.
 
Four different 
counter objects are used in this patch; one to set the drawing location and size, and three others to change the color. Understanding the leftmost 
counter is the most important: it counts from 
0 to 
767, giving us 
768 steps total. The drawing X/Y location is calculated with the 
% (modulo) and 
/ (division) objects, breaking up our lcd object into a 
24x
24 grid.  If we look at the output of the 
counter and the 
% and 
/ objects, we can see that the system works by creating two loops from 
0 to 
23, one going quickly (from the 
% object) and the other incrementing each time the first loop has repeated (the 
/ object).  The values are multiplied by 
10 (to get the pixel location for the top-left location), then have 
10 added  (to get the pixel location for the bottom-right). This sets up a lcd-filling grid of circles for our program to draw.
 
The three other 
counter objects cycle through three different number ranges to give us an ever-changing color palette. These 
counter objects use the three-argument initialization, where the initial 
2 forces the counter to move upward to the maximum, then downward to the minimum. This is what causes the drawing to slowly change colors as it draws.  Clicking the 
button labeled "reset" will restart the simulation from the beginning of the loop.
 
If we return back to the top-left of the patcher, the second small example shows the use of the 
scale object.  This object allows you to set a range of input values and a range of output values; the object will then correctly 
scale the values so that they are mapped into the new number range.  In our example, input values between 
0 and 
100 are mapped to the range of 
-1.0 to 
1.0 – this is determined by the arguments provided to the object.  If you change the input 
number box, you will see that a value of 
0 yields an output of 
-1.0, a value of 
50 will give us a value of 
0.0, and a value of 
100 will give us a result of 
1.0.  These numbers are mapped in a linear fashion across the range we provide.
 
If you choose to exceed the input range, you will find that the output continues to use the calculated range effect, thereby allowing you to exceed the expected range without failing. Hence, a value of 150 will translate into an output of 2.0, while a value of -100 will give you a value of -3.  The arguments are used to determine the mathematical expression used for conversion.
The section of the drawing patch labeled 
2 uses 
scale to draw a shape based on sine wave calculations. A 
counter object produces output ranging from 
0 to the maximum value (set using the two 
number boxes to the right of the 
metro object). This is scaled from 
0.0 to 
6.283185 (2*pi), then sent to a 
sin object, which calculates the 
sine of the input value. This produces a sine wave that varies from 
-1.0 to 
1.0 in range.  This value is sent to another 
scale object which maps this range to the integer range 
0 to 
319 – the size range of the 
lcd object. This is used to provide the X locations of the line. A similar set of functions are used to set the Y location. These numbers are then inserted into a list (using 
pack, prepended with the 
lineto message (using 
prepend) and then sent to the 
lcd.
 
Clear the 
lcd using the 
message box containing the 
clear message.  Turn on the 
metro using the 
toggle, and watch the result. The result is a sine-based drawing over the entire 
lcd face.  You can set the maximum values of the procedure by altering the 
number boxes that are attached to the 
counter objects.  Note that the 
number boxes change not only the parameters of the 
counter objects, but also the maximum input range expected by the 
scale objects immediately below (the third inlet for the 
scale object determines the maximum input range expected).
 
The two 
counter objects, when set to different maximum points, create different interlocking sine waves that draw across the 
lcd.  These curves are called 
lissajous patterns and simulate what happens when out-of-phase oscillators are fed into the X and Y inputs of an oscilloscope.  This is a great example of using simple math functions to create complex drawings.
 
Going back to the top-left of the patch, the third example gives us a chance to see the 
line object in action. The 
line object takes a pair of incoming values (configured as a value/time pairing) and slowly moves from one value to the next. If a single value is received, it jumps immediately to that value.  However, when a second value is provided, it is treated as the number of milliseconds to move to that new value.
 
Clicking on the first 
message box (labeled 
100 1000) will move the 
line from the starting value of 
0 to the target value (
100) over 
1000 milliseconds. Clicking on it again will show no change, because the current value (which remains at 
100) is the same as the target value (it has nowhere to go).  The line object is “state aware”, meaning that it understands its current value, and will adjust its action based on the state of that value.
 
Clicking on the second 
message box (
0 5000) will move the result of the 
line back to 
0 over 
5000 milliseconds (5 seconds). Clicking on the first box will move us back to 
100.
 
The third 
message box is a little more interesting.  It uses a special function of the 
message box to create multiple messages; when a 
comma separates values, they are treated as separate message, and will function as if two messages were sent down the same patch cord immediately after one another.  In this case, the value 
20 is sent as the first message.  Since there is no time pairing, the current value out of the 
line immediately jumps to 
20. Immediately afterward, the 
50 2500 pair is sent, causing the output to slide from 
20 to 
50 over 2.5 seconds. We can also use the 
number box to immediately jump the 
line to a new value; since no timing value is provided, it too will cause the current state to jump to the entered value.
 
The section of the drawing patch labeled 
3 is the most complex procedure we’ve yet seen. It depends on the 
idle mechanism of the 
lcd object to do some procedural drawing.  When the 
idle message is turned on (with the 
idle 1 message), the 
lcd object outputs the current mouse location relative to the 
lcd object's canvas when you move your mouse over it.  These X/Y coordinates are sent as a list out the second outlet of the 
lcd.
 
The light blue patchcord out of the 
lcd connects our mouse coordinates to an 
unpack object back at the top.  These values are sent into our drawing code, which creates a set of values used to draw a pair of round shapes that follow the cursor.  The 
line object is used to slow the changes in the shapes, and causes them to slowly "zero in" on the current cursor location.  Turn on the 
idle message with the 
toggle box, then mouse around the 
lcd object to see how it reacts.
 
There are two very important things in this procedure.  First, the use of the 
line object to slew the output values over a one second (
1000 ms) timeframe.  This gives the results a more organic feel by causing them to 
interpolate over time.  Secondly, we use the 
cartopol (
cartesian 
to polar) object to change the X/Y ("Cartesian") position of the cursor into a Distance/Angle ("Polar") pair of coordinates, useful for drawing contents in a circular domain. Once the polar coordinates are calculated, they are scaled to match the size of the circular drawing area, then used as part of a complex, multi-message 
message box to create the two “eyes” found in the middle of the 
lcd object.
 
The 
message box at the bottom of the code sends four drawing commands in sequence to the 
lcd.  The first two draw two background circles using the 
paintoval command at fixed positions (
100 100 140 140 and 
180 100 220 240).  The last three arguments to 
paintoval set the color (black: 
0 0 0).  The second two messages use the values from the 
pack object to draw green "pupils" on the eyes.  The four values provide the starting and ending angle for the pupils using the 
paintarc message.
 
Understanding all of the functionality of this procedure may be difficult, but it is worth it – this is another example of using some mathematical programming to create a complex and life-like end result.  Simple realtime graphics are made out of building blocks of procedural code just like this; taking a set of input values and scaling them to your needs is critical for many applications in Max.
We’ve seen some fairly complex programming that provides controlled drawing functionality within an 
lcd object by creating loops (
counter), scaling input values to output values (
scale), and interpolating numbers over time (
line). We’ve also worked with a few objects that compute trigonometry.  By using these new objects in combination, we can assert a lot of procedural control over what we want to accomplish in our programs.
 
See Also
| Name | 
Description | 
| counter | 
		Count the bang messages received, output the count
	 | 
| scale | 
		Map an input range of values to an output range
	 | 
| line | 
		Output numbers in a ramp from one value to another
	 | 
| sin | 
		Sine function
	 | 
| cartopol | 
		Cartesian to Polar coordinate conversion
	 |