art with code


Holographic video

NHK is developing a holographic TV that doesn't require viewing glasses (via Reddit.)

The premise is simple: put a transparent surface between the viewer and the object. All the viewer sees is the photons coming from the transparent surface. Now sustain the photon emission from the transparent surface as-is and remove the object. To the viewer it looks like nothing has changed. The object seems to be still visible through the surface and you can walk around and look at it from different angles. A hologram! (When I understood the idea, I got a stupid goofy grin and walked around the house going all "WOOHOO! HOLOGRAMS! YEAH!")

Implementation then. The camera lens could be a large sheet of viewing-angle-optimized hemispherical pixels with an RGB light detector for each direction. The viewing device would swap the detectors for emitters. It'd require a huge lens (the size of the display, really) and require multiple times the megapixels of the usual one-directional image (as now each pixel is in fact several pixels, each facing a different direction.)

Except that they're not doing it quite like that. I don't fully understand it, but I think they're using an 2D array of lenses to get a flat projection and then record the resulting 2D image in the usual manner (project to a small CCD/CMOS/whatever). The display is a regular ultra-high-resolution flat panel with a similar array of lenses in front of it. Here's a good presentation slide deck: 3D-TV System Based on Spatial Imaging Method for Future.


Loading .tar.gz with JavaScript

With the power of copy-pasting code from the INTERNET, I have now created a JavaScript library that streams gzip files and specifically .tar.gz files.

DEFLATE and CRC32 implementations found with Google and tweaked and bolted onto the tar parser. The performance is something between 1-5 MB/s on Chrome, third of that on Minefield.

In action: Demo page
Just the library: gzip.js


Numbers, numbers

A Finnish copyright survey tells us that copyright infringement costs the Finnish recording industry more than 355 million euros every year. The yearly sales of the Finnish recording industry are around 100 million euros. If 30% of that is profit — 30% being the profit margin for software companies — they spend 70 million to make the records, get 100 million back in sales and pocket a cool 30 million in profit.

Now, as a result of the copyright infringement costs, the costs of the Finnish recording industry are actually 70 + 355 = 425 million euros. They spend 425 million euros, get 100 million back in sales and end up 325 million in the red. I will expect the whole industry to go bankrupt in three months, if not faster. Every euro they spend is costing them five.


Slideshow-qgl, now with new features

Slideshow-qgl — my tiny slideshow app — now has recursive dir traversal, a fullscreen mode and a slideshow mode. Which makes it more useful than.. most slideshow apps out there. GQview and EOG, I'm looking at you. With a stern eye. And a hint of rebuke.

As you might guess from the name, slideshow-qgl is based on Qt4 and OpenGL. Qt4 makes it relatively easy to write and OpenGL makes it fast to pan & zoom & fade between images.

It follows the mplayer approach to GUI design, specifically "widgets are ugly, get rid of them." This is what it looks like with an image loaded and zoomed in a bit:



Parsing tarballs with JavaScript

Update: Check out this augmented version that streams gzipped tarballs.

Here's a small piece of JavaScript to parse tarballs and my custom JSON packfiles. There be four demos as well: loading files from a tar, streaming images from a tar, loading files from a JSON packfile and streaming files from a JSON packfile.

The part that converts images to date URLs is a bit slower than it could be, as it has to strip high bytes off the characters. The upcoming JS File and Blob APIs for binary data handling should help there. Though if you have less than a hundred kB of images, I don't think you'll even notice the delay. Even half a meg of stuff unpacks in a fraction of second on my slow laptop (Pentium M 1.7GHz). If you do need speed, you can convert the images to data URIs beforehand.

Quickly estimating, it'd take something like fifteen seconds to load up a hundred megs of models and textures on my laptop, maybe around 5 s on a decent computer. Doing the initial archive parsing pass would take maybe a second for a hundred meg archive. If that's too slow for you, I want your internet connection. If the hundred meg tarball is split 1:4 geometry:textures, where the geometry takes 20 bytes per tri and the textures are 10x compressed JPEGs, it'd have 1 Mtri geometry and 240 Mpx textures.

