Thursday 29 January 2009

Obtaining screen coordinates

In order to convert an X,Y,Z coordinate into X,Y screen coordinates I needed to decide which axis was which in terms of isometric direction. Using the cartesian system the X axis runs horizontally across the screen and the Y axis runs vertically up and down the screen so something that worked logically with that in mind seems the best method to use. The following diagrams illustrate the decision I had to make regarding the 3 axes of an isometric or more importantly the Y and Z axes.
The X axis is the same in both directions however the Y and Z axes are reversed in Method 2. Method 1 is the standard rotation used in 3D graphics with the Z axis going "into" the screen and as such would seem the obvious choice for my purposes. As a break from tradition I decided to go with Method 2 for the purposes of my isometric engine since when it comes to the perspective I'll be using for the project it makes more sense to imagine the objects or tiles to be viewed from above for the purposes of converting from 3D to 2D. I'm having trouble explaining why that is but it makes a lot more sense to work in X and Y rather than X and Z when it comes to simply moving objects around on a flat surface. Hope I made this clear. Anyways, the maths behind converting these coordinates is as follows:

Screen.X = X-Y

Screen.Y = ((X+Y) Div 2)-Z The Div is a simple divide but it also rounds down the result into an integer value. Very handy. Divide by Zero errors still apply.

This results with slightly skewed but usable screen coordinates. The only values I need from this calculation even values anyway so the fact certain values are displaced is irrelevant. Early on I was moving objects 1 isometric unit at a time but because of the staggered manner of an isometric plane when converted to screen coordinates it meant objects would jump slightly once per 2 unit movement and I spent a lot of time trying to get the perfect conversion formula until I realised that none of this mattered and it actually looked a lot better if all coordinates were first rounded down to multiples of 2.

X = (X Div 2)*2

It actually doesn't matter so much if the Z coordinate is rounded since any change to Z move the object up or down the screen in a straight line so the movement is smooth anyway but if I didn't move it in multiples of 2 it would move a half as slow as X or Y movements. Now that I've got the calculations for 3D isometric to cartesian coordinates the only problem is the origin of all these values is 0,0 on the game window which effectively means 0,0,0 in isometric is in the top right corner of the game window and worse 0,10,0 is actually offscreen so with a slight addition to my formula we have a working screen coordinate generator.

Screen.X = Offset.X+(X-Y)
Screen.Y = Offset.Y+ ((X+Y) Div 2)-Z

Offset is a TPoint (X,Y: Integer) so I initially set this to 400,200 and our object at 0,0,0 appears in the middle of the window. It also means I can increment the offset values and get a scrolling effect and provided I have a clipper so only objects that are within the game window get drawn I have the groundwork for an effective draw routine.

No comments:

Post a Comment