# Matrix for 2D perspective

I'm trying to determine whether what I'm attempting to achieve is even possible mathematically. I'm obviously not a seasoned game developer so I'm having trouble even coming up with the terminology to pose this question.

My 2D game (and I must stress that it is 2D) has a perspective such that the "camera" looks down at the game world from 45 degrees. Here's a rough sketch describing the look I'm trying to achieve:

As objects move from foreground to background (such as the red box pictured), they not only get smaller but are moved towards the center of the screen. So whilst the on-screen representation is rectangular, the actual game world has this shape:

Now I suspect I can do all this without using a matrix. I've already got the scaling working and don't think it would be too difficult to offset on the x axis objects according to their distance from the camera.

However, what I'd really like to know is whether I can encompass this perspective inside a simple matrix. I've had a look around the web but have got lost in a sea of nomenclature that I don't understand and information that doesn't appear to be relevant to me (such as 3D camera positioning, etcetera).

Can anyone tell me whether I'm barking up the wrong tree? If it is possible, can someone point me towards some articles or blog posts that describe this in detail?

• You are trying to hard to think of this in 2D while the math is obviously 3D. Just set up a 3D scene like, the entire point of 3D graphics is finding math to convert it to the 2D screen. Keep your game idea in 2D and just use 3D math with a camera pointed at 45 degrees and some billboards :), no need for actual models etc... – Roy T. Mar 7 '12 at 17:34
• Yes, do it in 3d. Also: Why would you want to do it without a matrix? A matrix simplifies the math! Edit: I should make it clear that a lot of the time I don't actually use an actual matrix, they're just the theoretical tool I use. With 2D stuff it's usually just x=Ax+By+C, y=Dx+Ey+F – user10968 Mar 8 '12 at 2:46
• @NeuroFuzzy: er, I don't want to do it without a matrix - the point of my question was to determine how I do it with a matrix instead of manually. – me-- Mar 8 '12 at 18:24
• ack, sorry, I misread. – user10968 Mar 9 '12 at 7:51

You are talking about doing manually something which is already done for you automatically by 3D APIs. One of the most basic functions of any 3D engine is to handle the transition from a bunch of objects in 3D space and a camera (naturally you must always have a camera) to a 2D picture (technically a projection) on the screen.

In your case, doubtless an object's representation moves more pixels per second going left or right than away from the camera, due to your angle (unless you deliberately have a fundamentally illogical physics model, like many such pseudo-3D games, and have those speeds be equal - not criticizing). This would be handled by what is known as the view matrix, which looks at where objects are in the world and says where they should be on the screen.

If objects far away did not get smaller, and the road away from you looked straight if it was straight (ie did not appear to narrow due to perspective) you would have the familiar isometric game. To make far away things smaller, and a few other similar things, you apply what is known as a projection matrix which pretty much takes what the camera sees, and "distorts" to show how it would look if the camera had an arbitrary lens. An isometric game has no projection matrix and thus everything is... Well, isometric.

There is usually a third kind of matrix, a world matrix, in 3D engines - because parts of 3D models are placed relative to the models origin, you need the world matrix for placing models in different points of your world. It's also like position and rotation (and scale, and skew if you have 4D matrices) of your object all in one handy mathematical entity.

So what you usually do is, you multiply (matrix multiply) these three matrices, and multiply the "model" (which is a bunch of points and polygons defined with respect to a model origin) in order to place a model's image on the screen. These matrices are not invariant, of course. For instance, the world matrix is generated depending on where your object moves.

I think isometric games are at the "2D threshold" - they are roughly the same amount of work Math-wise in 2D and 3D:

• You can make a "2D" isometric game with an identity matrix for a projection matrix, and put all sprites on billboards (in the computer graphics meaning) but you'll still have to muck about with a quite superfluous "camera" to create the 3D transformation matrices.
• You can make a 2D isometric game with sprite graphics, where you say directly where on the screen you want each sprite to be drawn (in the familiar x, y with regard to top left of the window fashion). But if you have, say an isometric RPG, and characters can jump, you'll still have to keep track of height and calculate the y coordinate accordingly, and if you don't do some trigonometry with sizes and speeds the game world will be very "strange" form a physics point of view.

However, once you do more 3D-stuff than a sprite-based isometric game would entail, as you are, I think it would be much less trouble to do everything in 3D, unless your goal is to make a 3D engine from scratch. As for your question, hopefully it is clear to you now that what you want to do can be done, it can be done easily, and it is routinely done by just about everyone out there who does 3D as a matter of course. To sum it up: Yes, it can be done, and it's fairly straightforward, but you shouldn't do it and would save yourself a lot of needless work if you just used a 3D engine.

For learning about linear algebra, you may find sources like the Khan Academy or the MIT lectures helpful. As someone who already knew linear algebra but had no idea how it applies to 3D graphics, I have found XNA and RB Whitaker's XNA tutorials very helpful and easy. They also explain using matrices for 3D like I did here, except better.

• Thanks for this very helpful reply. I have an existing object model with 2D vectors to represent location, velocity, normalized heading etcetera, and with methods to convert from world to local space and vice-versa. So it sounds like I basically want to add a method to convert from world space to view space using a projection matrix, with my z coordinate fixed at zero (which will temporarily rise and fall for any objects in the game that jump). Can you validate my thinking here? – me-- Mar 8 '12 at 18:44
• Well, technically the view matrix operates on world space (and produces an isometric image with no perspective). The projection matrix "sort of" operates on this isometric image and stretches or shrinks it to make it more realistic. So you would have a method for world space -> view space, then a second method for isometric view space -> perspective-y view space. You are correct about z. – Superbest Mar 9 '12 at 11:24

A matrix is one of many ways of storing an arbitrary transformation, but it happens to be a very simple way, since "apply the transformation to a point" is simply "multiply a vector by a matrix".

Fundamentally, you have several coordinate systems you are converting between:

1. 3D Object Space. This is the logical location of your objects.

2. 3D Camera Space / Eye Space. Camera space is that trapezoid (actually a frustum, since it extends up into the 3rd dimension as well) in your question. The Z coordinate is from the near side to the far side, the X coordinate maps from the left side to the right side, etc.

3. 3D Screen Space. This is taking the frustum of cameraspace and stretching it into a rectangular shape.

4. Pixel Coordinates on screen. This is pretty much the X and Y coordinates of screenspace, but offset so that the origin is at the top left instead of center, and the Y coordinate is probably flipped.

See http://www.songho.ca/opengl/gl_transform.html for a good article that includes math and diagrams on the coordinate transformations.

some Pseudocode to get you headed in the right direction: You'll probably want to find an existing matrix math library for whatever platform you're using.

objCoords = x,y,z,1 = ... my objects location ....
eyeCoords = modelViewMatrix * objCoords
screenCoords = projectionMatrix * eyeCoords
screenCoords = screenCoords / screenCoords.W  // <- w is the perspective factor here
// at this point, screenCoords contains an X and Y
// you can work with in your 2D engine.