Archive for September, 2008

Vista annoyances

Saturday, September 20th, 2008
  1. The intensity of the shadows around the windows darkens in proportion to the number of shadows. When you have a pile of windows of the same size in the same place, it looks very weird.
  2. Sometimes remote desktop sessions from an XP machine freeze for no apparent reason - often it is necessary to close the session and reconnect to regain control. Curiously, rebooting seems to help but then it starts happening again at the next reboot - some parameter seems to be set at random on boot which affects how often this happens. Googling suggests a few solutions, none of which made any difference for me.
  3. Windows Mail works well enough but it's search facility is much slower than Outlook Express's was because mail is stored one message per file instead of one folder per file. I guess this would be less of a problem if I hadn't turned off the Windows search service, but this service is a resource hog.
  4. The Aero glass theme is okay but I think on the whole I still prefer the classic Windows 98 look. It's easier to tell when a window has focus. Glass is really just a gimmick - there's no usability advantage. And taking screenshots of windows leaks information through the translucent title bar. I would switch back to the classic look but certain pieces of Windows functionality look terrible on Vista classic. Also you can't do this without turning off compositing. I hope they fix that in a future version.
  5. You still get an annoying warning message when the number of icons on your start menu is too large. Why can't you just make the menu take up the entire vertical height of the screen and put as many icons as you can on it?
  6. You can't type a full path into the "Save As" dialog anymore! It says that "\" is not a valid character to have in a name. You have to navigate to the directory you want to save in and then just type the name.

Some might say that having worked at Microsoft throughout the entire Vista development cycle I should have been trying it out regularly and filing bugs. But they weren't paying me for that, and for most of Vista's development it was too buggy to be usable for my day to day work - I would have had to have dedicated a machine to it (which I probably would then have used rarely). Also, I tried filing bugs against Windows a few times and they always got resolved as "By design", "Won't fix" or "Postponed". It's not that the developers don't know about these things, they just don't have the resources to fix them.

More Linux usability problems

Friday, September 19th, 2008

Tab completion: If there are multiple possible completions, you have to type the next character and press tab. With Windows you can just press tab repeatedly until you get to the completion you want. Both systems are reasonable but it's annoying to use one when you're used to another. To be fair the Linux system has better worst-case behavior (O(n) keystrokes instead of O(exp(n))) and I think it's generally better for navigating hierarchies that you know well, but the Windows system is better for navigating unfamiliar hierarchies.

Shell glob expansion: while it makes some sense for the shell to expand wildcards and does ensure consistent wildcard expansion for different programs, I think this design causes more problems than it solves. Wildcards mean different things depending on what you're doing, so I think on balance it makes more sense for individual programs to do their own wildcard expansion as in Windows. For example in Windows I can type "findstr /sip foo *.txt" to find the string foo in all files ending in .txt in all subdirectories. With Linux this is significantly more complicated. This also leads to:

Too much escaping: with so much intelligence in the shell, many characters have shell meanings and aren't just passed along to programs on their command lines unless they are escaped. This leads to tons of escaping. Escape sequences aren't hard to write (at least if you know what the escape character is) but they are very hard to read - they look like line noise.

I made my bash prompt a different colour from the rest of the terminal and now it gets confused if press up when the path is so long it takes more than one line of the terminal window. It's just a bug (in readline I think) but this software is so mature there's no excuse for it.

It's annoying that closing a terminal window closes any programs that I've opened using it, even background ones. I don't want any processes to go away without me explicitly killing them.

Double-clicking on the top-left corner of a window should close it like it does on Windows, but it doesn't.

Adding programs to the start menu seems to be much more difficult than it is on Windows.

Emacs gripes