The script doesn't handle gzip or any other compression, use gzip-encoding on the server for that. The tar file format is pretty simple: it's based on 512-byte blocks and each file begins with a 512-byte header, followed by the file data padded up to a multiple of 512 bytes. The numbers are represented as octal ASCII (though there is a GNU tar extension that uses binary ints for handling files bigger than 8 GB, which my script doesn't support).

My JSON packfile format consists of a one-line JSON header array of {filename : string, offset : bytes, length : bytes} followed by a newline and the concatenated file contents. Easy to create and parse.

Edit: Added streaming using xhr.readyState == 3 checks. It might cause some stuttering on the page when dataURLing the images, though it should be quite efficient otherwise. Optimizations welcome :)


Vanishing hardware

... Apparently the ethernet chip on my desktop computer motherboard completely disintegrated and now it doesn't even show up on lspci. All I know is that it disappeared after waking up from Windows 7 sleep mode.

Oh well, another excuse to upgrade.

Edit: after putting Windows to sleep again and waking it up, it seems that it momentarily lost and then regained the SMBus controller as well (not the ethernet controller however), in the process deactivating Windows. How very Windows of it. A pox on it! A pox on it and its descendants to the seventh generation!

Energy use by economic output

Energy use in kWh per GDP per capita. Country data from NationMaster, plotted with R. The green line is the LOESS regression curve. The blue lines are averages for top and bottom 100 countries (after removing the best and worst 10 countries), the pink lines are averages for countries ranked 11-20 from top and bottom.

Roughly speaking, the general trend is five bucks GDP for every kWh of energy use. The least efficient countries get 2 $/kWh and the most efficient 25 $/kWh.

Assuming that energy use follows economic growth and that the average annual global economic growth is 3%, we can extrapolate (hah) that the global energy use would equal the total output of the Sun at around the year 3125. Put that in your pipe and smoke it.


A chain of trivia

Chemical makeup of the human body - Elements by mass 65% O, 18% C, 10% H, 3% N, 4% others. You're three times as oxygen-rich as the air you breathe. 98.7% of the molecules in your cells are water molecules (but only 65% of mass, water molecules are light). There are around 174 teramolecules of water per cell. Your DNA chromosomes are huge giant molecules about 5 billion times more massive than water molecules.

R-generated graphs of the first fifteen elements in the human body by mass and count. Hey, power law distributions!

Elements in Animals and Humans - what are the other elements used for? Deficiency in Magnesium causes tetany, muscle spasms.

Clostridium tetani - the Tetanus is an anaerobic soil bacteria that seems to produce one of the most deadly neurotoxins for no good reason whatsoever. The Tetanus toxin binds to muscle nerve synapses and blocks the release of relaxation signals, causing death by bone-shattering spasms.

C. tetani is closely related to Clostridium botulinum, another lethal anaerobic soil bacteria. The Botulinum toxin (a.k.a. Botox) binds to muscle nerve synapses and blocks the release of activation signals, causing death by flaccid paralysis.

The two above bacteria are Gram-positive, as opposed to Gram-negative, the difference between the two types being that Gram-positive bacteria retain a violet crystal stain whereas the Gram-negative ones can be re-stained with a different color. The cause of this is apparently that Gram-negative bacteria have an outer layer around their cell walls that doesn't absorb the violet crystal stain as readily.

Animal cells and protozoans don't have cell walls. Plant cell walls are made out of cellulose, bacteria cell walls consist of peptidoglycan. The antibiotic enzymes, Lysozymes, react with peptidoglycan, breaking a molecular bond in it to tear apart the bacterial cell wall (by contorting a sugar in it to an uncomfortable position that breaks easily). Fungi cell walls are chitin, as are the exoskeletons of insects. Diatoms, those strange silicon phytoplankton of the seas, have cell walls made out of silicic acid. Diatom shells along with Radiolarian shells form the siliceous ooze at the bottom of the sea.

Pelagic sediments are the result of the constant rain of sediment over the abyssal plains. The rain consists of dead plankton shells, remains of marine animals, micrometeorites and dust carried by rivers and winds. If you ever wondered where marble comes from, the chain starts here. Calcareous plankton shells fall to the ocean floor, forming calcareous ooze, the precursor of limestone, a type of sedimentary rock that consists of calcite (CaCO3). The limestone then gets hammered in the forge of crustal plate collisions and recrystallizes to marble, some of which was dug up in Attica at around 440 BCE and used to build the Parthenon, the CaCO3 of which is now being dissolved to aqueous Ca2+, SO42-, H2O and CO2 in a reaction with sulfuric acid (H2SO4) from acid rain.

