Introduction
I’m lucky to know lots of very creative and thoughtful people here at Element14, and in my everyday work and play. I spend as much time with them as possible because I learn so much.
If I throw out a problem at people I’ll inevitably get back some possible solutions, and I then use some engineering experience to convert it into a physical project. Engineers love to problem-solve, and they love to create things. If you’re lucky enough to be able to come up with good ideas and want to take things to the next level, with a bit of practice you can build your own prototypes and projects. It is an invaluable skill because otherwise hiring an engineer to turn your ideas into even just a prototype is a $100k endeavour.
Time is short, and it is sometimes quicker to understand how to do something by seeing it rather than learning it from first principles. It is also good to have an aim or an assigned task.
The (arbitrary) task for this blog post will be to get the Pi to draw a Christmas tree, with zero programming experience. Drawing this is sufficiently non-trivial, yet is still close enough to a ‘Hello World’ project for beginners. For this project, some graph paper may be handy to sketch/visualize shapes and co-ordinates. No programming experience is needed.
Getting Ready
This project involves graphics and the Pi needs a ‘graphics library’ or engine to be installed. To do this, open a Terminal window by going into the menu on the Pi and clicking on Accessories -> Terminal
Next, type the following in that window:
sudo apt-get install libg2-dev
You may be prompted for your password. Some messages will appear, and eventually you should see it successfully complete. The graphics library is installed!
Stick Man
The code below implements a stick man and a pile of boxes (Christmas presents). It can be run in four easy steps.
- Transfer the code below into a file and save it on the Pi in your home folder. There are a couple of ways to do this:
- One way is to copy-and-paste (tip: To copy the code from this website, it is best to click on View Plain and then in the new window that opens, right-click and choose Select All and then right-click again and choose Copy).
- The other way (easier) is to get the Pi to retrieve the code automatically. To do that, open a Terminal window as before (by going into the menu on the Pi and clicking on Accessories -> Terminal) and then type in the window:
wget -q https://github.com/shabaz123/stick-man-and-xmas/raw/master/stick.c
- Open a Terminal window as before if you don't have one currently open.
- Type the following inside the window:
gcc stick.c -lg2 -o stick
- If you get no error message then you’re ready to run the program. To run it, type this:
./stick
Code for Stick Man (Click on View Plain):
/**************************** * Stick Man * * rev 1 June 2017 ****************************/ // include #include <stdio.h> #include <g2.h> #include <g2_X11.h> // defines #define width 200 #define height 300 /**************************** * main program ****************************/ int main(void) { int id; int i; id=g2_open_X11(width, height); g2_circle(id, 50, 80, 20); g2_line(id, 50, 60, 50, 20); g2_line(id, 30, 40, 50, 50); g2_line(id, 50, 50, 70, 40); g2_line(id, 40, 0, 50, 20); g2_line(id, 50, 20, 60, 0); for (i=0; i<5; i++) { g2_rectangle(id, 100+(i*5), i*25, 180-(i*5), (i+1)*25-1); } getchar(); // wait for user to press a button g2_close(id); // clean up return(0); // exit }
The screenshot here shows the result of the steps.
To exit out of this program, click in the terminal window so that it has focus, and then press Enter.
Stick Man Deciphered
Without knowing much or anything about programming, it is still possible to examine the software for the Stick Man. The first few lines look like a title or comments or a header. The next three lines (lines 9-11) may not make much sense but we know that the graphics engine was called libg2-dev so some of it looks related to that, and we can assume it is setting up or incorporating the engine.
The define lines (15-16) looks a bit like algebra, where letters or in this case words like width and height are representing numbers.
Continuing further down and ignoring anything that doesn’t entirely make sense yet, it can be seen that there are a lot of lines (from line 32 onwards) containing the text g2, and this is likely graphics engine related. Looking more closely, there are lines that say g2_circle and g2_line so they are probably used to draw the stick man’s head and remainder. The numbers look like xy co-ordinates and knowing that a circular head is higher than the rest of the body, it is plain that the xy co-ordinates have an origin (i.e. 0,0 point) at the lower-left of the image. There are five rows (lines 33-37) containing the text g2_line so they must correspond to the body, two arms and two legs.
There is a g2_rectangle command further down in the code (line 42), and the boxes in the stick man photo are of this shape. There are five stacked boxes in the photo but only one g2_rectangle command in the code. Therefore, the curly braces/brackets near there and the line with the text ‘for’ (line 40) must implement some sort of looping instruction to the computer.
For the last few lines of code there is a sentence on each line that explains what it does, and this means the code there is easy to understand at a high level.
In summary, the entire code was deciphered without needing to know more than a small bit of English and a tiny bit of math!
If you need a bit of help visualizing the co-ordinates and do not have a piece of graph paper handy to sketch it, see further below for a diagram with co-ordinates overlaid on it.
Building the Christmas Tree
The code above could be modified to create a tree. It could be sketched on graph paper first if desired, to get a sense of what xy co-ordinate values to use.
In some ways, the tree could be similar to the pile of boxes. If each box was replaced with some pointed lines or shape then it is close to an Xmas tree representation. It could be refined further by drawing some decorations.
I decided to draw the tree next to the boxes, so that I did not have to delete any code. This entailed making the window bigger, I expanded it from the previous 200x300 value to twice the width (400x300) and then I instructed the computer to place the tree centred at the X co-ordinate of 300, by drawing the tree pot as a rectangle with opposite corner co-ordinates of (280,0) and (320,20). The tree trunk was 10 units thick, so that was a rectangle with co-ordinates of (295,20) and (305,40).
The rest of the tree was drawn as six iterations of a flat horizontal line and two shorter angled lines to create the pointy bits.
The entire code is shown here. To use it, either copy-and-paste it into a file called xmas.c or (easier) get the Pi to retrieve it automatically into a file using this command:
wget -q https://github.com/shabaz123/stick-man-and-xmas/raw/master/xmas.c
and then type:
gcc xmas.c -lg2 -o xmas
followed by
./xmas
Code for the Xmas Tree:
/**************************** * Xmas Tree * * rev 1 June 2017 ****************************/ // include #include <stdio.h> #include <g2.h> #include <g2_X11.h> // defines #define width 400 #define height 300 /**************************** * main program ****************************/ int main(void) { int id; int i; id=g2_open_X11(width, height); g2_circle(id, 50, 80, 20); g2_line(id, 50, 60, 50, 20); g2_line(id, 30, 40, 50, 50); g2_line(id, 50, 50, 70, 40); g2_line(id, 40, 0, 50, 20); g2_line(id, 50, 20, 60, 0); for (i=0; i<5; i++) { g2_rectangle(id, 100+(i*5), i*25, 180-(i*5), (i+1)*25-1); } // draw the tree g2_rectangle(id, 280, 0, 320, 20); g2_rectangle(id, 295, 20, 305, 40); for (i=0; i<6; i++) { g2_line(id, 220+(i*10), 40+(i*15), 380-(i*10), 40+(i*15)); g2_line(id, 220+(i*10), 40+(i*15), 220+(i*10)+30, 40+(i*15)+15); g2_line(id, 380-(i*10), 40+(i*15), 380-(i*10)-30, 40+(i*15)+15); } getchar(); g2_close(id); return(0); }
Incidentally, if you're curious, do you know how to find out what the differences are between the code stick.c and xmas.c? Well, the computer can show you. Type the following at the command prompt:
diff stick.c xmas.c
For reference, here is a diagram showing some of the co-ordinate values that were used:
Summary
This blog post showed how to modify existing code to create a custom solution. Although it seems basic, the exercise has demonstrated how to write and run code, and how to inspect it and decipher it. Another useful thing that the code showed was how to get the computer to repeat things that are similar but subtly different many times using an algebra-like letter ‘i’ that changed value on each loop, to produce useful results with little code.
It would be great to see other people’s ideas for Xmas trees or decorations for it. The code so far can be run on any computer but in the next blog post, it will be interesting to take the best decorations (or I’ll create some), and animate them, and then use the code to animate a physical electronic model of a tree too, wired up to the Pi. It will require any model of Pi. This will demonstrate how to control real hardware with such a device, instead of virtual Xmas decorations on the screen. In terms of the bigger picture, this will allow projects and designs to have smarter controls and functions using your own custom software!
Top Comments