Simple Rasterisation

My friend Sir Bob asked me yesterday if I knew anything about drawing something like a three-dimensional box on a flat screen, like in Java, and have it so that if you were to drag the mouse, you could rotate the box.

Simply put: yes. I very briefly outlined the concept of rasterisation, how it works in a context like OpenGL, and how you could do it manually. This post is a bit of an elaboration on the "how you could do it manually" part, with basic geometry.


These are simple ways of rendering 3D objects in a 2-dimension space (like a computer screen.) Libraries like OpenGL don't do this, OpenGL uses transformation matrices; but those matrices are derived from simple geometry like this.

Projections

Converting from object-space to screen-space. For example, you may have a line from {0, 1, 1} to {1, 2, 0}, and you want to convert it to a line on the 2-dimensional screen.

Fixed POV Orthographic Projection

Ignore the z part.
{ x, y, z } → { x, y }
For example: {0, 1, 1} becomes {0, 1}, and {1, 2, 0} becomes {1, 2}

Fixed POV Perspective Projection

Shrink things that are further from the view-point.
{ x, y, z } → { x / (z + 1), y / (z + 1) }
For example: {0, 1, 1} becomes {0, ½}, and {1, 2, 0} becomes {1, 2}

Rotation

Moving the object in its 3-dimensional space, by rotating it about the point {0, 0}.

Rotation About the Y Axis

Rotate the vector { x, z }

1. current angle =  ⎧ 90°   .. if x = 0, z > 0
⎨ 270°  .. if x = 0, z < 0
⎩ atan(z / x)  .. otherwise
2. distance = sqrt(x2 + z2)
3. new angle = current angle + rotation
4. new point = { x = distance × cos(new angle), z = distance × sin(new angle) }

Note: the y value doesn't change. I'm sure you can work out why not.

Rotation About the X Axis

Rotate the vector { y, z }
(as above, using y in place of x)

Rotation About the Z Axis

Rotate the vector { x, y }
1. Easy solution: let the 2D render surface take care of that (eg. Java Graphics2D's .rotate() note: in the documentation for rotate you can see a two dimensional transformation matrix.)
2. Real solution: as above, using y in place of z

Rotation About an Arbitrary Y Axis

To rotate an object about a Y axis that isn't at {x=0, z=0}, you do the same maths as above, but translate the x and z terms so they are relative to the axis.

For example, to rotate the line above by 90° about the axis {x=-1, z=1}:

  • the point {0, 1, 1} is translated to {1, 1, 0} by subtracting the axis; then rotated to {0, 1, 1}; then translated to {-1, 1, 2} by adding the axis again
  • the point {1, 2, 0} is translated to {2, 2, -1}, rotated to {1, 2, 2}, and translated back to {3, 2, 1}

Then to draw the line in a perspective view, the screen points are: {-0.33, 0.33} and {1.5, 1}


Disclaimer: I worked most of this post out in my head, so if it's wrong, tough.
Also, there are additional factors you can introduce, such as a field of view, clipping box, etc. that give you a bit more control over what you draw.

My general rule when doing anything graphical is this: don't be afraid to hold your hands out and imagine what is happening to the objects. Visualising everything is key to understanding it, much more so than the maths.

... Matty /<


Matthew Kerwin

Published
Modified
License
CC BY-SA 4.0
Tags
development, graphics

Comments powered by Disqus