Isometric Grids in Python
I love isometric views; they pack a bunch ( punch ?) of visual information and are great for sketching pseudo 3D views, making them programmatically on the other hand has always seemed daunting, at least to me, come along as I face my isometric fears and build one from scratch in python.
Here's a typical isometric Grid/Image and a simple approximation of what's going on which we will use throughout, starting from a simple square you rotate it 45° and then squish it so it is twice as wide as it is tall.
Prerequisites: If you want to code along you'll need pygame, although hopefully what we learn here will work for other libraries that can draw lines and place sprites on a canvas, same goes for other languages. If you need a primer on grids/Pygame check this other post : Making Grids in Python.Note: Not an optimized Pygame solution, use/tweak the game loop as per your needs, this one for instance runs all the time which might not be what you want, the last example adds some basic animations if hat's what you are after.
Let’s start simple with a square we can convert to an isometric form, importantly this square or rectangle is made up of 4 segments and their respective coordinates so we can move (or project) them around, I’ve also added some colored circles at the vertices which will become handy for tracking them.
A common technique I found can be achieved by rotating the square 45° and making the width twice as the height, in pseudo code :
isometricfromCartesianX = pointX - pointY
isometricfromCartesianY = (pointX + pointY)/2Cartesian is the regular x,y's we've been using for our coordinates, the following code snippet does this transformation...
There’s not much to it, just apply the
cartToIso function on the original square points and off you go, notice that the size and position of the isometric square ( technically a rhombus ) are shifted to the left and down, the width is also double the height.
Isometric grid: That wasn't bad for a first approximation, note that I am not getting into the thorny math of coordinate projections because at this point I am just figuring it out myself but so far so good, so let’s move on and try to make a grid…
Once more there's not much to it, I am using the exact same grid code I used for my 2D grid post and then using the cartToIso function on each point, just be careful to encase the points correctly, so a point like (origin, hw + origin) turns into cartToIso([origin, hw + origin]) notice the inner list brackets .
A grid in the end is mostly a container so in order to make it more useful we need to populate it with content, let’s start simple with some color coded tiles in cartesian and isometric views…
Few things worth noticing from this example: We (I) have a mess of coordinates, borders and other small details, this is mostly fine for a quick example on how to draw isometric tiles. The main problem is that we don't have a way to tie up the container ( the grid ) and the content ( the tiles ), a secondary problem is that there is no clear relationship between the cartesian grid and the isometric one, while you might not need the graphical representation in your program you still need a coordinate system and starting from a cartesian one and converting to isometric is fairly common, so you might still need to check on these coordinates before moving them to isometric ones, so these 2 issues are our next order of business...
The following script uses a
cellMap matrix to describe the grid and ties the coordinates of both cartesian and isometric projections…
Once more the weird thing here is the rotation of the coordinates since top left is now visually top right, if you need to rotate them in other direction either change your map or how you loop over it.
And here’s a slightly more complex script where we change the map every second or so….
There are a few methods for animating tiles and Pygame in general, here we added a timer variable which we check for in one second increments and then we create a new random cell map, but you could use pygames native timer and/or FPS, check pygame's time documentation for.
Where to now?
At this point you should have enough to make your own isometric grids, simple tiles and Pygame game loop, where you go from here is entirely up to your project, for instance if you want to make a game or 3d visualization you will need to deal with adding the z axis and ordering your tiles so they don’t overlap, ( check this SO answer ) and as mentioned the techniques covered here are neither the only ones or limited to Pygame.
Thanks for reading and I hope this post helped you in some way.