Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Saturday, October 26, 2013

Conserving screen space in GNOME



I finally found a tool to accomplish something I have wanted for a long time, namely tuning the size of icons and buttons in Gnome. Gnome applications waste a lot of precious screen space by default, probably the default settings are developed for and by people with six HD monitors at their desks. On a tiny screen such as the 1024x600 screen in my eee-pc, pixels are precious and should not be wasted.

The tool I found is called gnome-color-chooser. Install it with

sudo aptitude install gnome-color-chooser

I should say that I'm using Linux Mint Debian, with the Mate desktop based on Gnome 2. Gnome 3 appears to be configured differently, judging from a quick search.

The color chooser tool allows you to choose the colors of different elements, but it has several settings for button sizes and icon sizes as well. First, let's set all paddings to 0, except the y-padding of widgets which I chose to keep as 1. Check Use shadowless Menubars and Use shadowless Toolbars. On the Icons tab, you can set icon sizes. I set the sizes to 14-12-12-12. I particularly liked the setting Start menu, setting it to 12 pixels made the menu small, nice and manageable.



What the tool actually does is to provide settings in a file included from .gtkrc-2.0.
As the Archlinux Wiki points out, one can also modify the .gtkrc-2.0 file by hand.

Other settings to change for a compact look:
  • System > Preferences > Appearance, Fonts-tab, Details-button. Change Screen resolution from 96 to 80. For some reason, this setting works better than changing the font sizes.
  • System > Preferences > Appearance, Themes-tab. Controls: Clearlooks, Window borders: Mint-X, Icons: Gnome



While at it, fix the file manager preferences:
  • View new folders using: Compact View
  • Compact view defaults, Default zoom level 66%
  • Uncheck All columns have the same width
With the latest update pack for LMDE, many application started to display the following warning when run in a terminal. I frequently launch emacs from a terminal to edit files, then the message clutters up the terminal.

Fontconfig warning: "/etc/fonts/conf.d/53-monospace-lcd-filter.conf", line 10: Having multiple values in <test> isn't supported and may not work as expected

A quick fix to get rid of this annoyance is to comment out line 10 of the offending file:
<!--  <string>Bitstream Vera Sans Mono</string> -->
I figure this might change something, but it looks that the file was broken anyway as it was shipped.

Sunday, October 20, 2013

New disk for an old eee-pc



Our trusty eee-pc 901 was getting slower and slower. The 16G SSD in it was not very fast to begin with, but has definitely become slower over time. To keep the otherwise nice laptop running for a few more years, I decided to upgrade the SSD. The drive I ended up buying a 64G Super Talent FPM64GLSE. RunCore disks have a reputation for being faster, but they were also more expensive and hard to obtain. The eee-pc requires a PCI-E disk. There are also newer mSata disks available. These use a physically similar connector as PCI-E, but are not compatible.



A quick test of the Super Talent with iozone yielded the following results, in KB/s. The same settings were the same as when measuring SD card performance on the raspberry Pi earlier,
./iozone -e -I -a -s 50M -r 4k -r 512k -r 16M -i 0 -i 1 -i 2

                                   random random
reclen write rewrite   read reread   read  write
     4 17258   20110  12626  12623  12528   1457
   512 74590   41339 127710 127909 121887  74354
 16384 40403   75312 129705 129748 130483  40077

As with SD cards, the speeds that the manufacturers specify is the rate of sequential reading or writing of large contiguous blocks (Reading max 150 MB/s, writing max 100 MB/s is what they specify). Randomly writing small blocks of data is a much slower. Still, I am pleased with this result. Also in practice the upgrade had a large effect, the laptop feels much more responsive.

An annoyance with this drive is that it is configured as a slave. When booting the eee, it complains that no master disk is present and demands to press F1. When F1 is pressed, the boot proceeds normally, the unnecessary message just prevents the machine from booting unsupervised.

I installed Linux Mint Debian Edition on the new drive. I had Ubuntu 11.10 before, which started to show its age. I decided not to upgrade it, after experiencing Ubuntu 12.04 on another machine - I felt that the upgrade to 12.04 broke the user interface.

I am happy with Linux Mint. However, I came across a couple of problems during the installation. One that looked serious was that GParted reported errors about a recursive partition on the newly installed disk. I could not get rid of this message but decided to continue the installation anyway, and it turned out fine. To reduce the disk writes and the wear, I added noatime to the mount options for the disk in /etc/fstab.