The clouds covering Venus are composed of sulfuric acid and it rains sulfuric acid in the upper atmosphere, but the rain evaporates around 25 km above the surface where the temperature hits 300 °C. The surface temperature of Venus is around 470 °C, which is close to Draper point (525 °C) where solid materials emit clearly visible blackbody radiation. Maybe dark places on Venus could glow a faint dull red.

The deep-sea hydrothermal vents glow as well, but with a spectrum too blue to explain with just blackbody radiation from the hot 350 °C water. The higher frequencies might be from perturbation caused by the dynamic environment, namely sonoluminescence from tiny bubbles bursting and crystallo- and triboluminescence from crystals forming and breaking.


Athenian Democracy

Listening to this Athenian Democracy lecture by Donald Kagan. The Wikipedia article is detailed too.

Ancient Athens of the time had 100,000 citizens, of whom maybe 30,000 were politically eligible (male citizens of 20+ years of age). They had political meetings every ten days to discuss and set policy about everything with majority votes. These political meetings had maybe 5,000 people present each time, but there were some votes that required 6,000 or more present to be binding.

Compare that to a modern representational democracy such as Finland. 6 million citizens, around 4.2 million eligible (citizens of 18+ years of age). They vote once every four years to choose which parties should get parliamentary seats. The parliament numbers 200 and meets four times a week to set policy about everything with majority votes.

If the Athenians had used a similar system (scaled by population), the number of members in their parliament would have been one.


Quick game reviews

The night is dark and long and I have nothing to do.

Puzzle Quest, a character-building story battle game with movement done on a map and battles resolved in Bejeweled. 65 hours played. Addictive, not all that fun to play, the match-three matches take too long, the item & spell combos are fun to come up with but haven't gotten powerful enough to shorten the matches. The art is nice but the gameplay GUI art is not so nice. Story is whatever but has a non-stereotypical stereotypical fantasy world with the player helping everyone regardless of what they want to do. And what they want to do always seems to involve playing Bejeweled against megafauna / Bob Warlord. Playable in 15-min increments in the same way that you can smoke just one cig a day. Story: A bad guy is resuscitating people and no-one wants to help and minotaurs are turning into robots to kidnap dragons and orcs and ogres are being belligerent and you must put some other minotaur bad guy together and resuscitate it so that it can fight the other bad guy and my head is hurting.

Company of Heroes, a WW2 RTS about the U.S. experience on the Western Front to take out of the remaining 20% of the Nazi army. 19 hours played. Nice graphics, jaggedy shadow maps, paintings shown between missions lack finish. Battles take too long, three guys building a tank factory to build an endless supply of Shermans makes it very RTS gamey. Not casual, takes hours per campaign map. Cover system good. UI less good than in SupCom. Not all that fun to play, but not addictive either. Story: terrorists have taken over Europe and you must kill them all. I guess?

The Misadventures of P.B. Winterbottom, a cloning-based puzzle platformer about pies. One hour played. Good presentation. Strong style. Good music loops. Figuring out the tricks to the levels is fun but means frustration, which is less fun. Not quite casual, requires ~half hour per session. Story very wtf.

Penny Arcade Adventures Episode 2, a character-building story battle game with movement done by walking characters around sets and battles resolved in turn-based combat. Half an hour played (plus Episode 1). Much like Episode 1. Maybe too much. Gabe's special attack minigame is no longer the most frustrating thing ever, which is good. Good presentation, strong style. Has battle-helping items with a time penalty to utilize, making one less likely to bother. Not quite casual, half hour sessions. Story: there are more robots and you should break them all.

Star Wars: Knights of the Old Republic, a character-building story battle game with movement done by walking characters around sets and battles resolved in pausable real-time combat. 1.5 hours played. Good presentation. Oh god do I have to talk to everyone here and beat up military people and this racist city is very boring why do I have a sword and a glow-bolt pistol where should I go now this is a lot like Baldur's Gate I'm assigning skill points to some skills I don't know anything about, hey I'm dying in these combat sequences, how quaint. I'll play more at a later date (said five months ago.) I guess it has a story to it?

