Monday 13 February 2006 — This is over 18 years old. Be careful.

I’m doing a lot of coding these days involving XY coordinates, and there’s a handful of little annoyances. They’re no one’s fault, I just want to vent.

First, it’s natural to say “x and y”, and it’s natural to say “height and width”, but x corresponds to width, and y to height, so I often make mistakes that switch the two:

ht, wd = foox, fooy # This is wrong.

The same goes for loops over x and y. The natural order to visit the points in a grid is the raster order: finish a row, then go on to the next row. But that means having the first loop be over y rather than x:

for y in range(lowy, hiy):

for x in range(lowx, hix):

do_something(x, y)

For this last, there’s a solution: create a generator that makes x,y pairs in a single loop:

def xyrange(startx, endx, starty, endy):

""" Generate the pairs (x, y) in a rectangle.

"""

for y in range(starty, endy):

for x in range(startx, endx):

yield x,y

Then this function is the only place that needs the inside-out y x ugliness, and you can use a single loop everywhere else:

for x, y in xyrange(lowx, hix, lowy, hiy):

do_something(x, y)

This has the advantage that you can break out of the loop cleanly when you find a point you are looking for. It has the disadvantage that you can’t do an action at the end of each row.

*Update:* Richard Schwartz noticed that I originally had
said,

First, it’s natural to say “x and y”, and it’s natural to say “height and width”, but x corresponds to

height, and y towidth, so I often make mistakes that switch the two.

which makes that sentence itself an error of the sort it describes, making it an unintentionally self-referential sentence!

## Comments

Pete Lyons8:34 AM on 13 Feb 2006andrew8:54 AM on 13 Feb 2006Bill Mill9:33 AM on 13 Feb 2006Ned Batchelder10:42 AM on 13 Feb 2006Or, in the loop, you could check if x is equal to lowx, and then do beginning of row processing...

Damien Katz11:48 AM on 13 Feb 2006Michael Chermside1:55 PM on 13 Feb 2006Marius Gedminas2:29 PM on 13 Feb 2006Ned Batchelder3:01 PM on 13 Feb 2006Ayende Rahien4:13 PM on 13 Feb 2006""" Generate the pairs (x, y) in a rectangle.

"""

for y in range(starty, endy):

for x in range(startx, endx):

yield x,y, x == endx

That should give you the ability to check for the end of line

Alexander Belchenko4:18 PM on 13 Feb 2006James6:44 PM on 13 Feb 2006Jonathon Duerig11:20 PM on 13 Feb 2006http://esoteric.voxelperfect.net/wiki/Befunge

Shane Hathaway3:40 PM on 15 Feb 2006Also, precisely what part of a pixel do does a coordinate refer to? When you say (0,0), does that mean the center of the top left pixel or the top left of the top left pixel? This matters if the lines are antialiased.

Haukur Hreinsson9:44 PM on 18 Feb 2006ftp://ftp.alvyray.com/Acrobat/6_Pixel.pdf

I have an additional 2D programming annoyance. You tend to write two lines where one does something with say x, width, and cos, and the other with y, height, and sin. Then there may be a few things that go in both lines. And of course you write the second by copying and modifying the first. The fun starts when you forget one of the required changes. And even if you don't, it still feels wrong.

I get way too hung up on stuff like that.

Ed Davies8:03 AM on 15 Jun 2006## Add a comment: