[Math] Determining which side of a 3D cube is facing the viewer

3dgeometrylinear algebra

Me and a friend are trying to render a rotating cube on a 2D plane(the screen) using java.
Here's the problem

  • The cube has 6 sides, each with a specific normal vector of the form $(0, 0, 1)$, $(0, -1, 0)$ and so on
  • The sides(and their normals) are rotated using a matrix as described on en.wikipedia.org/wiki/Perspective_projection#Perspective_projection
  • But unlike Wikipedia we project our rotated 3D-vectors on a plane situated on the positive X-axis using:

v = The 3D vector which has been rotated by the matrix = $(a, b, c)$

v2D = The 2D vector projected on the plane/screen = $(b, c)$

  • These new 2D vectors are then used to draw an image
  • To determine which of the six sides, that should be rendered we use the fact that the plane is located directly on the positive X-axis.

n = 3Dvector pointing directly outwards from the side

n2 = [rotation matrix]*n = The rotated normal pointing directly outwards from the rotated side = $(x, y, z)$

now if $x>0$ then the side is facing the same direction as the positive X-axis. And since the plane/screen to project on is located on the positive X-axis this means that the side is facing the screen and should be drawn on it.

  • So far, this is working perfectly and it looks like this:
    Image1
  • But this cube could need some perspective and to get this we change the projection slightly:

v = The 3D vector which has been rotated by the matrix = $(a, b, c)$

$w=-a/700+1$;

v2D = The 2D vector projected on the plane/screen = $(b/w, c/w)$

  • This gives a cube where more distant objects are smaller
  • The only problem is that sometimes it shows sides that shouldn't be shown like:
    Image3

So how should I compensate for the new perspective? It's clear that n2 is no longer pointing orthogonally from the surface of the sides. So that's what I need. A vector pointing orthogonally from the surface of the side, which has been distorted by w while n2 haven't

(edit) Here are some numbers.

  • The Cube has a width of $300$ pixels i e 150 pixels from origo to a side following it's normal
  • The plane/screen to project on is located on the positive X-axis at $(300, 0, 0)$
  • The viewer is located at $(1000, 0, 0)$ hence $700$ in the calculations above

Best Answer

When you weren't taking perspective into account (image 1), you were effectively viewing the scene from infinity, i.e. you replaced the parameter $700$ by infinity, resulting in a scaling factor $w=1$. When viewing from infinity, there is no difference between checking whether the normals point in a certain direction or checking on which side of the surface the viewer is, since the viewer is effectively infinitely far away and so which side she's on is determined exclusively by the direction of the normal.

But when you bring perspective into it, these two are no longer the same, and what you're actually interested in is not which direction the normal points, but which side of the surface the viewer is on. So you should figure out what viewer position your perspective projection corresponds to, and then instead of just testing the direction of the normals, form the scalar products of the normals with the viewing position, and check whether the result is greater or smaller than the corresponding product for points on the plane. I guess this can probably be rewritten as a transformation on the normals instead, but this to me seems a more natural way to think about it.