Torchlight, a character-building story battle game with movement done by walking characters around sets and battles resolved in real-time combat. 41 hours played. Nice presentation, good ambient music, randomly generated maps, way too many drops, decent feel of POWER in attacks (I would still take it up a notch but I'm weird like that), fiddly targeting. Addictive. If Diablo 2 is Zangband (well, noooot really but), this is Moria. Go down down a dungeon, down down down. Down. When done with the story dungeon, there's a new random dungeon that never ends. The random dungeon generation system is nifty. Summoning golems is nifty. Lightnings and laser beams are nifty. Can be played in short stints but takes a while to load and is kinda iffy windowed. Story: There's a McGuffin in the earth and it turns you into a monster. Except not really. Only the bad guy can do that. In the meantime you just genocide everything living down there because they're hindering your walk.

Warhammer 40k: Dawn of War 2, a character-building story battle game with movement done by clicking on a map and battles resolved in tactical RTS-ish real-time combat. Played 20 hours. Randomly generated maps (I.. think.) Boss fight at the end of each map. Playing it feels like using Photoshop, very much a keyboard shortcut game. Move your four squads of bald robot men from cover to cover in a very micro fashion. Starts off challenging, gets difficult, mocks you for doing less than perfectly. Game gets uglier the more you screw up (invading monster army turns the air green with red flakes). Not casual, maps take hours to play and you're punished for failing. Presentation much like Company of Heroes (same engine, same studio) but with more shiny metal bits and glowy glow guns. Story: an invasive space species carried by the space winds is taking over space planets and the indigenous surface dwellers try to chase it off before it turns their C-H-O into its C-H-O.

CoH vs. DoW2: In WW2 you try to look like a tree or a grass because you are a hunter and don't want to be spotted. In the grim future where there is only war you wear colorful shiny clothes because war is waged as an amusement and proving ground for the aristocrats, so you must have bright clothes to show off the colors of your team.

Trees and grass are a form of water and air that absorb solar radiation to turn more water and air into tree and grass. Hence they try very hard to not be shiny reflective, hence clothes that try to look like they're trees and grass are also not shiny, hence a WW2 infantry game is not shiny. Also, you're more likely capable of digesting plastic than metal. Because plastic is made of C-H-O, same as you. Metal is not what you're made out of, so you can't turn it into your own mass, so you don't have a way to digest it. And you're mostly made out of air and water too. With some small gunks of dissolved crust elements such as Ca, P, K, S, Cl, Na, Mg, Fe.

Beyond Good & Evil, a story game with photography and occasional real-time combat, movement by walking characters on sets. Two hours played. Good presentation. Strong style. Controls on PC quite horrible. Performance problems. Tells a story, creates a world. Should finish it.

Trine, a character-building physics puzzle platformer with real-time combat. 1.5 hours played. Very nice level graphics and main character models. Paintings less nice. Somewhat frustrating. Story whatever at least up to now. Puzzle Quest ate all my time so I haven't played this much. Story: A McGuffin spares game designer from having to come up with a way to have three separate characters working together in a single-player action game.

Prince of Persia (2008), a running and jumping game with real-time combat. Played it through. Production values through the roof. Fun to play, pretty scenery, good sounds, strong style, non-obtrusive storytelling. You're constantly being saved. Story: bad gods help people, good gods do nothing, felling trees is bad but sometimes you gotta do it.

Hammerfight, a skill-based real-time combat game. Played the demo through. Super difficult, but good impact when your attacks connect. GUI graphics rather awesome, game graphics good too with glowing colors and banners waving in the wind. Slow renderer, most lacking in fillrate for smoke. Talking heads in story not so good. Story: Neighbouring emperor wants to conquer you! And he succeeds! Man.

Why do I buy these games if I don't play them? Probably because it's easy and they're cheap. And grocery shopping desensitizes you to paying 10e for something.


Git commit stats

Tonight I wrote a little tool in Ruby to print out stats based on git log output. See the project page on GitHub. (Hey, apparently there's a ready-made tool for this. And it has the same name too! Better change the name of my script to gitnuts.)

Here are the weird things it tells about my commits on a project:

Commits: 1365
Changed files: 2483
Changed files per commit: 1.8
Total added lines: 86277
Total deleted lines: 22628
Total changed lines: 108905
Added per commit: 63.2
Deleted per commit: 16.6
Changed per commit: 79.8

Changed lines per commit
Bucket size: 10
Bar step size: 9
0 *********************************************************** 538
10 ******************** 187
20 ***************** 161
30 ********** 98
40 ******* 68
50 ****** 62
60 **** 43
70 *** 33
80 * 14
90 ** 18
100 * 17
110 * 15
120 ** 21

Commits per month
Bar step size: 7
2008-01 ***** 35
2008-04 **************** 117
2008-05 **************************************************** 367
2008-06 ********************************************************** 411
2008-07 ******************************************** 313
2008-08 **************************************** 286
2008-09 ********************* 148
2008-10 ** 15
2009-01 *** 22
2009-02 **** 32
2009-10 ************* 92
2009-11 *********** 77
2009-12 * 9
2010-01 ****************************************** 295
2010-02 ********** 71
2010-03 ************ 89
2010-04 * 13
2010-05 ********** 76

Commits per weekday
Bar step size: 7
0-Sun ***************************************** 291
1-Mon ****************************************** 298
2-Tue ********************************************* 317
3-Wed ********************************************************** 406
4-Thu ********************************************************** 408
5-Fri ********************************************************* 404
6-Sat *************************************************** 359

Commits per hour of day
Bar step size: 3
0 ************************************************ 145
1 ******************************************************* 165
2 ************************************ 108
3 ********************************** 103
4 ***************************************** 124
5 **************************************** 121
6 ************** 42
7 ****************** 54
8 ******************* 57
9 ************ 37
10 *************** 46
11 ******************** 62
12 *************************** 82
13 ********************** 68
14 ********************************** 104
15 *********************************** 107
16 ************************************ 109
17 ********************************** 103
18 *************************************** 118
19 ********************************************* 135
20 **************************************** 122
21 ****************************************** 127
22 ****************************************************** 164
23 ************************************************************ 180

How about some chartjunk courtesy of R? Check color identifies commit author, y-axis is log10 of change size + 1, x-axis is time in seconds from epoch. The lines are lowess smoothings of the raw data.


Effort estimation game first round results

First round results

Task 1 estimated: 50 lines, 30 min implementation, +15 min making it work right.
Task 1 measured: 55 lines, 60 min implementation, +15 min making it work right.
Task 1 adjustment factors: 1.1x lines, 2.0x implementation time, 1.0x fix time.

Task 2 estimated: 10 lines, 10 min implementation, +15 min fix time.
Task 2 measured: 39 lines, 15 min implementation, +12 min fix time.
Task 2 factors: 3.9x lines, 1.5x impl, 0.8x fix time.

Second round

Task 3 estimated: 150 lines, 8 hours implementation, 17 hours fix time.

Task 3 estimates adjusted with factors from tasks 1 & 2:
375 lines, 14 hours implementation, 15 hours fix time.
Let's see how it goes...


Bayesian effort estimation game

Update: First round results!

How accurately can you estimate how much effort it takes you to write a new piece of code? Fear not, I have a solution! An untested solution! Very academic, you might say!

  1. Compile a list of features of different sizes that you're going to implement.

  2. Pick a small feature for starters.

  3. Estimate the effort required for it: lines of code, time to "it compiles!", time spent fixing bugs, time spent testing, time spent documenting.

  4. Document the effort: Write in your notebook when you start and stop working on the feature, and the lines of code (look at the commit data). If you don't work on the feature, write why.

  5. When you're done with an estimated task, compare the estimate and the effort by computing the effort/estimate -ratio for the task. This is your new a priori estimate error for that task.

  6. Pick a new feature, estimate, multiply the estimate by the a priori estimate error.

  7. When completing the new feature, calculate its effort/estimate -ratio. Add the ratio to the list of ratios, use their average as the new a priori estimate error. When you have a bunch of errors, plug them into R and start keeping track of their mode, standard deviation and whatever useful statistical variables you can think of. Plot a curve for estimate error per task size.

  8. The goal of the game is to keep the average estimate error of the previous 10 tasks as close to 1 as possible as long as possible.

  9. Take photographs of the people playing this game and make trading cards of them with seasonal averages and all the interesting statistics you collected earlier.

  10. Sell the trading cards to kids.

  11. Profit!

Blog Archive

About Me

My photo

Built art installations, web sites, graphics libraries, web browsers, mobile apps, desktop apps, media player themes, many nutty prototypes