Thursday, February 14, 2013

Happy Valentine!



We wish you all a happy Valentine's day with origami hearts and an equation.

Let's make a plot in polar coordinates, of \( r = |\phi|^p\). The angle \(\phi\) goes from \(-\pi\) to \(\pi\),  and \(p \approx 1 \). Here is the plot, in processing, with \(\phi = 0 \) pointing up. Move the mouse to change \(p\)!

Mathworld has more equations for hearts, but none of them is as simple as ours. As \(p = 1\) gives a nice shape, \(p\) can be left out for an even simpler equation.



Sunday, December 2, 2012

Favorite Games: Nethack



Nethack A classic. You are an @-shaped hero, and your goal is to explore a dungeon filled with monsters (mostly letters) and treasures (gold $ and gems *) and other objects. I haven't played this one seriously for a while - it is much nicer to play on a full keyboard with a number pad, and I seem to usually sit at a laptop. This is a very addictive game, once you get past the initial steep learning curve. For this post we wanted a couple of screenshots, and once we started playing we got hooked again. We even learned to play without the number pad.

While exploring the dungeon one finds weapons (, armor [, and spell books +, and gets tougher by gaining experience and by learning new skills. Nethack is fun because it is so unpredictable. The ascii graphics is very simple, but the world of Nethack is complex. Monsters can interact with each other and with the world around them. You never know what will happen next, and the text description of the events in the dungeon forms an unpredictable story - sometimes a completely absurd fairy tale.

I grew up playing Nethack on DOS, and liked the way the map is drawn there with full lines for the walls. It is tricky to get this graphic mode to work in a unix terminal, for some reasons connected with different character sets. Anyway, there are several solutions. I installed the program konwert, and ran Nethack in this way on one of the text mode consoles (control+alt+f1):
nethack | konwert cp437-utf8
Then simply enabling IBMgraphics in the in-game options make the graphics look as it was meant to.



Taking screen shots of a text mode terminal is something I have never needed to do before, but it is possible with the snapscreenshot program. I ran it in this way, in a text-mode console, with Nethack running in console 1:
sudo snapscreenshot -f8 -c1 -x1 > screenshot1.tga
In an X-term window snapscreenshot does not work.

The Favorite Game series

Sunday, November 25, 2012

Dancer - a Processing test



A post on bitCraft inspired us to try the Processing language, a simple programming language for drawing interactive graphics and creating generative art. People have made some really fun and amazing stuff. Your program, called a sketch, can then be exported to all kinds of media platforms.

My program is a tweaked version of the program's own Brownian motion example. I added some cursor interaction and some forces, played around with the colors.

Moreover, I learned how to display the resulting processing sketch in blogger from here. Basically, I had to host the web page somewhere else, and then include it with an iframe.

Thursday, November 1, 2012

Raspberry Router



I wanted to set up my Raspberry Pi as a 3G router for my small home network,  and as a file server too. It worked out nicely, so here are some notes and links that helped me.  My internet connection is provided by a USB GSM modem (Huawei E173), so the first task is to get this device running on the Pi. This was surprisingly easy, thanks to the sakis3g script.

I learned that once you start messing with the network, downloading new stuff gets tricky - so it's best to get everything at once.
sudo apt-get install ppp isc-dhcp-server usb-modeswitch 
and download sakis3g
wget "http://www.sakis3g.org/versions/latest/armv4t/sakis3g.gz"

EDIT: The Sakis3G web page is down at the moment, but a local copy of the script is here: sakis3g.gz (version 0.2.0.e).

The Pi can probably not supply enough current for the 3G modem through the USB ports (thanks for the tip), so I connected the modem through a powered hub. Without the hub, the modem did not work.



The sakis script was easy to use, it asked me to select my modem and then the network name (APN). When the connection works, one can write the selections in a configuration file to avoid having to enter them again. In sakis: "More options..." -> "Generate success report" shows a lot of info. Last in the list, there are the options needed to connect. Copy these (except  --console and --interactive) to the file /etc/sakis3g.conf with one option per line. Sakis does not like any extra whitespace on these lines. Now it should be possible to connect with  a simple sudo sakis3g connect.

I found a nice guide to setting up the pi as a router. This worked well for me, I just had to change which network interface is connected to the local network (eth0 for me) and which is connected to the outside (ppp0).






A small complication has turned up with the GSM modem. The modem is a multimode USB device, and must be switched into the correct mode before actually working as a modem. Sakis handles this automatically (using the usbmodeswitch program I installed above). The trouble is, that when the modem is switched, it changes its USB device ID. So the device option to pass to sakis is different the first time and any later time sakis is run without unplugging or powering down the modem in between.
The broadband company seems to drop the connection after 24 h. I think I will put a cron script for reconnecting at 5 in the morning or so. I came up with the following command for finding the current USB ID of  the modem and passing it to sakis.
sudo sakis3g connect USBMODEM=\
`lsusb | grep Huawei | sed 's/.*ID \([a-f0-9:]*\) Huawei.*/\1/'`
sed is a strange creature! grep finds the relevant line, and the sed command extracts the ID number between 'ID ' and ' Huawei'. This is of course assuming that exactly one huawei device is present.

I post some of the configuration files here. In this later post, I added a WLAN stick and got the Pi set up as a WLAN access point, these files are for a WLAN device as well. If you don't have one, just ignore those sections.
my /etc/networks/interfaces:

auto lo
iface lo inet loopback

auto eth0 #static address on eth0
iface eth0 inet static
address 192.168.50.1
netmask 255.255.255.0
network 192.168.50.0
broadcast 192.168.50.255
gateway 192.168.50.1

auto wlan0 #static address on wlan0
iface wlan0 inet static
address 10.10.0.1
netmask 255.255.255.0

And then /etc/dhcp/dhcpd.conf

ddns-update-style none;
default-lease-time 600;
max-lease-time 7200;
log-facility local7;

#for the eth0 subnet
subnet 192.168.50.0 netmask 255.255.255.0 {
range 192.168.50.10 192.168.50.250;
option broadcast-address 192.168.50.255;
option routers 192.168.50.1;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local";
option domain-name-servers 8.8.8.8, 8.8.4.4; #Google DNS
interface eth0;
}

#for the wireless network on wlan0
subnet 10.10.0.0 netmask 255.255.255.0 {
        range 10.10.0.25 10.10.0.50;
        option domain-name-servers 8.8.8.8, 8.8.4.4;
        option routers 10.10.0.1;
        interface wlan0;
}

Wednesday, August 29, 2012

SD card benchmark on the Raspberry Pi

This thread in the Raspberry forum and this post discuss benchmarks of different SD cards for use with the Raspberry Pi. I wanted to test my own card, and to do it in the Pi itself. An important conclusion of the two discussions is that the speed of small random writes is important for running an operating system of the card. What the card manufacturers report is the sequential read and write speed which can be substantially higher - these are important in cameras for example.

The posts suggest the program iozone for measuring the SD card performance. I could not find it as a raspbian package, but it was easy to compile from source. Very quick instructions follow.

wget http://www.iozone.org/src/current/iozone3_408.tar
cat iozone3_408.tar | tar -x
cd iozone3_408/src/current
make linux-arm
./iozone -e -I -a -s 50M -r 4k -r 512k -r 16M -i 0 -i 1 -i 2

The final command runs the test. This command line was suggested in the raspberry forum, for the options run iozone -h . Note that iozone tests the device where the current directory is located. The flags -e and -I are significant here. -e include fflush and sync in the timing, while -I requests the use of direct I/O, without any caching.

For my SanDisk 8G class 4 card (8 €, Media Markt) I got the following results. See here for a picture of the card and packaging.
                                          random  random   
reclen   write rewrite     read   reread    read   write
     4     913     991     3279     3278    3061     457
   512    5292    5370    11305    11304   11218    1319
 16384    5122    5442    11442    11442   11442    5406

The column reclen gives the size of the data blocks tested, while the other columns are speeds in KB/s. For this card, the important figure for small block random write is quite respectable but not as high as what other people in the threads above have reported for the best cards. Anyway, SanDisk cards of class 4 or 6 seem to top the list.

But benchmarking a SD card seems to be a more complicated topic than running the short test above. In practice using RAM for cache gives a huge performance boost, in particular for small writes. My guess is that whether the small random writes will be a bottleneck or not is very much dependent on the application.

I ran two further tests with iozone, using the flag -a (for automatic): once without cache enabled (-e -I) and once with cache. In the -a mode, iozone runs tests for many different file sizes and block sizes. Each test ran for over an hour before I interrupted it. This made me wonder if this amount of writing will wear out the SD card. So far I have seen no problems.

As long as the data written fits in the RAM, cache gives a huge improvement. At a file size of 64 Mb there is a significant speed drop when the cache becomes too small.   

Friday, August 17, 2012

Trying out the Raspberry Pi

I am a happy owner of a Raspberry Pi - a tiny (and really cheap) computer, capable of running Linux. Now I too am a part of the Raspberry revolution. I am just starting to try it out, but I already got our platform game running on it! More on the game will follow in a later post, first some notes on the Pi itself.

I decided to try out the Raspbian flavor of Linux on the Pi. I chose this for the hardware floating point support, and since the Raspberry Pi foundation recommends it.

I currently don't have an USB keyboard, so I hoped to access the Pi over the network with ssh. Luckily, Raspbian is set up with an ssh server running. The only things required is to make sure that the Pi gets an IP address when it boots, and then find out which IP it got so that you can ssh to it.

I connected the Pi to a laptop running ubuntu, and tried to use the network manager on the laptop to give the Pi an IP address with DHCP when it boots. Sadly, this did not succeed. Apparently the laptop Ethernet interface stays "down" as long as nothing is connected to it (the Pi is off), and the Pi got no IP address when it booted.
Fortunately it was easy setting up a DHCP server on the laptop manually:
1) Turn the network manager off, so it does not get in the way
2) sudo ifconfig eth0 192.168.0.2 #enable eth0, give it an IP address
3) sudo udhcpd -f
4) boot the Pi, wait a while.
5) udhcpd prints out the IP address it offers
6) ssh to the address. User name pi, password raspberry.



If you have the Pi connected to a TV or monitor, you will see the Pi printing some messages while it boots, and then launch the raspi-config program.  Without a keyboard raspi-config is not usable, but you can still access the Pi with ssh. Raspi-config seems to start automatically at each boot, until you have completed it once.  It can be run from a terminal at any time.  If one wants the Pi connected to the internet, some more networking is needed than what I describe above. A router would probably be the most convenient solution. I have had success with Windows "internet connection sharing".

EDIT: When trying to share an internet connection from an Ubuntu laptop to the Pi, this bug bit me. After the suggested work-around, sudo killall dnsmasq on the laptop, I could boot the Pi and it got an IP address. Then the next problem appears: how to find the IP address of the Pi? The Pi prints it on the TV or screen during boot. If no screen is connected one can use the nmap tool:
nmap -sP 10.42.0.1-254
this IP range being the one that Network Manager seems to offer. -sP tells nmap to ping all the hosts in the given range.

I have a PAL TV connected to the Pi. PAL needs a setting in the configuration file config.txt, located on the boot partition (the small, FAT one) on the SD card. Either edit this file on the card and uncomment the line
sdtv_mode=2
or use raspi-config on the Pi.



In this discussion and here I found interesting observations about which SD cards work well with the Pi. Apparently the fancy and expensive cards, called Class 10, are not the best since they are highly optimized for sequential reads and writes. This is good for photography but not for running Linux of the card. For this application, the speed of short random reads and writes is much more important, and these speeds may well be much better on cheaper cards of lower class. I got an 8 Gb Class 4 Sandisk SDHC card from the local Media Markt for 8 €. It seems to work well, but I have no serious benchmarks yet.

