Axonometric Projection?

Hi all
I’ve been on and off trying to figure out a simple system to draw textures on top of axonometric tiles (I think that’s the right term)?
The intended view is tiles of 64 pixels width and 31 height (on the top face). I have managed to get a view working that’s comprised of filled polygon faces:

The gaps between faces is something I’ll try to work out (I was following a page that suggested this view requires the height to be 1 pixel less than half of the width), but it gives that as a result.
Anyway, here’s what happens when I try to draw a texture on top of it:

This is using the following code:

                 if (!wireframe) {
                    g2.setColor(colors[Math.min(colors.length -1, tileID)]);
                    //g2.translate(-projHalfWidth / 2, 0);
                    g2.drawImage(Game.getTileset().getDefinition(t.chunks[cX][cY].tiles[tX][tY][z].tileID).tex, 0, 0, projWidth / 2, projHeight, null);
                } else {

I read somewhere that using Math.atan(0.5) would yield the correct angle for rendering, and while it does partially seem to be the case, I’m left scratching my head over how I can fill the top face with this image correctly? Mostly, I’ve experimented with translation, shearing, and different angles, but to no effect. I really can’t figure this out.

I would appreciate any help :slight_smile:

I was doing something similar to that recently. First I rotated a square by 45 degrees, then scaled its vertical size by 0.5, then translated it to the correct position. I don’t think you need atan in there, its just a 45 degree angle.

Thanks for that, I’ll give it a try as soon as I can :slight_smile:
Would that give a correct result for 1:2 projection?

edit: I’m guessing it would, that’s a silly question. It’s late :stuck_out_tongue:

LiquidNitrogen has the right idea; what were you even thinking with Math.atan(0.5)?

Note that the order of the transforms matter (scaling, rotating, translating); May vary between implementations/engines.

Demo I made out of boredom:,output

I was following the advice of a document I found online that suggested it as some sort of golden number. I must have misinterpreted it, or it may have been wrong.

Well, that article may have been correct, and atan(0.5) does make sense if we think about how it was derived and what the author wanted to compute with it:
If we assume the length of the projected tile along the X axis to be twice as large compared to the projected height of the tile along the Y axis, then the perceived angle of the tile (when seen in the axonometric projection) can be derived just like that:
tan(angle) = (opposite leg / adjacent leg)
where opposite leg is the length of the projected tile along the Y axis and adjacent leg is the length along the X axis.
Since we assume the length along the X axis to be twice as long as the length along the Y axis, this ratio is 0.5.
So, tan(angle) = 0.5
Since the author may have wanted to compute the actual angle between the X axis and the side of projected tile, we would have to use the inverse of tan, which is atan: atan(tan(angle)) = atan(0.5) ≈ 26.6 degrees.

It’s also interesting to note that you don’t have to stick to 45 degrees, although it does look most correct… you can use whatever rotation angle you want, which gives you the ability to view the scene from any angle and smoothly rotate the camera. It can be difficult to make objects on top of the map fit in properly with rotation however, but the option is there.

I may be totally wrong here, but shear seems like the option to use. Maybe something like g2d.shear(texture.width, 0)?