Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining which side is facing the viewer on a 3D-cube

Tags:

java

3d

For a school assignment me and a friend have been working on rendering a cube on a 2D surface(the screen) using a 2D-library(slick)

To do this we use the method described here 3D-projection - Wikipedia the free encyclopedia.

We use a 3x3 matrix to rotate the 3D-vectors which represents points on the cubes surface. Then We project the 3D vectors onto a plane(the screen) located on the positive X-axis using this method:

public Vector2D translate2D(Vector3D v){

    Vector3D trans = translate(v);//Rotates the vector into position

    float w = -trans.getX()/(700) + 1;
    float x = (trans.getZ())/w;
    float y = (trans.getY())/w;
    return new Vector2D(x, y);
}

where translate() rotates the vector into the correct position and w adds some perspective to the cube.

Now here's the problem:

I need to know which sides of the cube to render and which to not render(i e which are facing the viewer and which aren't). As long as you don't use perspective(w) this is easy. The cube always shows three sides to the user and to find these all you needed to do was:

  1. Get the side's normal
  2. Translate it using the rotational matrix
  3. If the translated normals X-component was positive, then the side was facing the positive X-direction and therefore was to be visible to the viewer.

This because the screen is located directly on the positive X-axis.

Now, because of perspective, the viewer is facing 1-3 sides depending on the rotation of the cube. How can I compensate for perspective in my calculations and determine which sides are facing the viewer? As mentioned I have access to each side's normal(unit vectors pointing straight away from each side) and the matrix which handles the rotation as well as the above method.

(edit) Thank you for your answer horatius83 but here's my problem: I dont know he surfaces normal since the side's normal is slightly distorted due to the added perspective.

Here are some images to describe my problem further

Without perspective(side's normal=surface normal):

enter image description here

With perspective showing 3 sides(side's normal!=surface normal):

enter image description here

With perspective showing 3 sides but should only be showing 1(side's normal!=surface normal)

enter image description here

(edit) the code determining whether the side should be rendered is very simple and not entirely correct since we're using the side's normal as if there was no perspective(as in image 1). If there is perspective this must be compensated for in some way. I just don't know how.

public boolean sideVisible(Vector3D normal){
    if (translate(normal).getX()>0) {
        return true;
    }else{
        return false;
    }
}
like image 284
Johan Wikström Avatar asked Nov 04 '22 23:11

Johan Wikström


1 Answers

Take the dot-product of the view-vector (imagine an arrow coming out of the camera) and the surface normal. If it's negative, then the face is visible.

(Edit: you'll want to do these calculations in world-space, that is following the model to world transformation)

like image 109
horatius83 Avatar answered Nov 13 '22 16:11

horatius83