Thursday, September 18th, 2008
  1. Copy and Paste in CUA mode (Ctrl+C, Ctrl+V) doesn't interact with the desktop clipboard. If I want to copy and paste to another application I have to use the mouse. I know this isn't really the fault of Emacs, and might even work if I used it in windowed mode, except for:
  2. Windowed mode takes too long to start up if I'm using Emacs on a remote machine (as I often am). Sometimes even terminal mode takes a long time to start up if the machine is busy. I guess this has improved in recent years but it's still annoying when I have to wait for it. I'm sure Emacs gurus would tell me that I just need to leave it running continuously and use it as my desktop environment, but I would rather bend my software to support my way of working than the other way around.
  3. CUA mode doesn't work in PuTTY because the shift+cursor keys don't send the right sequences. Again, I know this isn't really the fault of Emacs.
  4. PgUp and PgDn don't work right. Specifically, if I'm in the middle of a long document and I press PgUp followed by PgDn, it should put the cursor back where it was. It doesn't. This drives me crazy as I lose track of where the cursor is in the window, where the cursor is in the document and where the document is relative to the window. It always takes me a few seconds to get my bearings again. I found some code which fixes this, but shifted PgUp and PgDn don't work - guess I'll have to learn some elisp.
  5. Long lines are wrapped instead of disappearing on the right by default. This seemed quite sensible at first (since you can see the whole document without horizontal scrolling) but it makes vertical cursor movement is unpredictable. In general I think I prefer horizontal scrolling. Fortunately this is easy to change.
  6. Spaces aren't removed from the ends of lines. This mostly trips me up when I copy and paste using the desktop clipboard from another emacs session in a different terminal window - all the lines that end partway through a /* comment */ get spaces at the end of them for some reason.
  7. It indents with tabs instead of spaces. I know how to turn this off but it means that most GNU source code has tabs. This means that the indentation of these files only looks correct when the tab stops are every 8 characters. Also it means that when I move the cursor left or right I can't predict whether it will move 1 space, 8 or something in between, and often end up overshooting with my cursor movement. Also the fact that pressing Tab doesn't insert a tab character has tripped me up a few times.
  8. I couldn't get visible whitespace mode to work - it seems to be incompatible with my terminal. I think this might be fixed with Unicode support in the next version of Emacs.
  9. There don't seem to be any good colour schemes for terminal mode, only for windowed mode. Again I guess this is the fault of the terminal for having only a fixed palette of 16 colours. I tweaked the default colours a bit to get something reasonable but it's still a bit garish, and writing a colour scheme from scratch is daunting.
  10. Sometimes font-lock mode parses things incorrectly. Most editors have similar problems, but when it happens in Emacs it's more confusing because Emacs tries to be more intelligent.
  11. Not all navigation can be done with the shift keys for selection. I particularly miss shift-home and shift-end - combinations like these are much more intuitive and discoverable than special purpose commands like "delete to end of line".
  12. Undo doesn't work very intuitively - if I undo too far it undoes the undoing. I like the Windows Ctrl+Z to undo, Ctrl+Y to redo system more.
  13. Backspace in incremental search goes to the previous hit. I often want to search for something and then when I find it search for something else from that point. This operation always seems to trip me up. Okay it's easy to work around but still annoying.

Many of these can probably be fixed if I spend enough time tinkering with it.

I suppose to be fair I should list the things I like about Emacs too:

  1. Extensibility. Nothing else even comes close.
  2. Community. I don't think any other editor has had so much written about it online.
  3. C programming features. It's terrific that I can make my code follow the GNU style guidelines just by pressing Tab somewhere on the line.
  4. It highlights extraneous spaces at the end of lines.
  5. Apart from point 13 above, incremental search works great.
  6. I like the way tab completion and some other things work the same way as in bash. Consistency is nice. Nothing outside the Free Software world is this well-factored.

Linux cleartype subtly broken

Wednesday, September 17th, 2008

Most modern graphical desktops have an option to render fonts taking into account the positions of the sub-pixels on liquid crystal displays. Since these are always in the same positions relative to the pixels, one can subtly alter the horizontal position of something by changing its hue. This effectively triples the horizontal resolution, which can make for a great improvement in the readability of text.

Unfortunately, my Ubuntu desktop doesn't do this correctly - some bits of text have a yellowish fringe and some bits of text have a bluish fringe, both of which are quite distracting. The problem is that while you can alter the horizontal position of something at sub-pixel intervals, you can only alter its width by whole pixels (otherwise the hue changes don't cancel out and integrating over a region of the screen gives a yellow or cyan colour.

I've therefore had to switch my desktop to use grayscale anti-aliasing, which is a bit more blurry. Fortunately the pixels on my monitor are small enough that this doesn't bother me very much. I do prefer the font rendering that Windows does, though. While FreeType does apparently include code to support Microsoft's patented programmed hinting I can't seem to get the font rendering on Linux to look as good as it does on Windows.

Equations for 3D graphics

Tuesday, September 16th, 2008

When I first learnt how to do 3D graphics it was as a recipe. You take your 3D world coordinates x, y and z and rotate them (rotation matrices around the coordinate axes are particularly easy to write down). If you want perspective, you then divide x and y by z (for isometric views just ignore z). Next you scale the result by the number of pixels per world-coordinate unit at z=1 and translate so that x=y=0 is in the center of the screen.

