Processing
Introduction to programming. Write short programs that generate graphics and animation.
Find episode: in source code tags summary
1. Introduction
..
.graphics.animation.intro.
welcome to fun programming!
this is the introduction to a series of videos where i will be explaining creative programming to beginners. i start with a programming language called processing in the next video. these videos are part of a challenge to upload one episode each day during august 2011.
i focus on creating visual effects and not so much in theory. usually i introduce one new concept on each episode.
most images in this video are taken from the programs we write in coming episodes.
in www.funprogramming.org you can read the descriptions of all episodes in one page.
note: this video replaces the original introduction video. it's the same but better :)
2. Download Processing. Use point() and line()
.line.point.
.point.line.pixel.
download processing from www.processing.org and do some exercises with point() and line(). we are introduced to using coordinates to access pixels on the screen. a coordinate has a x and a y value. the x value is the distance from the left border of the display. the y value is the distance from the top border of the display. using an x,y pair you can locate any pixel on the screen. the top left pixel is located at 0,0. the pixel at 10,30 is found at 10 pixels from the left border and 30 pixels from the top border.
3. Create an animation, use random()
.background.draw.line.random.void.
.semicolon.pixel.draw.background.animation.
a short review. what happens if we forget a semicolon at the end of the line?
a little more detailed explanation of the display as a grid of pixels, with hundreds of rows and columns. we try out the function random() to make our program create a different image each time. finally we try out the function draw() and background() to be able to animate lines and change the background color.
4. Shades of gray and colors, frameRate()
.background.draw.framerate.random.setup.void.
.rgb.gray.colors.framerate.open.save.animation.
when you write a program, you can save it on your hard disk. you can open the saved program later and continue working on it.
discover gray scale shades and rgb colors, then animate the background color and change the frame rate.
5. Light speed effect, change line colors
.background.draw.line.random.setup.stroke.void.
.line.animation.stroke.autoformat.
learn how to change line colors and make some kind of disco laser effect and a very simple light speed effect. we also show the option to auto-format the source code, which adds and removes spaces to make it all beautifully aligned.
6. Animate white lines across the display
.background.draw.line.random.stroke.void.
.animation.line.
exercise. in this episode we create a simple program that animates white lines on black background. the lines extend from left to right border of the display.
7. Animate horizontal lines, use a variable
.background.distance_top.draw.float.line.random.stroke.void.
.horizontal.line.animation.variable.
modify the program from episode 6 to make all lines horizontal. to achieve this we use "variables" for the first time. a variable is like a box where we can store a value and reuse this same value multiple times in our program.
a horizontal line has a starting and an ending point, and both are at the same distance from the top border of the screen. to make sure both points are at the same distance from the top (both have the same y value), we use twice a variable that contains our y value.
new: sam below requested more info about "float", so here it goes: variables (these boxes where you can store things) in processing have a "type". this means each box can only store certain types of things. imagine having boxes that could only contain pencils, or only bananas. you have to choose the right kind of box for your item. a "float" is like a box that can store numbers with decimals (like 6.259305). other available types are "string" (for text), "int" (for integer numbers like 6 or -523), or "boolean" (for true/false).
the reason i used float is because random() gives you back a float.
it is possible to convert from one type to another.
8. Animate vertical lines
.background.distance_left.draw.float.line.random.stroke.void.
.vertical.line.animation.
discover how to turn the horizontal lines from the last exercise into vertical lines.
a vertical line has a starting and an ending point, and both points are at the same distance from the left border, so both have the same x value.
9. Change screen size, animate colorful lines
.distance_left.draw.float.line.random.setup.size.stroke.void.
.size.animation.random.
we modify the last program we did (animated white vertical lines on black background) to make it more colorful. we see how to use the random function with two parameters instead of one. this way we get a random nomber that is between a minimum and a maximum value.
we also show how to change the screen size using the size() function to make it larger. when we don't use the size() function, the screen is by default 100 pixels wide and 100 pixels tall.
10. Draw circles and rectangles, change fill color
.b6ff00.background.c0e1ea.center.ellipse.ffbc03.fill.rect.rectmode.size.stroke.
.ellipse.oval.circle.rect.fill.color_picker.copy.cut.paste.
learn how to use the ellipse() function to draw ovals, circles and even an egg. we also show how to use rect() to draw rectangles, and how to change the fill color for both ellipse() and rect().
instead of guessing rgb values, you can use the color selector to pick a color, which is much easier.
you probably know, but we remind you the most basic shortcut keys: ctrl+c for copy, ctrl+x for cut and ctrl+v for paste).
11. Non-random animation of a circle crossing the screen
.background.bb1f5.c1ff3e.circle_x.draw.ellipse.fill.float.nostroke.setup.size.void.
.animation.help.
we first review the ellipse() function and then animate a circle from the left to the right border of the screen. we use a variable to hold the current position of the circle. for doing random animation we don't need a variable because we don't need to know the last position of the object. but for animating an object moving in one direction, we need to know where we are now to know where we will be next. that's why we store the current position in a variable.
this episode was a bit too long and serious. the next one should be shorter and more fun :)
12. Do a loop animation using an if() statement
.background.bb1f5.c1ff3e.draw.ellipse.fast_circle_x.ff4800.fill.float.if.nostroke.setup.size.slow_circle_x.void.
.loop.conditional.if.
in this episode we learn how we can use the if() statement to execute some code conditionally. that means the code is not executed always, but only if certain condition is met. in our example, the condition is that the circle has moved too far to the right. in that case, we bring the circle back to the left border of the screen.
we also see how to animate two objects at different speeds, and how each object can have a different color.
13. Event happening only sometimes
.background.bb1f5.c1ff3e.draw.ellipse.fast_circle_x.ff4800.fill.float.if.nostroke.random.setup.size.slow_circle_size.slow_circle_x.void.
.learn.
we use the print() function for the first time. using print we can find out the value of a variable and display messages below our program.
when something is not going as expected it can be useful to add some print() calls to our program. we can print the value of a variable, or just print a text to find out if that part of the program is running or not.
print() is your friend :)
14. New directions for our moving circle
.background.circle_x.circle_y.d60dff.draw.ea73.ellipse.float.setup.size.stroke.strokeweight.void.
..
we introduce the strokeweight() function to change the width of the lines we draw. if we don't use strokeweight(), the lines are very thin.
we also review some basic animation. then (after minute 4:30) we find out how to move our circle not only from left to right, but in another directions, by making the x and y values larger or smaller.
15. Ball bouncing at the window borders
.background.circle_x.circle_y.d60dff.draw.ea73.ellipse.float.height.if.move_x.move_y.println.setup.size.stroke.strokeweight.void.width.
..
this example is a bit more advanced. in the past, when our animated circle reached the border it jumped to the opposite border. now we discover a way to make our circle bounce at the borders!
the trick is to have a variable that says how much to move our circle on each frame. this variable can hold a positive number or a negative number. if the number is positive (above 0), our circle can move to the right or down. if it's negative (below 0, like -1), our circle can move to the left or up.
if we flip the sign of the variable when touching the borders of the screen, it will look like the circle is bouncing at the borders.
16. Create an animated rainbow
.b1ce.background.draw.ellipse.float.nofill.rainbow_size.random.setup.size.stroke.strokeweight.void.
..
we draw circles in the bottom part of the screen. half of the circle is outside the screen, so it looks like half circle. we draw them using different sizes, colors and line weights, so we get a colorful rainbow effect.
17. A better way to generate random colors
.b1ce.background.colormode.draw.ellipse.float.hsb.nofill.rainbow_size.random.setup.size.stroke.strokeweight.void.
.beginners.
here we make the colors of our animated rainbow less pale. until now we have used the rgb color mode to randomly generate colors. in this episode we discover the hsb color mode. it's easier to control because it allows us to generate random colors with certain properties, for example dark colors, pale colors, bright colors, etc. that means they are less random and probably closer to what we want.
18. Things that happen sometimes
.background.draw.else.float.if.line.random.setup.size.stroke.void.width.
.random.
this is the second time we compare a random number to a given number to make an event happen only sometimes, not always. changing the given number we can make the event more or less probable. we test different numbers while animating some vertical lines that create something similar to a bar-code.
19. Tweak the bar-code, create your first function
.background.change_line_color.draw.else.float.if.line.random.setup.size.stroke.void.width.
..
this time we continue with the bar-code example from last episode. we create our first custom function. functions can make the code easier to read. they are also useful to avoid repeating code: when the same group of lines is used multiple times in a program, it's a good idea to convert that group of lines into a function.
we also play a little bit with the numbers to see how they affect the image.
20. The smallest drawing program ever
.draw.if.keypressed.mousepressed.mousex.mousey.point.save.true.void.
.beginners.
in this episode we learn how to read the current mouse position which is stored in the variables mousex and mousey. we also learn how to find out if the mouse button is clicked using the mousepressed variable. with this information we make a very simple drawing program.
then we create a keypressed() function to detect when the user presses a key on the keyboard. when the user presses a key, we call the save() function to save our drawing to an image file in our hard drive. you later can send the image by e-mail if you want.
21. Improved tiny drawing program
.background.draw.draw_top_line.if.key.keypressed.line.mousepressed.mousex.mousey.point.random.save.stroke.strokeweight.true.void.width.
..
we continue with our tiny drawing program. the first version saved the image when you pressed any key on the keyboard. now we check which key was pressed by reading the *key* variable. if we pressed *s*, we save the image. if the *b* key was pressed, we change the background color. and the *c* key changes the line color.
the background color is easy to see, but we don't know about the line color until we draw something. it would be nice to know about our line color *before* drawing anything. to solve this, we draw a thin line on the top border of our drawing which lets us see the current color.
finally, we show how creating a function can avoid having repeated lines of code. we create a function that draws a line on the top border of the screen, and we call this function in two cases: after setting the background color, and after setting the line (stroke) color.
22. Stars blinking at night (fade out effect)
.background.draw.ellipse.fill.height.nostroke.random.rect.setup.size.void.width.
..
in this episode we create an interesting fade out effect. until now, every time we animated (moved) something on the screen, we erased the whole display before drawing each new frame. but instead of using background() to erase the whole screen, we can draw a rectangle that covers every pixel. the trick is to use a low opacity. this means that the "paint" we use does not complete cover the old drawing. it's like a tinted car window or our sunglasses. so on each frame we add a new black layer that makes things a little bit darker. then draw something new on top, in this case small circles. the result is quite interesting. you can try this for any previous animation we have made. just replace the first call to background() inside the draw() function with two lines: fill(0, 10); and rect(0,0,width,height);
23. Using the while loop
.background.colormode.ellipse.float.hsb.nofill.print.random.size.stroke.while.
..
introduction to the while loop. the structure is similar to an if statement, but there is an important difference. with an *if* statement, the code inside the curly braces will run 0 or 1 times (0 times if the condition is false, 1 time if the condition is true).
but with the while loop code can run many times, not only 0 or 1. it will keep running while the test condition is true. it is ideal to repeat some code many times.
in our example we use it to draw many circles. just changing one value we can decide if we want 10 circles or 100. it's important that something inside the while loop will make the condition false, otherwise the loop runs forever and can make our computer slow. always check that the loop will run only as many times as you expect, not forever!
24. Circle patterns with a while loop
.background.colormode.ellipse.float.height.hsb.nofill.print.random.size.stroke.while.width.
..
in this episode we continue with the previous program, where we draw many circles using a while loop. we try different sizes and positions for those circles, and study the strange patterns that appear.
25. Typing big letters that fade out
.background.cc.draw.ffe200.fill.height.key.keypressed.random.rect.setup.size.text.textsize.void.width.
..
it's time to write some text on the screen using the text() function. the first parameter is the text you want to display, and the second and third parameters are the x and y position. with textsize() you can control how large the text is. if you call fill() before calling text() you can set the text color.
after some basic text() calls we create a program that writes anything you type on the screen. each letter is written on a random position and with a random size. the letters then quickly fade out and disappear.
26. Make patterns by rotating objects
.aa21e.background.fill.float.nostroke.random.rect.rotate.size.smooth.while.
..
after many episodes moving things up, down, left and right, we introduce rotation. the rotate() function allows us to create rectangles that are not horizontal or vertical. if we make many of them using a while loop, we can create interesting patterns. for now we only rotate things around the top left corner of the screen. in future episodes we will discover how we can rotate objects around their own center (like when a cd or the wheels of a car spin).
the smooth() function makes the lines smoother, which you will notice a lot when you rotate rectangles.
27. Animating while rotating
.background.circle_size.draw.ellipse.fill.float.nostroke.println.random.rotate.setup.size.smooth.void.
.rotate.animate.animation.
in our previous episode we used rotation and a while loop to create a pattern. we created and rotated many objects.
in this episode we animate using the rotate() function. on each frame of our animation (each time draw() gets called), we rotate our screen a little bit and then draw a circle. we repeat this over and over, so we see this circles spin around the 0,0 position. when we add some randomness to the size of the circles an interesting pattern appears.
28. Rotate and even move your axes
.background.circle_size.draw.ellipse.fill.float.height.nostroke.println.random.rotate.setup.size.smooth.translate.void.width.
.rotate.translate.
there are two things we have assumed to be true since the first episodes: when we increase the x coordinate things get drawn more to the right, and the pixel 0,0 is at the top left corner of the display.
we now discover that the x axis does not always point to the right: if we call rotate() the x axis can point anywhere, like the needles of a clock. we could turn our graphics up side down using rotate().
we also discover that we can move the axes. if we do, the 0, 0 point is no longer at the top left corner of the screen.
we show that adding just one line in our program to the beginning of our draw() function we can create drawings that rotate around the center of the screen, instead of rotating around the top left corner.
29. Rectangle spinning around the mouse pointer
.backb.backg.background.backr.center.draw.fill.float.height.mousex.mousey.nostroke.random.rect.rectmode.rotate.setup.size.smooth.translate.void.width.
.rotate.translate.spinning.
in this episode we finally see how to rotate a rectangle around its own center. we add the fade-out effect to make the rectangle leave a nice blurry trail behind it, and changing just one line we make it spin around the mouse position.
key ingredients for this episode are rectmode(), rotate() and translate().
30. Multiple rotating objects and reset matrix
.background.center.draw.fill.float.nostroke.rect.rectmode.resetmatrix.rotate.setup.size.translate.void.
.resetmatrix.
previously we animated a rotating rectangle. this time we animate not only one, but four rectangles.
to rotate an object around its own center we must move the origin and rotate the axes. this works fine when there is only one object, but to rotate more than one object is tricky, because each time translate() and rotate() are called, the effect adds to previous calls to translate() and rotate(). to solve this we introduce resetmatrix(), which removes previous changes to the origin and axes rotation.
basically we do 1. translate(), 2. rotate(), 3. draw something, 4. resetmatrix() to undo the effects produced by 1 and 2. then repeat 1, 2, 3 and 4 for other rotating objects.
31. Function parameters and return values
.calculate_sum.float.hello.my_added_numbers.print_sum.println.return.setup.void.
..
this episode is a bit more serious and less visual, but it will be important to know how to create your own functions.
we create a simple function that does not take any parameters, and another that takes two numeric parameters and adds them together. we also create a function that returns a value.
knowing this we will be able to simplify the program we created in the previous episode with four rotating rectangles.
32. Use a function to simplify a program
.background.center.draw.draw_rotating_rectangle.fill.float.nostroke.rect.rect_size.rectmode.resetmatrix.rotate.setup.size.translate.void.
..
in this episode we simplify the program created on episode 30, with the four rotating rectangles. we write a function that creates a rotating rectangle. the function takes several parameters to modify it's behaviour. this way, the function can be used to create rectangles on different locations and with different sizes.
33. Use multiplication to scale up or down speeds and sizes
.background.c9ff29.center.draw.draw_rotating_rectangle.ed6.ellipse.fill.float.nostroke.rect.rect_size.rectmode.resetmatrix.rot.rotate.setup.size.translate.void.
.multiplication.scale.scalin.
multiplication is something we often use in our programs, so it's important to feel comfortable with it. in programming languages, the sign used for multiplication is the asterisk: *. when we multiply any number by 1, we get the same number: 77 * 1 = 77. when we multiply by a number larger than 1, we get a number larger than the original number: 77 * 1.2 = 92.4. when we multiply by a positive number smaller than 1, we make it smaller: 77 * 0.8 = 61.6. knowing these simple rules we create a program where objects move a different speeds. we also update the program we created with 5 rotating rectangles to give each rectangle a different rotation speed.
34. Create a grid of objects with nested while loops
.background.ellipse.else.fill.float.height.if.nostroke.random.size.while.width.
.while.nested.loops.grid.
we have seen in previous episodes how to create many objects at once using a while loop. this time we use a while loop inside a while loop to create a grid of objects. the result is a collection of objects (rectangles or circles in our example) distributed in the screen in a pattern similar to the white and black rectangles in a chess game.
using a loop inside a loop is something very common in programming, and we will see more examples in coming episodes.
35. A grid of rotating objects creates a wave of rectangles
.background.draw.draw_rotating_rectangle.float.nostroke.rect.rect_size.resetmatrix.rot.rotate.setup.size.smooth.translate.void.while.
.rotation.grid.while.loop.spinning.
this is the second time we create a grid of objects.
in the previous episode we used a while loop inside a while loop. those loops increased two variables which were used to place rectangles in the screen.
in this episode we use again two nested while loops, but instead of counting pixels to fill the whole screen, we count how many rectangles we want to draw. then we use a function from previous episodes that creates rotating rectangles.
we try different things: all rectangles rotating with exactly the same angle, using a different angle for rectangles depending on the column, depending on the row, and finally we give a different rotation angle for each rectangle in the screen depending on the column, the row and a variable that constantly increases to make them spin.
36. Organic random animation using noise()
.background.draw.float.height.line.my_num.noise.setup.size.stroke.void.width.
.random.noise.
we have used random() in many of our episodes. we could say random() has one problem: it's too random. things in real life do not jump from place to place, but move in small increments. the noise() function allows us to get that kind of random numbers.
there are some differences between random() and noise(). random() returns a number between a minimum and a maximum value. noise() returns a value between 0 and 1. the parameters used when calling random set the minimum and maximum values. the only parameter used in noise() is used to get random numbers that do not change too much.
so if i call noise(3.00) and then noise(3.01), they will return a random number, but in both cases the number will not be very different. this is great for animating positions, sizes, rotation or colors.
normally we will be interested in ranges of numbers greater than the default 0 ... 1 range. we solve this by multiplying whatever number comes out of noise(). for example if we multiply noise() by 100, we will get a number between 0 and 100.
try to use noise() in any of the programs we created in past episodes!
37. Make a rectangle dance using noise()
.background.c2f.center.draw.fill.float.height.my_num.noise.nostroke.rect.rectmode.rotate.setup.size.smooth.translate.void.width.
.noise.random.animation.
our second experiment using the noise() function. in this case we make a rectangle move, rotate and resize using several calls to the noise() function. the noise() function takes one parameter. if you call noise() several times and the parameter is identical, you get back the same random number.
in our animation we call noise() five times with different parameters and we also try what happens when the parameters are equal. in that case it feels like the rectangle properties are linked. for example, moving to the right equals to a larger rectangle, or moving to the right means more clockwise rotation.
try animating also the background color, the fill color, the stroke, and maybe change the different numbers in the program trying to predict which effect your change will produce. can you make the rectangle move only on the left half of the display?
38. Animate the ocean surface using noise()
.background.draw.float.height.line.noise.setup.size.time.void.while.width.
.animation.noise.
imagine the noise() function is like looking through a hole in a paper. the noise function gives you back a random number depending on the parameters you send. in the case of our paper with a hole, it would return the color we see through the hole, and the parameters actually mean in which direction we are looking through the hole. if we point a little bit up, or a little bit right, the color changes. the same way, if we change the parameters in our noise() function a little bit, the number we get also changes a little bit.
in this episode we use the noise() function with two parameters instead of one. in our example, the first parameter is our current horizontal position and the second parameter is the time. as we slowly change time, the random numbers we get also change, creating something that looks like the surface of the sea.
39. The candy-space. Understanding noise() with 1 parameter
.co.colormode.ellipse.fill.float.hsb.noise.nostroke.println.size.while.width.
..
when we use noise() with one parameter processing assumes the missing two parameters are 0. we present noise as a function that picks up candies from inside a box. to locate each candy we need to give noise() three parameters: x, y and z. we are used to x and y now from working with the screen. the z represents the depth, so we no longer are limited to the display surface, but we can imagine objects behind the display and objects in front of the display.
this imaginary candy space is full of candies of different colors. each time our program starts, processing fills the candy space with candies. but the space has a unique property: candies next to each other are similar in color. you will not find a blue candy next to a green candy. that's the reason why, if you want to get slowly changing colors out of noise(), you should choose candies that are close to each other. that means changing the noise() parameters slowly, in steps smaller than 0.03. with larger increments you probably get very different values out of noise().
40. The candy-space. Understanding noise() with 2 and 3 parameters
.co.colormode.draw.ellipse.fill.float.height.hsb.noise.nostroke.setup.size.void.while.width.
.noise.
second part of our candy space example, where we try out the noise() function with two and three parameters. we first animate the colors of one line of ellipses. we use the time as the y value in the noise() function. then in another test we create a grid of circles, where each circle gets it's color using the noise() function, using the x and y position of the circle to choose a color. finally we animate the colors of this grid, by using time to increment the z variable in our noise() call, so we get a different set of colors for each frame of our animation.
41. A function that generates sine waves
.background.bc4.d66727.float.line.noise.point.random.sin.size.stroke.while.width.
.sin.sine.wave.
this time we try out a new function called sin(). it's a function related to math and trigonometry and it returns numbers between -1 and 1. sin() takes just one parameter. we will use sin() to generate all kinds of interesting graphics and animations in coming episodes.
42. Programming animated effects on Android phones
.background.colormode.draw.fill.float.height.hsb.line.nostroke.random.rect.setup.stroke.void.width.
.android.effects.phone.
this episode is probably only interesting for you if you own an android phone. we don't discover any new programming tricks but see how easy it is to execute your programs on android phones. it turns out the processing editor is already prepared for launching applications on your phone. that means that after you have downloaded the required android sdk software you can run most of our previous exercises right on the phone with one (shift) click. if you are lucky enough to own one :)
and don't worry! i'm not having a stroke :)
43. Animate using sin(). Less math thanks to map()
.background.baff0d.draw.ellipse.f15.fill.float.map.nostroke.setup.sin.size.smooth.void.
..
this time we use the sin() function to animate a circle. in our example it will move smoothly from left to right and then back, repeating this motion again and again.
the sin() function returns a number between -1 and 1. the noise() function returns a number between 0 and 1. all these numbers are too small for measuring pixels and drawing things on the screen. that's why we have to multiply those numbers to make them larger.
since the sin() function returns negative and positive numbers, it can be a bit tricky to convert them into interesting numbers we can use to draw things on the screen.
that's why we learn to use the map() function, which converts one number from a given range to another number in a new range. for example, it allows us to convert numbers coming out from the sin() function, which are in the -1 to 1 range, into a number which is in the 0 to 400 range, much better for drawing things on the screen.
44. Combine sine functions to create crazy waveforms
.background.float.map.point.sin.size.stroke.while.width.
.sin.sine.wave.
if you multiply several sin() function calls together, like in sin()*sin()*sin(), the result is still a number between -1 and 1, but you get much more interesting shapes when you use the result to draw or animate in your programs.
45. Convert distances into colors or widths
.background.co.colormode.float.hsb.map.point.sin.size.stroke.strokeweight.sz.while.width.
.map.range.numbers.software tutorial.education.
the map() function is very useful when you want to convert numbers from one range to another range. when do we want to do that? well, we use different ranges of numbers for different things. for example the sin() function returns values between -1 and 1. the valid x positions for drawing on our screen might be between 0 and 400. the right values for rgb colors usually are between 0 and 255.
sometimes we want to make the color depend on a distance, or maybe the width depend on a speed. you can link any two concepts that come into your mind in your program. using map() is the easiest way to convert values from one range to another.
46. Create beautiful curves with lots of sin() calls
.background.bri.co.colormode.draw.ellipse.fill.float.height.hsb.map.nostroke.setup.sin.size.sz.void.width.
.sin.graphics.trigonometry.math.draw.animate.animation.
now we use the sin() function to control many different properties. we animate circles moving on the screen. their x and y position is calculated using the sine function. the size, hue and brightness of each circle is also calculated with different formulas that use sin(). this trigonometric function by default gives a very simple and predictable result. but when we combine multiple sin() calls we can get more complex graphics, but which still change in a smooth way.
47. Share your Processing program with the world
.b1ff0a.background.copy.draw.ellipse.else.float.height.if.nofill.random.setup.size.smooth.stroke.void.width.
.sketchpad.share.
discover how you can show other people your cool processing programs. you can do that in just one minute:
1) select your program's source code in the processing editor
2) copy (shortcut = ctrl+c)
3) go to sketchpad and log in (create an account if you don't have one)
4) click on create new sketch
5) you will see some existing source code. you can delete it all and paste yours (shortcut = ctrl+v)
6) click run and see if your program is working fine
7) click the camera icon on the top right corner of your running program to capture a nice screenshot
8) change the program name, by default it's called untitled sketch
9) share your program. there are buttons for sharing on facebook and twitter. if you want to send a link to your program by e-mail, right click on "link to this revision" and copy the address. then past the address on an e-mail.
in sketchpad you can do more things. you can run programs created by other people. you can learn from their source code. you clone someone else's program and change it. you can even see other people programming on real time and chat with them while they do it!
show other people the cool programs you create! :)
update: https://openprocessing.org is another very nice platform where you can share your sketches and discover amazing work by others. give it a try :)
48. Load and animate an image of Rick
.background.draw.float.if.image.loadimage.photo.pimage.setup.size.void.width.
.roll.school.load.image.animate.rick.
discover how to load a jpg image into your processing program. jpg is the standard photo format for most digital cameras and cell phones. the first thing you need to do is to save your processing program to your hard drive, and then use the "add file" option in the sketch menu of processing to copy the image into your project folder.
once the image is inside your project folder it is accessible from your program. then you need to do two things: first, to load the image into a variable using loadimage(). instead of storing the image in a float variable, which is good for storing numbers, we use a pimage variable, which is good for storing images.
once the image is inside the variable we just call image(photo, 0, 0) and the photo will appear on the top left corner of your window. in this example "photo" is the name of the variable, but you can try choosing a better name.
49. Show part of a loaded image using copy()
.background.copy.draw.line.loadimage.photo.pimage.setup.size.stroke.void.width.
.copy.image.loadimage.
second episode that deals with loading images. we review how to use loadimage() and then use image() to show a full image in the screen. then we learn about copy(), which allows us to show only one part of a loaded image, and at the same time stretch or resize that part. copy() takes 9 parameters, our record :) the first parameter is the variable that holds the loaded image. then there are two series of 4 parameters which are similar to the ones used when drawing a rectangle: x, y, width and height. the first 4 parameters refer to the loaded image: which part of that image do you want to display? the second 4 parameters refer to the display: in which area do you want to show the image area selected by the first 4 parameters?
all parameteres can be animated. just replace a fixed value by a variable, and change that variable over time.
50. What are global and local variables?
.float.my_test.println.setup.void.
.scope.global.local.
find out the difference between global and local variables. global variables are declared outside any function, and they can be accessed (used) on any function in the program. local variables are declared inside a function, and can be used only inside that function. it is possible to have local variables with the same name in different functions. even the name is the same, they are not the same. it's like two people with the same name. even the name is the same, the persons are not.
the scope of a variable refers to where is a variable visible or accesible. if a person asks what is the scope of a variable, she's asking whether it is local or global.
51. Convert float into int and animate a photo
.background.copy.draw.float.int.line.loadimage.map.noise.photo.pimage.setup.size.stroke.void.width.
.copy.int.float.convert.datatype.software tutorial.
we now continue with the program started in episode 49 where we copy() part of a photo and show this part on our screen. the idea is to animate it by moving which part of the loaded photo we show. if we randomly change the vertical position of the part we copy, we will have an interesting effect. but we encounter a little problem: copy accepts only integer values like 2, 5, 33 or 43, but random() and noise() return float values like 1.4325 or 38.4124. we solve this by converting the float value into an integer by using the int() function.
52. The drunk camera man effect
.background.copy.draw.float.he.height.int.line.loadimage.map.noise.photo.pimage.setup.size.stroke.void.wi.width.
.copy.animate.int.noise.animation.
discover how to read the width and height of a loaded image. we use this information to get random rectangular parts of that loaded image while staying inside it.
53. Create a pattern by drawing 150000 pixels
.colormode.float.height.hsb.int.map.point.random.rnd.save.sin.size.stroke.while.width.
.pattern.texture.while.loop.sin.noise.random.
instead of drawing some shapes in the screen, this time we are going to draw every single pixel in our display. we draw first all the pixels in the first column, then the second column and so on until we cover the whole screen. if we always use the same color the result is the same as using background(). but if we change the color of each pixel we can create interesting patterns. we quickly try using random(), noise() and sin(). finally we add a line that saves the picture to the hard drive. but it's not nice to save it always with the same name, because the previous image gets replaced. to solve this we generate a random name for our picture. each time the program runs, it saves an image with a random file name.
54. Infinite Forest? Combine random words using an Array
.adjectives.background.fill.int.nouns.random.string.text.
.random.word.text.array.
arrays allow us to work with a collection of items of the same kind. for example, a list of numbers, or a list of words. in this episode we create two list of words and pick randomly one word from each list to create funny combinations. to declare an array we write square brackets behind the variable type. for example, instead of float we would write float[]. for string, we type string[]. an equal sign follows, and then a list of elements surrounded by curly braces and a semicolon ";" at the end of the line. notice that when we use curly braces with if() or while() sentences, we don't write semicolons behind { or }. but we do on the line where we define an array.
also note that inside an if statement you type two equal signs to compare. for example, if(a == 3) { ... it is a ver common mistake to type only one equal sign. in that case you don't get an error, but the program does not work as you expect.
55. How many items in an Array?
.int.length.nums.println.random.which.
.array.length.int.float.string.
arrays are probably used in every single program we write, so it's important to understand how they work. we can create arrays of numbers and also arrays with texts. an array is just a list of items, a collection. instead of declaring 100 variables, we just declare one variable telling processing that it will contain 100 different values inside.
to access each element in the array we use the square brackets with a number inside them. for example print(car_brand[22]); would print the car_brand number 22, supposing car_brand is an array that contains car brands.
to know how many items are in an array, we do print(car_brand.length); that means we add ".length" to the variable name, and this returns how many elements the array contains.
we know that when we call random(100) we get a random number between 0 and 100. but there is one important detail: we never get 100. the number we get is always smaller than 100.
sometimes we want to use random() to choose a random element from an array. if the array has 5 elements, we can use int(random(5)) to choose the element and we will get back the integer numbers 0, 1, 2, 3 and 4, never 5, which is exactly what we want. in an array that has 5 elements, the first element is 0 and the last one is 4.
56. Silly poet writes absurd things
.adj.art.background.fill.int.length.nou.pre.println.random.setup.string.ver.void.words.write_word.
.funny.poetry.sentence.generator.phrase.writer.software.random.poem.
we had a program that wrote a random adjective and a random noun together. it was printing things like "tall tree" or "sticky sky". we continue changing this program so it can write longer sentences. until now we had an array with adjectives and another array with nouns. we add three new arrays: articles, verbs and prepositions. this allows us to build rather long sentences.
to print the words we create our own function called write_word(). this function only receives one parameter: an array of words. so if we want to print a random adjective, we use write_word(adj). if we want to print a random preposition, we call write_word(pre).
the function receives the whole list of words. looks at how many words there are in this list, and prints one of them randomly.
57. A random sentence generator writes nonsense
.adj.art.background.draw.fbf.fill.int.keypressed.length.mousepressed.new_sentence.nou.pre.random.random_number.save.setup.size.string.text.textsize.ver.void.words.write_word.
.random.words.sentence.absurd.strange.crazy.weird.silly.funny.lol.
the improved version of the silly poet can save images to the hard drive when we press a key on the keyboard. it also generates a new sentence when we click the display. that means we must listen to keyboard presses using the keypressed() function, and we also listen to the mouse clicks using mousepressed(). both of these functions require that a "void draw()" function exists in our program, even if it's empty. if there is no draw() function, then mousepressed() and keypressed() will never be called, and you will wonder why :)
58. Travel through space, use an array to move stars
.background.draw.float.height.if.int.new.point.random.setup.size.speed.stroke.strokeweight.void.while.width.
.stars.animation.field.star.moving.motion.array.
this time we are building a moving star field. the stars are just points drawn with point(). each star has three properties: x, y and speed. since we are drawing 100 stars, we use three arrays to hold all the information, otherwise the program would be hundreds of lines long.
each array hold 100 values. that means we have 100 "x" values, 100 "y" values and 100 "speed" values.
x[0], y[0] and speed[0] are the properties of the first star. x[1], y[1] and speed[1] are the properties of the second star, and so on.
each time draw() is called we substract a few pixels from each x. how many pixels? it depends on the speed that was randomly assigned to each star when setup() was called when the program started. so maybe we move the first star 3 pixels to the left, and the second star 1 pixel to the left. the amount of pixels is stored in the speed[] array, so each star has a constant speed.
59. A space-triangle flying through the galaxy
.background.co.draw.float.height.if.int.map.mousex.mousey.new.nocursor.point.random.setup.size.speed.stroke.strokeweight.triangle.void.while.width.
.space.animation.animate.ship.triangle.nocursor.track.mouse.
some quick enhancements to our previous moving star-field. we make the slow stars smaller than the fast stars. we let the star speed define also the star size. we do that by using the speed to set the strokeweight(). since the speed is a number between 1 and 5, that value is compatible with the strokeweight(). we also make slow stars darker than fast stars. but the color values are not so compatible with the speed. the speed is a number between 1 and 5, but the colors are usually numbers between 0 and 255. so we decide to use map() to convert the 1 to 5 range into a 100 to 255 range. stars moving 1 pixel per frame will get a gray shade of 100. stars moving 5 pixels per frame will get a bright white color. stars moving at speeds between 1 and 5 will get also different shades of gray.
then we draw a triangle that represents a small space ship. we draw this triangle wherever the mouse pointer is, so we can control the position by moving the mouse. we then call the nocursor() function to hide the mouse pointer, which didn't look so good on top of our "space triangle".
60. Are two circles touching or intersecting?
.background.diam.dist.draw.ellipse.else.float.height.if.mousex.mousey.nofill.noise.random.setup.size.stroke.strokeweight.void.width.
.dist.distance.two.points.interescting.circles.touching.software tutorial.
use the dist() function to calculate the distance between two points in the screen. why would you want to do that? well, you can use the distanceto know if two circles are overlapping. if the distance between the centers of the circles is less than the radius of the first circle plus the radius of the second circle, then they are touching.
the radius of a circle is the distance between the center of the circle and any point in the circle itself.
61. Draw shaky points, append items to an array
.append.background.draw.ellipse.else.fill.float.if.int.length.mousepressed.mousex.mousey.nostroke.random.setup.size.void.while.
.append.array.increase.length.software tutorial.
arrays do not need to be of a fixed size. in previous episodes we created arrays that had a fixed amount of elements inside. this time we begin by creating an empty array, but we then make the array longer each time we click on the screen.
when we start the program we do not know how many times we will click the screen, so that's why we start with an empty array and make it longer with each click.
62. A screen full of bouncing circles
.append.circle_x.circle_y.d60dff.draw.ellipse.fill.float.height.if.int.length.mousepressed.mousex.mousey.move_x.move_y.nofill.random.rect.setup.size.stroke.sz.void.while.width.
.array.bouncing.circles.ball.
in episode 15 we created a program that displayed one circle bouncing on the four borders of the screen. we now take that program and modify it so it can show any number of bouncing circles.
the original program used four global variables. two for storing the horizontal and vertical position of the circle, and two for storing the direction in which the circle is moving.
those four variables must now be arrays. the arrays will hold the horizontal position of each circle, the vertical position, the horizontal motion amount, and the verticla motion amount.
because there are several circles now, we have to use a while loop to go through each circle in the array to draw it and move it to a new position.
we could have created several circles when the program starts, but instead we begin with no circles, and let the user click the screen to add new ones.
63. Time for our first 3D animation
.background.box.draw.float.map.mousex.mousey.noise.p3d.rotatey.setup.size.translate.void.
.3d.software tutorial.
after many episodes of 2d graphics we find out how to draw things on 3d. it's actually very simple. we call the box() function to draw a 3d cube. we send just one parameter to box() to indicate the size of the box. to place the cube somewhere in the screen we use translate(). it's not the first time we use translate, but it is the first time we use it with three parameters. the third parameter indicates the depth, or how close to you or far away from you is the cube. this third parameter is called z. if z is positive, the object is closer to you. making that value smaller, even negative, will bring the cube away from you.
using the box() function will not work if you don't change the current renderer. by default, processing wants to draw only 2d. to switch to 3d mode, you can add a third parameter when you call size, for example size(400, 400, p3d); the p3d part is telling processing you want to do 3d graphics.
once you get used to using translate() to move the cube around, try using rotatex(), rotatey() and rotatez() to make the cube rotate around different axes.
64. Animate objects that slow down and stop using lerp()
.background.draw.ellipse.fill.float.lerp.mousex.mousey.nostroke.setup.size.void.
.animation.motion.decelerating.
in this episode we find out how we can animate an object that does not move at a constant speed, but is reducing its speed, like a car approaching a red traffic light. what we do in each frame of our animation is to find out the middle point between where we are now and where we want to be, and move to that middle point. frame after frame we move half of the distance to our destination. the steps becomes smaller and smaller, so it looks like we are moving slower and slower until the steps are so small that it looks like are not moving anymore.
to achieve this kind of animation we use a function called lerp(). with lerp we can find out what's the middle point between two other points. for example, we can find what's the middle x between the current x and the destination x. not only we can find the middle point, but also other points between two numbers that are closer to the first number or closer to the second number.
65. Are we getting close? Use dist() to find out the distance
.background.destx.desty.dist.draw.ellipse.fill.float.height.if.lerp.nofill.nostroke.random.setup.size.stroke.void.width.
.dist.distance.lesson.
the dist() function can be used to find out the distance between to points. in our example we test how far is a moving circle from the mouse pointer by writing: float d = dist(x, y, mousex, mousey);
now that we know the distance, we can do different things when we are getting close to our destination.
66. How random is random? randomSeed() & noiseSeed()
.colormode.fill.height.hsb.int.nostroke.println.random.randomseed.rect.seed.size.while.wi.width.
.random.noise.randomseed.noiseseed.
if you ever need to get the same random values time after time, you can achieve that by using randomseed() and noiseseed(). they affect random() and noise() respectively, and both take just one numeric parameter. by default, processing selects a random seed for both random() and noise() when your program starts. but if you set a specific seed using randomseed() or noiseseed(), the random values you get will be the same each time. for instance, if you run randomseed(123); and then print(random(100)); the random number you get is always the same number between 0 and 100.
67. Circular motion: sine and her cousin.
.background.co.colormode.cos.draw.float.height.hsb.if.line.map.setup.sin.size.smooth.stroke.strokeweight.void.width.x0.x1.y0.y1.
.sine.cosine.sin.cos.circular.motion.computer programming.
we have previously used sin() to generate numbers that continuosly slide between -1 and 1, but we did not study what sin() represented. this time we do that. we have a look at sine and cosine, two similar functions that help us create a circular motion. you can play with the sine/cosine tool at http://bit.ly/sine_cosine i hope it helps you understand sine and cosine.
68. Circular motion reviewed
.cos.draw.ellipse.float.height.if.noloop.random.setup.sin.size.two_pi.void.width.
.sine.cosine.circular.motion.animation.
a review of how we create a circular motion. we make x = 100 + cos(a) * 200, and y = 120 + sin(a) * 200. in this example, (100, 120) is the center of the circle. the radius of the circle is 200. that's the distance from the center of the circle to the circle itself. and we use sine and cosine to calculate the points in the circle. the variable "a" is the angle, that means how much are we rotating around the center. if "a" is 0, we are at the right side of the center. as we increase "a", we rotate around the center. when "a" reaches 6.28 we have completed one full rotation around the center. that number is actually two times a special number called pi. when you are interested in making one complete turn around the center you can use a variable called two_pi, which is more precise than just typing 6.28. if you plan to keep spinning around the center then you don't need to know about pi or two_pi.
69. Combine circular and other motions
.background.cos.draw.ellipse.fill.float.height.nostroke.setup.sin.size.smooth.void.width.x2.x3.y2.y3.
.animation.circular.motion.
objects can have more than one motion attached to them. for example an airplane may be flying forward and up. a leave falling from a tree is rotating and moving down. you can do the same in your programs: you can add several motions together to create a more complex motion. in this episode we combine linear motions, circular motion and a bit of randomness.
70. Slowly change the direction
.background.colormode.cos.draw.float.height.hsb.line.newx.newy.nofill.oldx.oldy.random.reset.setup.sin.size.smooth.two_pi.void.width.
.direction.angle.sin.cos.sine.
we can use an angle to define in which direction we are moving an object. if we slowly change that angle, we smoothly change the direction too. in this episode we create a program that draws a line. the line is born at the center of the screen and moves toward a random initial direction. this direction slowly changes randomly. sometimes it will be a quite straight line, other times it might turn around and go back where it was coming from. we achieve this by using sin() and cos() to calculate what is the next position according to the current position and the current direction.
71. Playing with directions
.background.colormode.cos.draw.float.height.hsb.if.line.newx.newy.nofill.noise.oldx.oldy.random.reset.setup.sin.size.smooth.stroke.strokeweight.two_pi.void.width.
.or.direction.angle.strokeweight.lesson.
one thing we discover this time is how to make an if() statement that tests more than one thing: do something if certain thing is true, or if some other thing is true. the key here is the "or". in the current example, we want to check if our line has gone out of the screen through any of the four borders. this is translated into: if the line crossed the top border, or if the line crossed the left border, or the right border, or the bottom border, then jump back to the center of the screen. we are checking if at least one of those conditions is true. in many programming languages, processing included, we type two vertical bars "||" when want to say or. for example, if(i == 1 || i == 2) would test if the variable "i" is either 1 or 2.
in this episode we also play with the line width and color, and with the direction in which the line turns most of the time.
72. Create visual rhythms using modulo
.background.draw.fill.framerate.if.int.nostroke.rect.setup.size.void.
.modulo.rhythm.animation.timing.events.
with the modulo function we can trigger events at regular intervals. if we have a variable "n" that increases each time draw() is called, we can write if(n % 11 == 0) { ... } to do something every 11th frame. the 0 value can be any value between 0 and 10. if you want to trigger just one event, that number is not important. but if you want to trigger two consecutive events, then you can for example use n % 11 == 4 for the first event, and n % 11 == 5 for the second event. for all the other values (0, 1, 2, 3, 6, 7, 8, 9, 10) nothing would happen. don't worry if you don't understand how it works yet. try watching the video and writing the example programs. we will keep working on it on coming episodes.
73. The circlebeats of a running circle
.background.csize.draw.ellipse.fill.grow.if.int.nostroke.setup.size.smooth.void.
.modulo.repeating.event.
a music box can be similar to an expression that uses a modulo. both can be used to trigger repetitive events, and both run in circles: the end connects with the beginning.
in todays episode we use the modulo to trigger a regular event. we draw a circle with a fixed size of 50 pixels, but when the event is triggered, the circle will quickly grow to 80 pixels, and then slowly shrink back to 50. the idea is to simulate a heartbeat animation, but using a circle.
with an if() statement we check if the circle has grown enough. when it has grown enough, we reverse the direction of the growth. we don't want it to grow all over the screen. now that the circle is shrinking, we need another if() statement to make sure it does not become too small. we also need to stop the shrinking at some point.
so we could say the circle has three behaviours: waiting with a size of 50 pixels, growing to a size of 80, and shrinking back to 50. repeat.
74. for() loops and other ways of typing less
.draw.for.framecount.framerate.if.int.noloop.print.println.setup.void.while.
.for.loop.increment.decrement.framecount.
usually in programming languages there are many ways of doing a task. some ways are shorter than others. in this episode we discover three things we can do to make our programs a little bit shorter. the first one is using increment "++", decrement "--", the add-assign "+=" and the subtract-assign "-=" instead of the longer version we have used in previous episodes: "i = i + 1", "i = i - 1", "i = i + 3" or "i = i - 3".
the second thing we discover is the "framecount" variable. this is an integer variable that increases each time the draw() function is called. if you want to know how many animation frames processing has drawn while running your program, have a look at the framecount variable. often in our past episodes we created such a variable that was increasing over time. since we have one available, we don't need to create our own.
finally we learn about the for() loop. previously, if we wanted to run part of our code several times, we created a while() loop. it usually meant declaring and initializing a variable before calling while(), then writing a while() expression with a condition inside, and then inside the while() loop we increased a variable. we can do those three things at once in a for() loop, so we write one line instead of three. this way we also avoid forgetting the increasing of the tested variable, so using a for() loop is good for avoiding creating infinite loops.
75. Bezier curves are so beautiful
.background.bezier.for.height.int.nofill.random.size.smooth.width.
.bezier.curve.lesson.education.
many shapes in real life are not based in lines, circles and rectangles so it's really useful to discover bezier curves in this episode. the bezier() function takes eight parameters when working in 2d (more if we are working on 3d, but we leave that for later). these eight parameters are actually the x and y values of four points. the first two parameters define the point where the line starts. the last two parameters define the point where the line ends. the two points between the start point and the end point act as magnets.
the lines we drew in past episodes always went straight from the start point to the end point. but with bezier curves we don't need to take always the shortest route. we can leave the start point going in any direction we want. this initial direction is defined by the first control point. the second control points defines from which direction we arrive to the end point.
it's a good idea to play with an interactive bezier-curve tool in some web page to get a feeling about how these curves behave.
76. Slowly morphing bezier curves
.background.bezier.draw.float.for.framecount.height.int.nofill.noise.setup.size.smooth.void.width.
.bezier.curve.animation.
bezier curves are built using four points. to animate a bezier curve you can animate one or more of those four points. if you use random() the animation will not be smooth, which is sometimes ok. if you prefer a more smooth animation you can use the noise() function. if one of the parameters of the noise() function changes slowly over time you will get slightly different random numbers each time your draw() function is called. we create such a slow changing value by dividing framecount by a number, for example 100. in that case you get a number that increases 100 times slower than the original framecount.
one thing to be careful with is that if you divide two integer numbers you get an integer number. for example 9 / 2 is 4, not 4.5. so if you divide framecount by 100, you will keep getting 0 as a result, then you will get 1 for the next 100 frames, then 2 for the next 100 frames... this is easily solved by making one of the numbers a float. one way of doing that is adding float() around one of those numbers. for example float(9) / 2, or float(framecount) / 100. but the easier solution is just to add decimals to one of the numbers. for example 9.0 / 2 or framecount / 100.0. note the ".0" at the end of the numbers.
77. A 3D rotating cloud of points
.amount.background.box.draw.for.framecount.height.int.new.nofill.p3d.point.random.rotatey.setup.size.stroke.strokeweight.translate.void.width.
.rotatey.animate.point.cloud.points.
in episode 63 we saw how to create a rotating box(). it was our first 3d experiment. this time we create a rotating box(), but we fill it with points floating in the air. the position of all the points is pre-calculated when the program starts, inside the setup() function. there we fill three arrays with random numbers. we need those numbers to stay the same between calls to the draw() function. that's why we need to "memorize" all the points: we create random position for many points, and we store those positions in three arrays. later, each time we call draw(), we use the information saved in those arrays to draw the same points over and over. the reason why they appear to move even when we draw them on the same exact locations is that we are using the rotatey() function to rotate everything we draw by a certain amount, and this amount is continuously increasing.
78. An array is like a book full of numbers
.background.box.draw.for.framecount.height.int.line.new.nofill.p3d.pages.random.rotatey.setup.size.smooth.stroke.strokeweight.translate.void.width.
.rotatey.rotate.animate.animation.star.
review of previous episode where we created a cloud of points spinning in 3d. we try to understand how do arrays work, and we imagine them to be like books, where each page is an element of the array. we also do a small change to the program replacing point() by line(), so we create something that looks like a spinning star in 3d.
79. A spinning star becomes a plant
.background.bezier.draw.for.height.int.map.mousex.new.nofill.p3d.pages.point.random.rotatey.setup.size.smooth.stroke.strokeweight.translate.two_pi.void.width.
.3d.rotate.animate.
this is the third time we modify our 3d rotating cube. the first time it contained floating points. the second version contained lines pointing from the center in many different directions. it looked like a star. this third version uses bezier curves, and hopefully it looks a little bit like a plant. all our curves begin at the bottom of the cube, right in the middle of the floor, and they all continue straight up because the first control point is at the middle of the ceiling of the cube. the end point is somewhere random inside the cube. to simplify things, we avoid thinking of an original second control point for each curve. we just reuse the end point as second control point.
don't worry if you don't understand yet the x, y and z axes, it can be confusing at the beginning. we will study them with more detail in the future.
80. The color datatype
.a78f2.background.color.ellipse.fc8e05.fill.float.img.int.name.nice_blue.orange.pimage.println.smooth.string.stroke.strokeweight.white.
.color.datatype.
learn about a new data type called color. each data type is meant to store some kind of information. the int type is used for integer numbers. the string type is used for text. the color data type is used for storing and reusing colors.
81. How to read the color of a pixel
.color.color_under_mouse.draw.fill.float.for.get.int.map.mousex.mousey.noise.point.rect.setup.size.stroke.void.width.
.get. read. pixel.
with the get() function we can read the color of any pixel in our program window. we can specify which pixel we are interested in by using x and y coordinates as parameters. for example, color mycolor = get(100, 200); would grab the color of pixel 100, 200 and put that color into the mycolor variable. you can use this on many different ways. for instance you could grab the color of the pixel under the mouse pointer and use it for drawing something. or if you wanted to draw a shape at a certain place, you could observe the color of pixels near that place. now you will be able to draw things that depend on things which were previously drawn in the screen.
82. Program a gradient of colors
.c1.c2.color.colormode.draw.float.for.height.hsb.int.lerpcolor.line.map.newc.random.setup.size.stroke.void.width.
.gradient.colors.lerpcolors.
with the lerpcolor() function we can find a color that is between two other colors. the lerpcolor() function takes three parameters. the first two are colors. the third parameters indicates if the new color we get should be closer to the first color or to the second. 0.5 means right in the middle of the two. numbers below 0.5 mean closer to the first color, and number greater than 0.5 mean closer to the second.
what we do in our program is getting all the possible colors between the first color and the second one by slowly increasing the third parameter from 0 to 1. with each color we get we draw one line. after filling the screen with lines of different colors we get a nice looking vertical gradient.
83. Circular gradients can look like spheres
.background.c1.c2.color.colormode.draw.ellipse.float.for.hsb.int.lerpcolor.map.maxr.newc.nofill.random.setup.size.stroke.strokeweight.void.
.circular.gradient.
there are many ways to do gradients. in episode 82 we created a linear gradient. in this one we create a circular gradient. the idea is simple: draw a shape multiple times while slightly changing the color and some other property, for example the position or the size. for the linear gradient we keep changing the position of the lines we draw. for the circular gradient we keep changing the size of the circles we draw.
84. Draw gradients, review functions and image loading
.back.background.c1.c2.color.colormode.draw.draw_circ_grad.ellipse.float.for.hsb.image.int.lerpcolor.loadimage.map.maxd.mousepressed.mousex.mousey.newc.nofill.pimage.random.setup.size.smooth.stroke.strokeweight.void.
. load. image. gradient. function. global. local. rename. variable.
this time we don't introduce new concepts but review previous ones. first we rename a variable to give it a more correct name. then we convert two global variables into local variables and the program becomes slightly shorter. next we change the program so instead of just drawing one circular gradient it draws a new one each time we click the screen. for that we see again how functions are declared, and how parameter types must match.
finally we try loading and displaying an image as a background, so the screen is not so empty when the program starts :)
85. Using a background image, mousePressed and mouseReleased()
.back_image.background.draw.ellipse.ff760d.float.if.loadimage.mousepressed.mousereleased.mousex.mousey.nofill.pimage.setup.size.smooth.stroke.void.
. mousepressed. mousereleased. image. background.
while programming you have to pay a lot of attention to details. for example, there is a function called mousepressed() and there is a variable called mousepressed. the function gets called once when we click with the mouse. the variable has a value of true or false depending on if the mouse is currently clicked or not.
since i want to make a circle grow while the mouse is clicked, i should keep checking the mousepressed variable inside the draw() function. each time i notice the mouse is pressed, i make the circle a little bit bigger.
but i need a way to make it smaller again, otherwise it would grow out of the screen at some point. i use a function called mousereleased() to achieve this. that function is executed when i stop pressing the mouse button, so it's a great place to reset the size of my circle.
after trying these mouse related functions and variables we use for the first time an image as a parameter for the background() function. in all previous episodes we used a color instead, so we were erasing the whole screen with a color, often white or black. but as we can see now, it's possible to erase the screen using a photo.
we end the episode with a question that will be answered in the next episode: how to draw a new circle each time we click the mouse? the difficulty here is that i want to move a circle when i move the mouse, and make a circle stay there in the background when i click. if i wasn't moving a circle it would be easy. i could just remove the background() call, and then just draw a new circle each time i click. but if i want to move a circle, i need to call background() to keep erasing the circle i'm moving, otherwise it gets full of circles as i move the mouse. tricky :)
86. Drawing shapes with your mouse
.back_image.background.draw.ellipse.ff760d.float.if.loadimage.loadpixels.mousepressed.mousereleased.mousex.mousey.nofill.pimage.pixels.setup.size.smooth.stroke.updatepixels.void.
. pixels. loadpixels.
in this episode we discover something easy to do, but not so easy to understand or explain :) we could say we work with two displays. one is the basic processing display. we also have another display. we can copy any of the two displays into the other. we use this as a way to take a photograph of the main display. things are changing in the main display. when something interesting happens (we release the mouse button), we copy whatever we see in the main display to the other display. this other display is just an image stored in a variable.
at any moment we can draw that copied display into the main display. we do this many times per second.
this, which may sound slightly confusing, results in a very simple effect: we are now able to move an object over the screen, and make it stick on the background whenever we click.
87. Playing with strings
.background.charat.day.draw.ffb81f.framerate.hour.indexof.message.minute.month.nf.println.second.setup.size.string.text.textsize.void.year.
.string.date.time.nf.
we have been using numbers very often in our programs. this time we do some text manipulation. the data type used for text is called string. we discover how we can use the "+" character to join strings and test date and time functions like year(), month(), day(), hour(), minute() and second(). we create a small running clock and discover how to force a number to be printed always using two digits using the nf() function. nf() means "number format". to end the episode, we use a function called charat(0) which returns one of the characters of a string (for example the first letter, or the third one), and another function called indexof("t"), which tells us where in the string a certain letter is found. for example, find out where inside our string is the letter "t". processing will return a number indicating the position, or -1 if the letter is not found.
88. Change pixels using the pixels array
.color.draw.for.int.length.loadpixels.pixels.random.setup.size.updatepixels.void.
.pixels.loadpixels.updatepixels.
short review of arrays. we create an array, count how many items it has, print one of the items and also modify one of them.
then we move onto the pixels array, which allows us to manipulate the graphics by using an array. it probably sounds more complicated than using point(), get() and set(), but it's also much faster. in some cases we will want to use this method. to show an example of using the pixels array we fill the whole screen with random pixels, and we do this inside the draw() function, so we get an animated effect which runs very fast, much faster than updating pixels using point().
89. Create your own photo filters
.blue.color.draw.float.for.green.image.img.int.length.loadimage.loadpixels.pimage.pixels.red.setup.size.updatepixels.void.
.pixels.filter.channel.
in the previous episode we used the pixels array for the first time. we wrote random shades of gray to every pixel. the result was an animation that looked like an analog tv that lost the signal.
this time, instead of replacing every single pixel with random values, we read the red, green and blue values of each pixel, and then modify those values. by doing this we can tint the image or convert it into a black and white image.
90. Change pixel hue, saturation and brightness
.brightness.color.colormode.draw.else.float.for.hsb.hue.if.image.img.int.length.loadimage.loadpixels.pimage.pixels.saturation.setup.size.updatepixels.void.
.pixels.hue.saturation.brightness.
for most people it is easier to think about about a color in terms of hue, saturation and brightness than in terms of red, green and blue. yellow is one hue, but is made of red and green, which might not be very intuitive.
in this episode we learn how we can read the hue, saturation and brighness of the pixels in our display. we then use that information to define a new color for each pixel.
using this technique we can create programs that modify the colors of any image.
91. Timelines: tell a story
.background.d77ea.draw.ellipse.else.float.height.if.int.line.millis.noloop.random.rect.scene1.scene2.scene3.setup.size.void.width.
.elseif.millis.story.timeline.
in this episode we discover a way to run several programs one after another. we can decide how long each program runs. this can be used to show different scenes, for example some welcome text, then an animation, and finally some credits showing the date and the author of the program. but it can also be used to tell stories, for example by showing a dialog where different characters speak in turns.
to measure time we use the function millis(), which tells us for how long the program has been running. it returns an integer with the number of milliseconds since the program started. one second is one thousand millisecods.
using the if() statement we can decide if certain lines in the program should execute or not. when we use if-else we can decide between two different options. that means that we are deciding if to run one line (or group of lines) or a different line (or group of lines).
in this episode we introduce the complete if() statement, that includes if-elseif-elseif-else. this allows us to have not only two options, but many options, one of which will execute depending on the conditions we write.
92. Interactivity: a draggable circle
.arrow.background.bgcolor.color.colormode.cursor.dist.draw.ellipse.else.fill.hand.hsb.if.int.mousepressed.mousex.mousey.nostroke.random.setup.size.smooth.stroke.strokeweight.sz.void.
.cursor.interactive.circle.click.rollover.rollout.drag.
let's focus for a while on interactivity. we have made many programs that just run, but often we could not influence much the behavior of the program. it's a good time now to learn how to create buttons we can click and objects we can move.
to get started we create this program where we can click and drag a circle to a new position. the circle reacts to our moves, and it changes slightly when we place the mouse pointer on top of it. it also changes when we click it. these changes are little gestures that tell us something without using words. it tells us we are dealing with an interactive object.
one new function we discover in this episode is called cursor(). it allows us to change the shape of the mouse pointer. this is used in web-sites: when you move the mouse pointer over something you can click, the pointer changes. now you know how to create that effect in processing.
93. Draggable circle with tweening
.arrow.background.bgcolor.color.colormode.current_alpha.current_weight.cursor.dist.draw.ellipse.else.fill.float.hand.hsb.if.lerp.mousepressed.mousex.mousey.move.nostroke.random.setup.size.smooth.stroke.strokeweight.sz.target_alpha.target_weight.void.
.tween.rollover.rollout.drag.
in this episode we discover how we can tween properties. tweening means slowly transforming a certain property of an object, for example the color, the size, the border color or the border width.
in the previous episode we changed the border of a circle depending on the mouse position. but all the changes were on/off type. either there was border or there wasn't. either the border was thin or thick.
to be able to tween properties we need variables where we store the current value of the property and the desired value of that property. then, step by step, we change the current value to approach the desired value. we use lerp() to slowly change the property.
94. Boolean: true or false?
.boolean.else.false.friendhasmoney.if.ihavemoney.print.
.boolean.true.false.and.or.
the boolean data type is often used for making decisions. a boolean variable can only have two different values: true and false. there are different ways of comparing values. we can test if a number is greater or smaller than another number, if they are equal, if they are different. in each case a value of true or false is returned. we can print this value, or store it in a variable of type boolean.
the same way numbers can be added, substracted and multiplied, boolean values (true and false) can be combined by using and, or and not. imagine we have two boolean values called a and b. each can be either true or false. a and b is true only if both variables are true. a or b is true if any of the two variables is true. when writing programs you don't write and, or or not. you use &&, || and ! instead. for example if(x > 10 && x < 20) { print("x is a number between 10 and 20"); }
95. Is the mouse inside a square?
.arrow.background.bgcolor.center.color.colormode.current_alpha.current_weight.cursor.draw.else.fill.float.hand.hsb.if.lerp.mousepressed.mousex.mousey.move.nostroke.random.rect.rectmode.setup.size.smooth.stroke.strokeweight.sz.target_alpha.target_weight.void.
.point.rect.square.inside.
calculating if the mouse is inside a circle is very easy. we just need to know the distance from the center of the circle to the mouse pointer, and if this distance is less than the radius of the circle, we are inside. the radius of the circle is the same as half the size of the circle.
calculating if the mouse is inside a square is a bit more tricky. we need to know four things. is the mouse below the top border of the square? is the mouse above the bottom of the square? is it on the left side of the right side of the square? is is on the right side of the left border? if those four conditions are all true, then the mouse pointer is inside the square.
96. Easier mouse in a rectangle
.background.bgcolor.boolean.color.colormode.corners.draw.fgcolor.fill.float.hsb.if.inside.int.mousepressed.mousex.mousey.newcolor.nostroke.random.rect.rectmode.return.setup.size.void.x1.x2.y1.y2.
.rect.inside.mouse.point.
using rectmode(center) makes it harder to find out if the mouse is inside a square. if we use rectmode(corners) the program becomes much simpler because we don't need to calculate the position of the four walls of our rectangle: we already know them.
in this episode we also see a small example of how we can generate colors that have the same hue but a different brightness or saturation.
97. Interacting with many rectangles (I)
.amt.background.bgcolor.color.colormode.corners.draw.fill.for.height.hsb.int.new.nostroke.random.rect.rectmode.setup.size.void.width.x1.x2.y1.y2.
.interactive. rectangle. mouse. over. array. collection.
this time we create five arrays to store information about a collection of rectangles. the five arrays are used to store the color and the left, top, right and bottom borders of each rectangle.
by storing this information in arrays we can draw those rectangles as many times as we want, and also calculate if the mouse is inside or outside of each rectangle.
no new concepts are introduced this time. episode 98 continues where this one ends.
98. Interacting with many rectangles (II)
.amt.background.bgcolor.color.colormode.corners.draw.else.fill.for.found.height.hsb.if.int.mousepressed.mousex.mousey.new.nofill.nostroke.random.rect.rectmode.setup.size.stroke.void.width.x1.x2.y1.y2.
. interactive. mouse.rectangle.array.click.drag.
in episode 97 we created a collection of rectangles which we drew on the screen, but which had no interactivity at all. let's fix this now.
in this episode we keep continuously checking if the mouse is inside any rectangle from our collection of rectangles. when it is inside, we highlight the border of that rectangle.
we draw all rectangles in our collection one by one. each time we draw one, we check if it is under the mouse. if it is under the mouse, we store the rectangle number in a variable called "found", so we can use that number later.
once all rectangles have been drawn, we check if the "found" variable contains the number of a rectangle. if it does, we draw a border for that rectangle.
later we improve the program. instead of allways drawing a border for the found rectangle, we check if the mouse is pressed. if it's not pressed we draw the border. but if it is pressed then we move the rectangle to a new random position on the screen. the result is that we can get rid of all the rectangles in one area on the screen by holding the mouse button down and moving the mouse at the same time.
99. Add sounds to your programs
.audiosample.background.close.ddf.draw.dx.dy.ellipse.fill.height.if.import.int.loadsample.minim.minim.new.nostroke.setup.size.smooth.stop.super.this.trigger.void.water.width.
.audio.sound.mp3.wav.effects.
update: the loadsample example program is now called triggerasample.
update: the stop() function is no longer required in minim for processing 2.1.
adding sound to your processing programs is easy. to play sounds we need to use an external library, because by default processing does not play sounds. but it's just a few lines of code.
one important thing we discover in this episode is the examples menu. that's a huge collection of programs that come with processing. there are lots of examples for almost every feature. you can quickly open and run programs that experiment and explain math concepts, arrays, animation, 2d, 3d and much more, including the minim sound library. it's a good idea to browse those examples, run each program and study the source code to understand how it works. it's a good way to learn and find inspiration for your own projects.
100. Sound and random rhythms
.audiosample.ddf.draw.framecount.if.import.int.loadsample.minim.minim.new.random.s1.s2.s3.s4.setup.soundengine.stop.super.this.trigger.void.when.which.
.sound.rhythm.sample.audio.
we are going to use the modulo operation to create rhythms. the idea was explained in episodes 72 and 73. at that time we used graphics to show rhythms, but now we know how to play sounds, so lets try make real rhythms! the program we create is something like a step sequencer. there are 64 steps that repeate over and over. in 4 of those steps we play a drum sound.
after creating a fixed rhythm, we modify the program to sometimes change the step in which sounds are played. we create an unfrequent event. when this event happens, we randomly choose one of the four sounds. the chosen sound will then be played at a new random step.
first we attempt giving a totally new random step (a number between 0 and 63). but that's not the best option when create rhythms. instead of choosing a completely random number, it's better to have less options. we choose one of these numbers instead: 0, 8, 16, 24, 32, 40, 48, 56. we achieve this by writing 8 * int(random(8)). the result is more like a real rhythm.
this episode is a bit longer than usual, maybe a bit dense too, but since it's the last one this year, you will have enough time to digest it :)
ubuntu users: by default you might be limited to playing just one audio sample. i explained how i fixed this issue at https://forum.processing.org/topic/why-can-t-i-play-more-than-one-audiosample
thanks to http://www.freesound.org/people/stomachache/ and http://www.freesound.org/people/junggle/ for the audio samples.
101. Control Processing using a MIDI controller
..
.midi.promidi.controller.
this time we learn no new programming concepts, but find out how to install a midi library in processing to be able to control program parameters using an external hardware device. midi controllers are often used together with music programs to do things like changing volumes or effect amount. but they are a great tool for experimenting with your programs, because they allow you to change numbers without having to restart your program. you just turn a knob or move a slider and see the graphics change.
unfortunately in this episode you won't see anything moving since the library does not work with my setup. but don't worry, in the next episode we will try another approach which works fine.
the basic usage of the promidi library is quite simple. you import the library, declare a variable that will hold your midi connection and use getinstance() to start the midi connection. next you add one or more calls to plug(). this will tell processing that certain functions must be executed every time a midi message arrives. then you have to decide what do you want to do with the numbers you receive: you can move or create objecs, change colors or other properties, etc.
102. Control Processing tilting your phone
.background.draw.float.import.new.osc.oscp5.oscp5.plug.setup.shake.this.void.
.osc.oscp5.control.android.iphone.
this is the second intermediate-level processing tutorial, where we will use a smart-phone to control processing. both your computer and the smart-phone must be connected to the same wireless network.
we use a program called control that allows us to send osc messages to processing. control is totally customizable. you can create your own interfaces in control, which means that you can add buttons, sliders and knobs to the screen of your smart-phone, and use them to control programs on your computer. instead of touch components, we will use a component called accelerometer, which sends messages when we tilt the phone in different directions.
to try this out you need a smart-phone, and you need to install control. after installation you need to configure it, to tell control who is the recipient of the messages. each computer on a network, smart-phones included, has an ip address. an ip address for a computer is like phone numbers for people. you have to find out the ip address of your computer, and enter that as a destination in control. you can use port 10000 in this example. ports are used to avoid mixing messages. imagine you have two phones sending messages to the same computer: each phone can send messages to a different port to be able to distinguish them.
the program you will write in processing needs a library, called oscp5. this library let's processing understand the osc messages your phone will be sending. after installing this library you will write a very short program that changes the color of the background depending on how you tilt your phone.
103. Functions help keep code organized
..
.functions.
when you start writing longer programs they can become difficult to follow. it's important to learn how to keep them easy to understand and easy to modify. there are different techniques for doing that. some of them involve subdividing programs in smaller, easier to manage blocks.
in this episode we take a look at how we can use functions to subdivide programs into smaller parts. a function usually should not have much more than 15 or 20 lines. if it does, then maybe it's time to break it down.
104. OOP means Object Oriented Programming
.aa8f5.background.car.car1.car2.carcolor.carx.cary.class.color.draw.drive.f5470c.fill.float.int.new.rect.setup.size.speed.void.
.oop.class.object.instance.
object oriented programming is a technique that helps us divide programs into smaller parts using something called classes and objects. cars, trees or people can be objects. each object in an instance of a class. the class is like the recipe used to build each object. you use the same class to build different instances of one kind of object.
imagine you want to create cars. to create car a you take the car class and create your first car by using new car(). when you want a second car (car b) you take the same class and create a new instance. you can use different classes to create different kinds of objects. in this episode we only have one class, called car.
each created object (each car) has properties and methods. properties are things like color, amount of doors, brand and model. methods are things the object can do. for example a car can start, stop, change speed and open doors. our simple car can only do one thing: drive().
111. Drive 100 cars: an array of objects
.aa8f5.background.car.carcolor.cars.carx.cary.class.color.draw.drive.fill.float.for.height.if.int.length.new.random.rect.setup.size.speed.void.width.
.oop.array.object.
second episode about oop (object oriented programming), in which we create an array of objects.
in the past we have created arrays of simple types, like int or float, and we have also created two instances of car. here we are going to combine both things: we are going to create instances of car, but instead of making one or two we will create 100, and store all those cars inside one array.
of course these rectangular "cars" don't look very spectacular, but in coming episodes we will create arrays of particles that decide in which direction to go. i hope then you start seeing how you can use arrays of objects.
112. Array of objects: hypnotic animation part I
.background.bug.class.draw.ellipse.fill.float.grow.if.live.maxsz.minsz.new.nostroke.orecuho.random.setup.size.smooth.sz.tsz.tx.ty.void.
.array.objects.
this episode is split in two parts. our goal is to create an array of animated objects. we will create a few hundred pulsating circles.
in the first part of this episode we create two files: a very simple main program, and a class file where we define bug, our animated circle. the size of this circle will increase and decrease regularly. each of our bugs will have six properties: the horizontal and vertical position, the current size, the maximum and minimum size, and the "growth direction": a value that indicates how much the circle grows or shrinks on each frame. if that value is positive, it means the circle is getting bigger. if it's negative, the circle is becoming smaller. if you have a number, and add a negative number to it, the resulting number is always smaller. that's how the circle shrinks. for instance, assume the circle has size 20. if you add -1 to it, you get 19. add -1 again and you get 18. i hope you get the idea.
113. Array of objects: hypnotic animation part II
.background.bug.class.cos.draw.ellipse.fill.float.for.height.int.length.live.map.new.nostroke.orecuho.setup.sin.size.smooth.speed.sz.tspeed.tx.ty.void.width.
.array.objects.circular.motion.polar.coordinates.sin.
this is the continuation of episode 112. we are building a hypnotic animation using an array of objects. our objects are instances of a class called bug. this bug is a simple animated circle.
the first thing we do in this video is to change how the circle grows and shrinks. originally we had properties to keep track of the maximum and minimum allowed sizes for the circle. this technique required 4 properties: the current, maximum and minimum sizes, and the current growth step size, which could be a positive or a negative number. this technique is probably easy to understand, but we can write less code by using the sin() function.
the sin() function returns numbers between -1 and 1 in a cyclical way. that means that it goes from 1 to -1, then back to 1, then again to -1, and so on, forever. so the sin() function is perfect for cases where we want something to move smoothly between two values (two sizes, two positions or two colors).
since sin() returns numbers between -1 and 1, and those values are too small to be used as sizes, we need to map() those small values to larger values more suitable for sizes.
sin() takes one parameter, which i will call t, because in this program it reminds me of time. we need to keep increasing t. the faster t increases, the faster sin() will cycle between -1 and 1. if all the bugs increased t at the same rate, for example, if t increased 0.1 on each frame, all bugs would then animate at the same exact rate. that would be slightly boring. it's more interesting if each bug animates at a different rate. that's why we use a property called speed, which defines the speed of the animation of each bug.
there are many ways we can place the bugs on the screen. we could place them in random positions, we can place them all in the center (which is kind of silly), we can place them in a grid, and we can do what we do in this episode: place them in a spiral that starts at the center of the screen and move away from the center while it rotates around it. to achieve this we use the formula of the circular motion. this formula includes a center, an angle of rotation around the center, and a distance from the center. this is also known as polar coordinate system.
114. How to create movies using Processing
.background.center.draw.fill.float.framecount.framerate.height.if.int.noloop.nostroke.random.rect.rectmode.saveframe.setup.size.sz.void.width.
.ffmpeg.video.youtube.frames.fps.combine.
processing can be used to generate movies. this is usually achieved in two steps: first we write a program that saves hundreds of images to disk. the second step involves combining all those images into a movie. many different programs can be used to combine images into a movie. we use a free command line program called ffmpeg, but feel free to use any other program you find on the internet to achieve this.
in the first 6 minutes of this episode we write a program that creates an animated effect. you can skip this first part and start watching at 06:10 if you just want to find out how to save the images to disk, combine them into a movie and upload it to the internet.
115. Numbers and computers
..
.numbers.dataviz.data visualization.sonification.
computers are full of numbers. all the data and programs they contain are actually numbers. it does not matter if they are images, sounds, videos or something else. those numbers are later interpreted in different ways. for example a sound file is played through the speakers, and an image is displayed on the screen. but since those files are just numbers, you could play an image through the speakers, and you can display a song as colorful pixels on the screen.
the world outside computers is also full of numbers. there are millions of things you can measure, and measurements can be written down as numbers. for example, the amount of letters in your name, the temperature, the time you woke up today, the speed at which you were walking at 11:23...
until now we have made much use of random() and noise(). those functions "create" numbers. but we can also observe existing numbers in your hard drive (inside computer files), or we can create data out of the real world, for example by writing down the time you wake up every day for one month.
when we display numbers coming from the real world as positions, sizes, colors, etc. we are doing data visualization (known as dataviz). humans are not so great at finding meaning in numbers, but we are very good at noticing subtle changes with our eyes. when we convert numbers into shapes and animations we are able to discover new things about those numbers. data can be also be converted to sound, which is called sonification.
116. Reading and displaying bytes, part 1
.byte.data.loadbytes.print.xff.
.loadbytes.data.byte.megabyte.
after using noise() and random() very often, let's take a look at reading data from computer files. we get started by doing some experiments converting bytes into colors. all computer files are full of bytes, so why not take a look at them? maybe we can find differences between the colors given by each file type.
in part 1 we create some files just to show that one letter often occupies one byte, except for special letters which can occupy more bytes. 1 megabyte is 1 million bytes. a typical camera image these days occupies several megabytes, so that's the size of several million letters.
reading bytes from files is very easy, you just need the loadbytes() function. be careful with the file size of the files you load. it's probably good to avoid files larger than 10 mb. if you try loading a large movie file with hundreds of megabytes, your computer may stop responding for a while.
this episode is split in two parts because apparently i just talk too much :)
117. Reading and displaying bytes, part 2
.byte.colormode.data.for.height.hsb.int.length.line.loadbytes.myhue.print.size.stroke.xff.
.loadbytes.data.byte.megabyte.
continuation from part 1. this episode is split in two parts because apparently i just talk too much :)
after loading the bytes from a file, we loop through those bytes displaying them as colorful lines.
later we will work with more meaningful data (data you can generate yourself or download from the internet).
118. Tips (copy paths, optimize, the binary AND operation)
.byte.colormode.data.for.height.hsb.int.line.loadbytes.myhue.print.size.stroke.width.xff.
.optimize.path.binary.and.
in this short episode i make three comments about the program we created on episode 117. nothing extremely important. you can safely skip it if you find it too serious.
1. copying paths. it's easy to copy a path from any file in your computer and paste it inside your processing program. this is only useful when using the java based processing version, not processing.js.
2. optimization. the original program was loading a file into a byte array, and then drawing one line for each byte. this can be very bad for performance if the file is large. for instance, if you load a 2 mb file, it will draw 2 million lines, even the screen can only display a few hundred. for our current program, all the remaining lines would fall outside the screen. if we modify our loop to just cover the visible area the program runs much faster. of course you could write a different program that does draw 2 million lines inside the visible area. i leave that as an exercise.
3. we have not yet studied binary operations, but we used one in the last episode to convert numbers in the range -128, 127 to the range 0, 255. in this episode we shortly compare using "map(number, -128, 127, 0, 255)" to using "number & 0xff".
120. Interactive file visualizer using loadBytes
.byte.colormode.data.draw.filepos.float.for.height.hsb.int.length.line.loadbytes.map.mousex.myhue.setup.size.stroke.void.width.xff.
.loadbytes.visualize.bytes.
here we modify the program that used loadbytes to display the content of a file as colored vertical lines.
the original program just displayed the first six hundred bytes as an static image. now we add interactivity, so by moving the mouse left and right we can explore the content of the complete file.
the required changes are very few. we add setup() and draw() functions to animate the thing, and then we just add a new variable that contains a number. the number is used to avoid always reading from the beginning of the file. this number is an offset. to calculate the number we use map(). we map the horizontal position of the mouse in the screen to the position inside the loaded file.
note: i tried loading different files and found that files with .ico extension produce very interesting patterns :)
121. Using a webcam in Processing
.available.cam.capture.draw.height.if.image.import.new.processing.random.read.setup.size.start.this.video.void.width.
.webcam.video.
by using a webcam processing can see our world :) you can show live video in processing, or capture single images as a photo camera would do.
very few lines of code are needed to show a camera live feed. just try it! :)
122. Programming roses and other flowers
.background.colormode.cos.draw.float.framecount.height.hsb.line.scale.setup.sin.size.stroke.strokeweight.translate.void.width.
.lissajous.rose.math.scale.
in this episode we take a formula found on a wikipedia page, and convert it into a processing program that draws a simple flower. ok, maybe you need some imagination to see the flower, but still.
the only new concept discovered in this episode is the scale() function, which modifies the coordinate system. this allows drawing larger and smaller figures without changing the x and y values used.
scale() can be used in conjuction to translate() and rotate(). all three functions modify the axes in one way or another.
123. Controlling Processing using MidiBus, part 1
.background.channel.controllerchange.draw.ellipse.float.height.if.import.int.line.list.map.midibus.mybus.new.number.println.setup.size.themidibus.this.value.void.width.
.midi.controlchange.midibus.controller.
a midi controller allows us to change values by turning knobs, moving sliders or pressing buttons on a hardware device. this is a great way to explore visual effects without having to modify programs and re-start them multiple times.
in this episode we use the midibus library to receive control change messages from a midi device. each message contains three numbers: the channel, which lets you distinguish between devices when you use more than one device, the number of the knob or slider (you probably want different things to happen depending on which knob or slider you touch), and the value, which indicates how much a knob is rotated, how far a slider is moved, or if a button is up or down.
in part 1 we do a simple program that draws either lines or circles depending on which knob we turn.
124. Controlling Processing using MidiBus, part 2
.background.cc.channel.controllerchange.draw.ellipse.fill.float.framecount.height.import.int.list.map.midibus.mybus.new.number.println.setup.sin.size.sz.themidibus.this.value.void.width.
.midi.controlchange.midibus.controller.
in part 1 we made a program that draws lines or circles when receiving control change midi messages. this first approach has an important limitation: it only draws when it receives messages. if you stop moving your knobs or sliders, it does not draw anything.
imagine you use two knobs to move a circle horizontally and vertically. you probably want your circle to stay visible on the display even if you are not moving your knobs. this means we need a way to be able to read the last value the knob had. the solution is simple: every time we receive a control change message, we store the value in an array. this allows us to read the knob value any time, not just during the instant it is received.
we could use an array of integers to store these values, as the value by default is a number between 0 and 127. but i think most of the time it's more practical to work with numbers between 0 and 1, that's the reason i used a float array. then, every time we receive a message, we map the message value from the range 0..127 to 0..1.
what's the advantage of numbers between 0 and 1? they are very easy to map into other ranges! to map a number between 0 and 1 into numbers between 0 and 400 you just have to multiply the number by 400. no need to use map().
in this episode we write a program that draws a circle. this circle can be controlled using a midi controller (position, size, color and oscillation speed).
if you pay attention, you will note that apparently i can't tell the difference between red and blue :)
125. Simple video player in Processing
.draw.framerate.height.image.import.mov.movie.movieevent.new.path.play.processing.read.setup.size.speed.string.this.video.void.volume.width.
.video.
playing video in processing is now very easy. we just need to import the right library and add a few lines of code. we have different options we can set when playing video: the sound volume, the reproduction speed and we can also choose if to play once or play forever in a loop.
in future episodes we will take a look at what other interesting things we can do with video data.
126. A Processing abstract video player
.background.break.brightness.colormode.cos.draw.ellipse.fill.float.for.framerate.height.hsb.hue.if.import.int.keypressed.loadpixels.mov.movie.movieevent.new.nostroke.path.pixels.play.processing.read.saturation.saveframe.setup.sin.size.speed.string.this.video.void.volume.width.
.video.painting.paint.abstract.
any non random data has a special quality that's missing in random values. such real life data can be photographs, videos or audio recordings.
in this episode we play a video file, but instead of displaying it, we look at the colors in some pixels in each frame. those colors have hue, saturation and brightness values. values can be used for different purposes only limited by our imagination.
what we do in this episode is, for each video frame, start in the middle of the screen, look at the hue, brightness and saturation of the middle pixels, use the color to draw an ellipse, the size of the ellipse defined by the saturation, and then use hue and brightness to decide in which direction to move. for bright colors we take a large step, for dark colors we take a small step. the same way the time changes the direction of the needles in an old clock, we let the hue set the direction of our step. we take up to 100 steps of different lengths and in different directions depending on the video colors, drawing one ellipse on each step. if we reach a border in the display, we stop before getting to 100 steps. this whole process happens very quickly, one series of steps per animation frame. the result looks like a painting that contains little details out of every frame in the movie.
127. Fun with filters part I
.background.blur.draw.ellipse.fill.filter.height.random.setup.size.stroke.textsize.void.width.
.filter.ternary.blur.threshold.invert.gray.posterize.erode.dilate.
filter() is used in processing to transform the currently displayed image. it takes one or two arguments.
the first argument can be a shader or a constant that indicates the kind of filter you want to apply. the available filters are threshold, gray, opaque, invert, posterize, blur, erode, and dilate. shaders are very fast and powerful, but involve learning a new programming language, so we will leave that for later.
the second argument is optional and it is used to adjust some kind of setting on the filter. for example filter(blur, 6) means use the "blur" filter, and the blur should be 6 pixels wide.
filters can be applied in series: first one, then another. they can also be applied multiple times, for example once each time draw() is called. applying threshold, gray or posterize multiple times on the same exact image does not make much sense, as a gray image can not be "grayer". but if something does change in the image then it may make sense to apply again and again.
the amount of available filters is limited, but combining them in creative ways one can obtain interesting images.
check out episodes 89 and 90 if you want to build your own custom filters.
128. Fun with filters part II: animated blobs
.background.blur.char.draw.else.fill.filter.if.int.keypressed.mousepressed.mousex.mousey.random.setup.size.stroke.text.textsize.threshold.void.
.filter.ternary.blur.threshold.
in this second video about filter() we discover an interesting effect we can achieve by applying filter(blur) followed by filter(threshold).
if we do that in a draw() loop we can obtain animated blobs, which are of course essential for architects and nurses.
139. Tweak values while a program runs
.background.center.draw.fill.for.framecount.height.int.noise.nostroke.rect.rectmode.resetmatrix.rotate.setup.size.translate.two_pi.void.
.tweak.variables.interactive.
(jump to 7:19 to see tweak in action)
tweak is a processing mode that allows you to change any numbers in your program while the program runs. without the tweak mode you would have to stop your program, change a value, start your program again and observe the changes. this new mode helps you fine tune your program in real time, while it runs.
the effect of each number in a program is easy to understand when it can be manipulated interactively and the result observed without delay. try writing this program and tweaking each value:
void setup() {} void draw() { ellipse(50, 50, 50, 50); }
try replacing ellipse() with line() and other drawing functions.
note: the setup() function must exist for tweak to work.
140. Recursive graphics
.b5d333.background.cos.ellipse.f683f.fill.float.height.if.lerpcolor.nostroke.nx.ny.random.recursivething.setup.sin.size.sz.two_pi.void.width.
.recursion.recursive.lerpcolor.
using recursion in computer programs allows us to generate beautiful and complex images with simple programs. recursion is simply achieved by writing a function that calls itself one or more times.
to avoid giving a headache to our computer, it's important to set a limit in how many times the function can call itself. otherwise it will attempt to call itself infinite times, and the computer will stop liking you. there are different ways to set a limit. you can use a variable to count the recursion depth, and stop when the depth is enough for you. you could also set a limit by drawing shapes that get smaller and smaller, and then stop when they are small enough.
in this episode, instead of coming up with random colors for the program, i use a color picker called gcolor2 to grab colors from a photo. in windows you can use picpick.org, and in mac "digitalcolor meter", already installed by default.
check episodes 67 and 68 if the sin() / cos() part is confusing.
141. Processing.js with sound / audio (I)
.background.bindjavascript.draw.dx.fill.height.if.int.interface.javascript.javascript.js.nostroke.null.playsound0.playsound1.random.rect.setup.size.void.width.
.pjs.audio.sound.
this episode is special, as it is not about programming concepts in general, but about how to add sound to a processing.js program. you won't miss any important programming concepts if you skip it.
part i.
any libraries you import in the standard version of processing are not available in processing.js, so we need to think of another approach to play sound files.
what we will do is to use javascript to play sounds. javascript is a programming language that runs in the browser. in fact, processing.js programs are automatically converted to javascript, but that's something invisible to us.
so processing.js will take care of the graphics, and javascript will play sounds. we will have two programming languages, and we must find a way to communicate them.
after making sure processing is running in the javascript mode, we can use a menu option to create a custom template. this will create a folder called template inside our sketch folder.
in that folder we will find an html file where we will write our javascript code to play sound. also inside that folder we will drop the unzipped audio library, which we download from http://buzz.jaysalvat.com, and the audio files we want to play. i recommend saving the sounds both in .mp3 and in .ogg format, to make sure it plays in different browsers.
we will edit the file template.html using a text editor. one new line will instruct the web page to load the audio library. other lines will make the sound files ready for use.
before we learn how to communicate processing with javascript, we will create two temporary html buttons to play the sounds, just to make sure things are working.
you have probably noticed that we are doing things a bit different this time. normally all the code of our program is processing code. in this case we have both processing code and javascript code. it's weird, but it works :)
the files from this episode can be found at: https://github.com/hamoid/fun-programming/tree/master/processing/06/e141_pjs_audio
note: in the examples menu of processing there are some processing.js programs that include audio, but they did not work on my computer.
142. Processing.js with sound / audio (II)
..
.pjs.audio.sound.
this episode is special, as it is not about programming concepts in general, but about how to add sound to a processing.js program. you won't miss any important programming concepts if you skip it.
in part ii, we connect processing.js with javascript. by adding some code in our processing program, and in our html template, we are able to call javascript functions from processing. why would we want to do that? since processing.js does not directly play sound, we want to use javascript to play sound. that means that our program must somehow execute javascript code to play sound. by reading part of the pomax guide, we discover how to do that.
in the processing side, we add an "interface", which is a object oriented concept which we may study in the future. for now, you should know that inside the "interface" block we must declare the functions we plan to call in the javascript side. in our example it's just two functions, to play two different sounds.
currently in my chromium browser in ubuntu, the sounds play only once. i noticed i could fix this by calling .load() on the sounds before playing them. i hope this is solved in the future, as calling .load() sounds not very efficient. you can try what happens if you remove the .load() lines.
the files from this episode can be found at: https://github.com/hamoid/fun-programming/tree/master/processing/06/e141_pjs_audio
challenge: make changes to the program so instead of two functions to play two sounds, you use just one function, and send the sound id as an argument. instead of playsound0() and playsound1(), use playsound(0) and playsound(1).
143. Using PGraphics as layers in Processing
.background.begindraw.creategraphics.draw.enddraw.fill.height.image.int.letters.pgraphics.random.rect.setup.size.squares.text.void.width.
.pgraphics.begindraw.enddraw.creategraphics.
by default all the processing drawing functions draw immediately in your main display. what would happen if you wanted to draw something behind other objects? you would probably need something called pgraphics.
so far you have used always one pgraphics, the default one. so you probably did not even think it existed. but you can create more than one, which allows you to draw things on different virtual displays, and later draw those virtual displays on the main one.
one thing you can do with pgraphics is layers. you can draw different kinds of objects on different layers, and then place them in your display in the order you want. for example texts always in front, rectangles behind. or small objects in front and big ones behind. you set the rules.
pgraphics have many uses. one other thing you could do is to create a pgraphics larger than the main display, and then move through it using the mouse or your keyboard, like it happens in online maps or computer games. that would be like having your eyes close to a painting, and moving your head to explore different parts of that painting.
in the next episode we will use an array of pgraphics to create an animated loop drawing program.
how to use pgraphics:
1. you declare a variable using the pgraphics type (not int, not float).
2. you initialize the variable using creategraphics(width, height).
3. you use drawing functions on your variable: mygraphics.begindraw(); mygraphics.ellipse(10,10,10,10); mygraphics.enddraw();
don't forget to add begindraw() and enddraw() before and after your drawing functions, or it won't work.
144. Drawing animated loops
.background.begindraw.creategraphics.currframe.draw.enddraw.for.framecount.frames.height.if.image.int.line.mousepressed.mousex.mousey.new.pg.pgraphics.pmousex.pmousey.setup.size.stroke.strokeweight.void.width.
.loop.animation.draw.
by using an array of pgraphics, in this episode we draw looping flipbooks. the idea is simple: we have a constantly playing animation of 20 frames, and we are able to draw on it. when the mouse is pressed, our ink ends up in the current frame, whichever that is. the resulting effect is quite interesting. once you have the program running, you can learn different drawing tricks, but i leave that to your own imagination :)
here two drawings i created using this technique: http://hamoid.tumblr.com/post/65383946931/a-small-loop-drawing-processing-program-inspired
145. Export animation frames, convert to animgif using gifsicle
.background.begindraw.creategraphics.currframe.draw.enddraw.for.framecount.frames.framestosave.height.if.image.int.key.keypressed.line.mousepressed.mousex.mousey.new.pg.pgraphics.pmousex.pmousey.preparegraphics.saveframe.setup.size.stroke.strokeweight.void.width.
.gifsicle.animgif.animation.saveframe.pgraphics.
in this episode we add two features to the loop drawing program we created on the last one: export the loop as gif images and clear the animation to start with a new drawing. both features are triggered by pressing different keys on the keyboard.
as the animation is a 20 frame loop, it does not really matter when we start saving the frames, as long as we export exactly 20. an easy way to export the right amount of images is by having a variable that indicates how many frames we still want to save. if the variable is 0, it means we don't want to save any images. at some point we press the key 's' in the keyboard, and we change the variable, making it equal to the total number of frames in our loop. in the draw loop we just have to check if the variable is greater than 0. if it is, we save a frame and reduce the variable by 1. at some point the variable will become 0 again and the saving of frames will stop.
once we have exported the frames we can use the command line program 'gifsicle' to pack all frames as a .gif animation, which we can later send by e-mail or upload to the internet. gifsicle is a free program for .gif animation manipulation. with it you can add and remove frames to a gif animation, compress it, change the delays between frames, reduce the colors and much more.
to clear the animation we just create again all the pgraphics when we press a key. probably a more efficient method would be to write a loop that calls clear() on each pgraphics (instead of creating them again). if you want to try improve the program by using clear(), take a look at http://processing.org/reference/clear_.html
146. Let's make errors I (syntax and type)
..
.error.bug.syntax.type.
this is one of those videos where we unfortunately don't do any amazing graphics. but we do something almost as fun: we provoke errors. i hope that by seeing errors happen you can identify them and fix them quickly when they happens to you.
in part i we take a look at errors that happen when you misspell or forget something (syntax errors) and also at errors that happen when using the wrong type (int, float, string, etc).
147. Let's make errors II (nullPointerException, arrays, logic)
.background.boolean.center.color.colormode.draw.ff66.ff6622.fill.fillcolor.float.for.framerate.fxactive.glowcolor.glowingrect.height.hsb.if.int.mousepressed.nostroke.popmatrix.pushmatrix.rect.rectmode.rotate.setup.size.stroke.strokeweight.translate.void.width.
.bug.error.nullpointerexception.infiniteloop.array.
this is one of those videos where we unfortunately don't do any amazing graphics. but we do something almost as fun: we provoke errors. i hope that by seeing errors happen you can identify them and fix them quickly when they happens to you.
in part ii we take a look at nullpointeexceptions, which happen when you try to access a variable that has not been initialized. we also see what happens when you try to access array elements that do not exist, and finally we take a quick look at logic errors: programs with the correct syntax, but unexpected behavior.
this is really a quick overview, as there are lots of things that can go wrong in programs. try to learn from your mistakes! :)
you can read about software bugs (and find out where the word comes from) in wikipedia: https://en.wikipedia.org/wiki/software_bug
148. Drawing shapes with glow or shadow
.background.boolean.center.color.colormode.disablestyle.draw.effecton.ff77.fill.float.for.glowcolor.glowingshape.height.hsb.if.int.loadshape.mousepressed.nofill.nostroke.popmatrix.println.pshape.pushmatrix.rectmode.rotate.setup.shape.shapecolor.shp.size.stroke.strokeweight.translate.void.width.
.glow.shadow.stroke.
by drawing the stroke of a shape multiple times with low opacity we can easily achieve glows and shadows. a simple concept that can produce good looking images. here some examples: http://hamoid.tumblr.com/post/76579918775/84932-jpg-34758-jpg-and-49862-jpg-as-saved-by
tip: the darkness of the shadow or glow should not decrease in a linear fashion (like 8, 6, 4, 2) or it will not look too real. that's why i used distances like 2*2, 3*3, 4*4 and 5*5. i'll try to record an episode in the future about linear vs exponential and other interesting curves. meanwhile here you can find information about curves at: http://www.robertpenner.com/easing/
149. Glowing SVG vector shape
..
.svg.vector.pshape.shape.loadshape.disablestyle.
in processing you can easily load, display and manipulate vector images. some advantages of vector images are: they often occupy little space on the hard drive, the can be enlarged without the result becoming pixelated, and there are tons of vector objects online which you can use in your programs. more about them: https://en.wikipedia.org/wiki/vector_image
in this episode i use inkscape, a free open source program, to draw and edit vector images. i save the file in simple svg format.
to be able to display svg text in processing, it must be converted to curves first.
to be able to set the fill and stroke properties of an svg shape in processing, you need to call shape.disablestyle() first.
you can display an svg file in processing just by writing two lines of code: pshape s = loadshape("heart.svg"); shape(s, 20, 20, s.width, s.height);
note: i made a mistake with the screen resolution when recording this video and part of the image is cropped, but i think nothing important is missing.
150. Webcam light tracking and air drawing
.available.background.brightness.cam.capture.draw.ellipse.ff0000.fill.float.for.framerate.if.image.import.int.length.loadpixels.maxbri.new.pixels.processing.read.setup.size.start.thebrightpixel.this.video.void.width.
.webcam.tracking.drawing.capture.
this episode shows two things you can do with a webcam.
the first one is tracking an object which is easy to distinguish from the background. we use brightness() to search for bright pixels, but you could also use red() to search for very red pixels, or one of the other functions that return color properties.
at home at night this works very well. doing this for an art installation is more tricky, because the location might be very different from your home environment. people can wear crazy colors, the sun spins around continuously changing the light, and lights may be turned on and off. if you want to know more about this field, search for computer vision (cv). there are some libraries out there which can help.
ideas: try to make a simple game which you control with light, use light to increase and decrease a parameter in your program, or use light to give instructions to your program.
the second experiment we do in this episode is using light to draw. it's actually a very simple trick. instead of drawing everything that comes out of the webcam, we just draw the bright stuff, and the rest we ignore. in our experiment we draw white on black. but you could change the colors as time passes, or you could continuously fade the drawing to black, giving you a nice trail effect. a more advanced experiment you could do is to create blinking particles and combine them with the video feed, so you could move a magic wand in front of the webcam and it would leave floating sparks :) so many things to try!
151. Convert an image into a 3D grid of boxes
.background.box.bri.brightness.draw.float.for.get.height.if.img.imgx.imgy.int.key.keypressed.lights.loadimage.loadpixels.map.mousex.mousey.nostroke.p3d.pimage.popmatrix.println.pushmatrix.rotatex.rotatey.save.scale.setup.size.translate.void.width.
.3d.grid.image.box.cube.
this episode is... long! i hope you can stay awake for 18 minutes :)
in this episode i show you how you can create a grid of 3d cubes based on an input image. we use the brightness of each pixel in the image to set the size of each 3d cube in our grid.
scale() is used to scale the scene up. the default is scale(1). if you want to make everything half the size, use scale(0.5). and to double the size use scale(2).
i talk about rotating the camera, but what i meant was rotating our scene. it is indeed possible to rotate the camera, but we don't do that in this episode. to rotate the scene we just include calls to rotatex() and rotatey(), using the mouse coordinates as input. so when we move the mouse, everything spins around. you could use framecount or millis() instead of mousex or mousey, if you wanted to have an automatic rotation.
lights() is used to enable the default 3d lights in processing. nothing fancy, but at least we see something. there are other kinds of lights, you can find them in the reference or in future episodes.
an idea to make the result in this episode more interesting: use not only brightness() but also hue() and saturation(). and map those to different properties of the box. you could for instance specify width, height and depth of the box (instead of making it a perfect cube). or you could move the boxes up in the air depending on brightness, for example. and then rotate depending on hue. and on top of that, translate them again after rotating. that's what i did to generate this image: http://hamoid.tumblr.com/post/108687502754/
ok, in the next episode i'll show you how to export your 3d object as an .obj file, and after that how to load an .obj file into blender to render your object as an image with realistic lights and shadows!
152. Exporting 3D shapes as .obj files in Processing
.background.beginrecord.boolean.box.bri.brightness.draw.endrecord.false.float.for.get.height.if.img.imgx.imgy.import.int.key.keypressed.lights.loadimage.loadpixels.map.mousex.mousey.nervoussystem.nostroke.obj.p3d.pimage.popmatrix.pushmatrix.record.rotatex.rotatey.scale.setup.size.translate.true.void.width.
.obj.export.toxiclibs.hemesh.
this time we are taking the shape we created in episode 151 and exporting it as an .obj file. to achieve that we use the objexport processing library. we also take a look at how to make code run only once even if it's inside the draw loop. that becomes useful to avoid exporting the .obj file over and over again. we only need the file once :)
processing by default offers a limited set of 3d primitives: only spheres and cubes. other shapes you have to load or build yourself out of triangles calling vertex(), which probably means knowing a lot of math. to make it easier to generate and manipulate complex 3d shapes there are several libraries, for instance toxiclibs (http://toxiclibs.org/) and he_mesh (http://hemesh.wblut.com/). in this tutorial i also show where you can find examples for exporting .obj files using both he_mesh and toxiclibs.
in the next episode we will import the .obj file into blender and render an image with realistic lights and shadows!
153. Rendering Processing shapes in Blender
..
.blender.obj.render.
after the two previous episodes, in which we created a 3d shape in proccesing and exported it as .obj file, we are ready to import that shape into blender and render a realistic looking image.
these are the steps we take to get our render ready:
1. import the .obj file into blender
2. clean up the imported model by deleting a huge rectangle that somehow grew in one side. maybe it was caused by using lights() in processing, or some kind of bug.
3. adjust the view. we move and rotate the objects and the camera around to make a composition we are happy with.
4. add a background plane that will receive the shadows of our galaxy object and also reflect sun light.
5. replace the default light with a proper sun, which seems to produce better results. try different lights yourself!
6. add simple materials to the plane and to the galaxy to set colors for them.
7. do some color management. choose the look of the render by simulating different film styles. basically it adjust the color range and tints the whole scene. this can add a nice touch to the result.
8. do test renders and one final render with a higher sample value. increasing the samples improves the quality, reduces noise, and makes it much slower too. find the balance.
9. save and enjoy the rendered image.
if you didn't do so already, i recommend you watch the blender beginner tutorials at:
http://cgcookie.com/blender/cgc-courses/blender-basics-introduction-for-beginners/ :)