Sunday, July 15, 2012

Platform game, level 4



After many months, we finally have a new version of the platform game! As always, it comes with a new level.

Download the game here: for Windows, Linux(32) and Linux(64). See these instructions for installing it on different platforms.

Wednesday, March 14, 2012

Compiling zziplib with MinGW

In our platform game, we use the zziplib-library to access game data files from within a zip archive. On a Linux system zziplib is easy to install via the package management system, but on Windows it is more challenging. I could not find the library precompiled, so I compiled it myself with MinGW. Here is a list of the necessary steps and tweaks. In addition to MinGW, msys is needed (to run the configure script). Python is needed during the compilation, apparently when formatting the documentation. Either one has to disable  the documentation step (but I don't know how) or have a Python interpreter in the PATH. Since I have the great drawing program Inkscape installed and it ships with Python, I just added that python interpreter, C:\Progra~1\Inkscape\python to the system path. Note that spaces in the path lead to problems, for that reason I used the name C:\Progra~1\...

Get zlib. The header files, lib files and the dll are needed. Download both "Binaries" and "Developer files". Put them where they will be found during the compilation, I chose C:\mingw\include for the header files and C:\mingw\lib\ for the lib files. The file zlib1.dll should be in the same directory as the application.

Download the latest version of zziplib. Extract it somewhere, make sure there are NO SPACES in the path. Turn off any anti-virus software for the duration of the compilation process. At least f-secure often pretends to find viruses in files compiled with gcc. Also, any antivirus program may interfere with the configure scrips in the following steps, if it opens a file which the script creates and then quickly wants to remove.

cd to the zziplib directory. Edit the file configure. Replace uname -msr by uname -ms in two places. This is necessary, since uname -msr returns a string containing brackets. This string is used as a directory name, and for that brackets are not allowed. (This tip is from here, on the MinGW mailing list.)

Run sh configure --disable-mmap --prefix=C:/mingw/ . Without --disable-mmap the library compiles fine, but causes a segfault in some mmap function when accessing a zip file. --prefix describes where the header files and libraries should be installed. Then run make and make install.

Wednesday, February 29, 2012

Game programming notes

I have learned a bit about game programming by writing a platform game. Today's post is about the libraries and tools and resources that have been useful in this process.

Graphics
Much of the hard low-level work in the game is done by the SDL library.  This library handles drawing graphics and playing sounds in a simple way. Best of all, the library is available for Linux and Windows and several other platforms as well, which makes it simple to write a portable game. I learned how to use SDL from the official documentation and by reading Lazy Foo's tutorials. In addition to the SDL library, we use the following additional modules:
SDL_gfx   for drawing primitives and frame-rate control
SDL image  for loading images in various formats (png)
SDL mixer  for playing sound clips and loading ogg files

Sound
Most of the sounds in the game were generated with the small program sfxr by DrPetter. The program generates sounds with a nice 8-bit feeling. One can tune the sound by changing a set of parameters, like the frequency and wave form. One can also control the sound envelope with attack, decay, sustain, release like on the good old Commodore 64. Sfxr produces wav files.  I packed these in the ogg format. In the game code, it is then simple to play the ogg files at appropriate times with the SDL_mixer library.

Data files
I want to minimize the number of files that have to be distributed with the game. Unfortunately the libraries used require a number of dll files (on Windows). But at least one can pack all the game data in a single archive file. So far I have used the zziplib-library to access game files that are packed in a zip file. See also this post for some details on how to get zziplib to work well with SDL. Compiling zziplib on Windows was not trivial, but this I save for another post.

One could also try to pack the game data in the game executable file. Here is a hackish method to create a file that is both the game executable and a valid zip archive, which can be read with zziplib. Another way is to simply compile the data into the exe file. I found that the Linux command-line tool xxd can format a data file as c array (use the flag -i).

Future
An installer system for Windows would be nice. The Nullsoft installer seems promising. Another lighter alternative would be some self-extracting archive.

Friday, February 3, 2012

Platform game 0.03 - new release!

Today's release of the platform game adds life to the game world. The controls are simple: move left or right with the arrow keys, and jump with CTRL. The game for Windows, 32 bit Linux and 64 bit Linux. The installation procedure is the same as in the previous version. 

Windows: Download the zip file and extract the folder game003, for example to the desktop. Double-click the file game.exe to run the game. Linux: Download, extract and run. You will need to have the libraries listed in the first game post installed for the game to work.

Sunday, January 29, 2012

Game data in a zip file

For our platform game, we wanted to minimize the number of files needed to play the game. The best would be to distribute just a single exe file, but getting all SDL libraries statically linked seems to be a challenge. This post is about the game data files (sprites, sounds and level data), and how to make the game access them directly from within a zip file.

Our current approach uses zziplib and SDL RWops. Zziplib makes it easy for the program to access files inside a zip archive. As a bonus, the library looks for the file outside the archive first, so one can keep the game data as separate, regular files while programming and testing. For distributing the game, one simply packs the data files in a zip archive, the program will still find them. SDL RWops is a mechanism for passing data to SDL functions, when loading images or sound clips. The data may be stored in memory, in a file or in some other way.

The zziplib homepage gives an example program for getting a RWops structure from zziplib. I made a few modifications to it, which I want to share here. The code is not yet pretty, it is at the works-for-me stage.  In particular, the mode argument is handled sloppily. The original example file was released under the zlib license, so the same applies for my modified versions.
SDL_rwops_zzip.c  SDL_rwops_zzip.h

First, mingw does not like the names _zzip_read() and _zzip_write(), it reports a name conflict. I guess this is a mingw problem, but it is easy to get around by changing the names, which are used only locally in this file.
SDL_rwops_zzip.c:23:12: error: conflicting types for 'read'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/../../../../include/io.h:452:37: note: previous declaration of 'read' was here

Second, zziplib supports obfuscating the zip archive, which makes it slightly harder to see the files inside it. It would be nice to use this feature together with the RWops. In the c file below, I have simply combined the obfuscation example from the zzlib site with the RWops functionality. A nice feature: obfuscation is applied only on files found in a file with the extension .dat, unpacked files and files in a .zip archive are assumed not to be obfuscated. I also added the function openZzipFile(), which opens a file with the same obfuscation mechanism but does not turn it into a RWops structure.

Saturday, January 14, 2012

Platform game, release 0.02

Now it is time for a new version of the platform game! This time it is possible to win the game and also to die, so now there is a clear goal for you. As before, comments and bug reports are welcome.

The game for Windows. Download the zip file and extract the folder. Double-click the file game.exe to run the game.

The Game for Linux 32 bit, and The Game for Linux 64 bit. Download one of the zip files above, according to your operating system (typically 32 bits for older computers). Extract the folder game002, and run the file game. You will need to have the libraries listed in the previous post installed for the game to work.

The same small print as before: The game, program and artwork are copyright 2012 by Johanna and Fredrik.

Monday, January 9, 2012

Antivirus Anger

We planned to release a new version of the platform game last weekend, but unforeseen technical problems appeared. Compiling the game for Windows turned out to be difficult. We program the game in c, using Linux. Thanks to the SDL library and MinGW, a Windows port of the GNU c compiler, the game should be easily portable to Windows as well.

The first problem was F-secure's antivirus program. When I compiled our game, it immediately recognized the game's executable file as a virus and removed it (for our protection). It turned out that not just our game got treated this way, but even the smallest possible c-program with an empty main function was detected as malware as soon as I compiled it. I am using the current MinGW, with gcc 4.6.2.

My various test programs were classed as Gen:Variant.Graftor.11442, Gen:Variant.Graftor.11230, Gen:Variant.Graftor.10418, Trojan.Generic.KDV.492012, Gen:Variant.Kazy.50358. Of course we could turn off the stupid antivirus scanner, but then the problem would probably just move to whoever tries our game and has the same antivirus system installed. Switching to an older gcc (version 3.4.5 which I had lying around) made the problem go away. Also, the most recent version of the game seems to avoid the virus scanner, for no apparent reason.

EDIT 21.1.2012
I was going to report the problem today on the MinGW-users mailing list, only to discover that an empty program is no longer classed as a virus. Maybe f-secure updated their scanning system?

Tuesday, December 27, 2011

Platform game



Today we proudly release the first version of our computer game!

The Game for Windows. Download the zip file. Extract the folder anywhere. Double-click the file game001.exe to run the game.

The Game for Linux 32 bit, and The Game for Linux 64 bit. Download one of the files above, according to your operating system (typically 32 bits for older computers). Save the file anywhere. Additionally, you need to install some libraries. For Ubuntu, run this command in a terminal:
sudo apt-get install libsdl1.2debian libsdl-mixer1.2 libsdl-image1.2 libsdl-gfx1.2-dev libzzip-0-13

Any comments and ideas are welcome. Please report any problems or bugs!

Small print: The game, program and artwork are copyright 2011 by Johanna and Fredrik. No Warranty is given! Please do not distribute.

Saturday, October 22, 2011

Circles and Python

Project Euler is a collection of computer programming problems. I have solved some of them in python, in order to learn the language. For one of the problems, I wanted to see what my program was doing, so I made it draw this picture:

The problem concerns circle packing: three circles are placed so that they all touch each other. Now place a fourth circle in the gap, touching the other three. Now there are three smaller gaps. Continue filling the gaps with circles.

I drew the circles with the matplotlib plotting library. Matplotlib is rapidly becoming my favorite plotting tool, replacing gnuplot.
Older
Related Posts Plugin for WordPress, Blogger...