This worked great, but didn't tell me why this was the right thing to do.

Later, reading about ray tracing I realized what was really going on. Your model is in 3D space but also in 3D space are some additional points - the entrance pupil of your eye and the pixels that make up your screen. If you imagine a straight line from your eye passing through a particular point of your model and going on to infinity, that line may also pass through the screen. If it does, the point on the screen that it passes through corresponds to the pixel on the physical screen at which that point should be drawn.

Since computer screens are generally rectangular, if the positions of the corners of the screen are a, b, c and d (a and d being diagonally opposite to each other) the position of the fourth corner can be determined from the first three by using the equation a+b=c+d. So to fix the position, orientation and size of the screen we only need to consider 3 corners (a, b and c). We also need to consider the position of the eye, e, which is independent of a, b and c. We thus have 12 degrees of freedom (3 coordinates each for a, b, c and e). Three of these degrees of freedom correspond to translations of the whole screen/eye system in 3D space. Two of them correspond to orientation (looking up/down and left/right). Two correspond to the horizontal and vertical size of the screen. Three more give the position of the eye relative to the screen. One more gives the "twist" of the screen (rotation along the axis between the eye and the closest point on the screen plane). That's eleven degrees of freedom - what's the other one? It took me a while to find it but eventually I realized that I was under-contraining a, b and c - the remaining degree of freedom is the angle between the top and left edges of the screen (which for every monitor I've ever seen will be 90 degrees - nice to know that this system can support different values for this though).

If you solve the equations, this system turns out to be exactly the same transformations as the original recipe, only a little more general and somewhat better justified. It also unifies the perspective and isometric views - isometric is what you get if the distance between the eye and the screen is infinity. Obviously if you were really infinitely far away from your computer screen you wouldn't be able to see anything on it, which is why the isometric view doesn't look as realistic as the perspective view.

Many 3D graphics engines allow you to set a parameter called "perspective" or "field of view" which effectively increases or decreases how "distorted" the perspective looks and how much peripheral vision you have. This is essentially the same as the eye-screen distance in my model. To get the most realistic image the FoV should be set according to the distance between your eyes and your screen.

Getting rid of the branch cut

Monday, September 15th, 2008

The video I made for Saturday's post made me wonder what the picture would look like if you didn't have a branch cut at all - if you make the logarithm function generate all of its multiple values (or equivalently, choose a sheet of the Riemann surface at random). Computers can't count up to infinity so the random method must be used. We can't make all the sheets equally likely as their number is unbounded so we need to pick some distribution. I chose a method that's rather simple to implement - I just roll a (virtual) dice until a 1 or a 6 comes up, and subtract the number of 2s and 3s from the number of 4s and 5s (a 1D random walk). That makes positive and negative numbers equally likely, but makes small (positive or negative) numbers more likely than large ones.

Here is the result:

Square roots

The infinite tower is transformed into a fractal fern-like structure. I was surprised at how different this looked from the second image on this post - while the non-principal branches are not visited very often, they cover a lot of space so make a lot of difference to the image.

Don't start big projects

Sunday, September 14th, 2008

If you have a big project to do, it's very difficult to get started because big projects are so daunting. Most people have probably experienced sitting down to start some project, getting a wave of anxiety about it and then thinking "I'll just refresh my news feed one more time/play one more game of solitaire before I get started". Days and days can pass this way.

The trick is, of course, to not start big projects at all - instead to start a small project and hope it grows into a big project. The trouble is that it's difficult to start modifying a project that's already big if you didn't start it yourself, since even learning enough to make a tiny change is itself a dauntingly big project.

If you can't pick a small project instead of a big project, the thing to do is divide up the project into smaller ones (which itself isn't necessarily a very big project at all - it's just writing down a short list). Then pick a sub-project and just go and do it (recursing as necessary). If you are at all susceptable to procrastination, it's important to avoid looking at the entire list - just concentrate on the one small part of it that's next and forget the rest. Completing one small part gives the satisfaction and mental energy required to start the next one.

It is for this reason that I don't think I could ever write a novel. A small piece of a novel isn't self-contained and independently useful the way that a small piece of a computer program can be, so you don't get that sense of satisfaction from completing it.

One problem I often had at Microsoft was scheduling and estimating time for large projects. Many other programmers I know have the same problem. In order to estimate accurately you need to do a full walk of the tree of sub-projects until each sub-project is no more than a day's work, add up the number of sub-projects and give that as the number of days. That's going to be gross overestimate, of course, since if you know a sub-project is going to be less than a day's work, chances are you know enough about it to do it much quicker than that. But managers (in my experience) prefer it when people overestimate than when they underestimate as it reduces risk. If you desire tighter bounds on your estimate you can figure this out with some practice, by multiplying the number of sub-projects by the average fraction of a day it actually takes to do a sub-project.

The trouble with schedules that are vastly overestimated is that they don't convey any sense of urgency - if you know in the back of your mind that you have three times as much time as you need to do a project, chances are you'll procrastinate for the first two thirds of that time. Then when the project takes longer than you estimated (as projects invariably do), you overrun the allotted time and look less than competent. Trying to achieve the delicate balance between a schedule that is achievable and a schedule that will motivate you sufficiently is difficult.

Scheduling is also very demotivating work in itself because that big list of sub-projects (and the corresponding long stretch of time) looks very daunting, and you don't even get the satisfaction of completing each part as you tick it off the list. I'd much rather not have any schedule at all, and just work at my own pace. I find that "trying to be finished as soon as possible" motivates me much better than "trying to be finished by date X". Managers do like to know when things will be finished, though.

I think the ideal way to cope with this would be to work one project ahead - work on project X+1 while management thinks you're working on project X. Then when you're asked to schedule project X+1 you'll know exactly how long it takes because you've just finished it. Add in a little extra time in case project X+2 takes longer. I never managed to get to this state, though - mostly because I was continually playing "catch up" and also because we weren't planning sufficiently far ahead that I had any idea what project X+1 would be at the start of project X's officially allotted time.

Adjusting the branch cut

Saturday, September 13th, 2008

The second image in this post was quite popular, so I decided to make a movie out of it.

There aren't really many parameters in the equations used to make this image, though - (the functions are just negative, exponential and logarithm). The colouring is arbitrary but modifying it wouldn't make a very interesting movie. The zoom factor is fairly arbitrary as well but zooming very much in or out would make the image take much longer to render (besides which, zooming movies have been done to death). About the only other arbitrary thing about the image is the choice of branch cut for the logarithm.

This describes a way of adjusting the branch cut in a continuous way, and this is the movie I made by adjusting theta from -4.5 to +4.5 radians:

High quality 640x480 11Mb DivX avi version.

This took about three days to render. I could have done it faster, but my laptop gets uncomfortably warm when both its cores are fully utilized. Also, a problem with Vista networking was causing the other machine I was using to keep getting disconnected from my laptop every few frames.

Cheating in online games

Friday, September 12th, 2008

Many modern online games go to great lengths to try to prevent players from cheating - some of them quite invasive. I hope that in the future our computer systems are architected to make it trivial to subvert such malware, but where does that leave players of on-line games who want to avoid playing against cheaters?

Well, I hope that in the future, online games are designed in such a way that cheating is impossible - that is, no information sent to a player's computer that would allow them to gain an unfair advantage and no information received from a player's computer is trusted to be untampered-with. In such a game, a player would be allowed to use whatever client software they like, and would be encouraged to use client software that gives them the best odds. Serious golf players pick the clubs that give them the best advantage, tennis players pick the best tennis rackets and so on - why should on-line gaming be any different?

One implication of this is that the best games will be Turing tests of a sort - a game of aiming accurately and reacting quickly won't be much of a challenge since the computer can do those things better than human players. Tasks that humans can do well but computers are poor at will need to be integral to the game.

That's not to say that games of aiming accurately and reacting quickly won't exist, but if they are played online they will be played between people who each other and trust each other not to cheat, not between strangers.

Static scoping improved

Thursday, September 11th, 2008

Many programming languages have a facility (usually called "static") to allow the programmer to declare a variable which is visible only to some particular object but has storage at the program's scope - i.e. its value is the same for all instances of that object and when it changes for one it changes for all the other instances too.

One programming language feature I've never seen (but which I think would be useful) is a generalization of this - the ability to declare a variable which is only visible in a particular object but whose scope is the (lexical) parent object. I call this "outer". For top-level objects, this would be the same as static but for nested classes the scope would be that of the outer class.

One could even use the "outer" keyword multiple times to put the variable in any particular level in the object nesting tree. This doesn't violate encapsulation, since members can still only be declared inside their classes.

If you have "outer" instead of "static" (and maybe a few other more minor tweaks) any program can be turned into an isolated object inside another program - i.e. you can easily turn a program into a multi-instance version of that program with all the instances running in the same process.