title: Rendering 3D objects on 2D Canvas using Java AWT
body: <p>I'm trying to port this <a href="https://www.basedesign.com/blog/how-to-render-3d-in-2d-canvas" rel="nofollow noreferrer">JS code</a> on Java because I got bored with programming a prototype of my 2D Java Game and I wanted to make my game into 3D, then I got this weird rendering bug, I think my math or logic was off...</p>
  <p><a href="https://i.stack.imgur.com/jwckY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/jwckY.png" alt="enter image description here" /></a></p>
  <p><strong>Sample data:</strong></p>
  <pre><code>Cube: x = 79.78739, y = 102.75975, z = -42.678993
  
  1: x = 31.787392, y = 54.75975, z = -90.67899
  2: x = 127.78739, y = 54.75975, z = -90.67899
  
  1 Project: x = 359.64944, y = 339.39612
  2 Project: x = 358.59076, y = 339.39612
  
  1: x = 127.78739, y = 54.75975, z = -90.67899
  2: x = 127.78739, y = 150.75975, z = -90.67899
  
  1 Project: x = 358.59076, y = 339.39612
  2 Project: x = 358.59076, y = 338.33743
  
  1: x = 127.78739, y = 150.75975, z = -90.67899
  2: x = 31.787392, y = 150.75975, z = -90.67899
  
  1 Project: x = 358.59076, y = 338.33743
  2 Project: x = 359.64944, y = 338.33743
  
  1: x = 31.787392, y = 150.75975, z = -90.67899
  2: x = 31.787392, y = 54.75975, z = -90.67899
  
  1 Project: x = 359.64944, y = 338.33743
  2 Project: x = 359.64944, y = 339.39612
  
  1: x = 31.787392, y = 150.75975, z = -90.67899
  2: x = 31.787392, y = 150.75975, z = 5.321007
  
  1 Project: x = 359.64944, y = 338.33743
  2 Project: x = 365.97394, y = 368.33295
  
  1: x = 127.78739, y = 150.75975, z = -90.67899
  2: x = 127.78739, y = 150.75975, z = 5.321007
  
  1 Project: x = 358.59076, y = 338.33743
  2 Project: x = 384.01562, y = 368.33295
  
  1: x = 31.787392, y = 54.75975, z = -90.67899
  2: x = 31.787392, y = 54.75975, z = 5.321007
  
  1 Project: x = 359.64944, y = 339.39612
  2 Project: x = 365.97394, y = 350.29123
  
  1: x = 127.78739, y = 54.75975, z = -90.67899
  2: x = 127.78739, y = 54.75975, z = 5.321007
  
  1 Project: x = 358.59076, y = 339.39612
  2 Project: x = 384.01562, y = 350.29123
  
  1: x = 31.787392, y = 150.75975, z = 5.321007
  2: x = 127.78739, y = 150.75975, z = 5.321007
  
  1 Project: x = 365.97394, y = 368.33295
  2 Project: x = 384.01562, y = 368.33295
  
  1: x = 31.787392, y = 150.75975, z = 5.321007
  2: x = 31.787392, y = 54.75975, z = 5.321007
  
  1 Project: x = 365.97394, y = 368.33295
  2 Project: x = 365.97394, y = 350.29123
  
  1: x = 127.78739, y = 150.75975, z = 5.321007
  2: x = 127.78739, y = 54.75975, z = 5.321007
  
  1 Project: x = 384.01562, y = 368.33295
  2 Project: x = 384.01562, y = 350.29123
  
  1: x = 31.787392, y = 54.75975, z = 5.321007
  2: x = 127.78739, y = 54.75975, z = 5.321007
  
  1 Project: x = 365.97394, y = 350.29123
  2 Project: x = 384.01562, y = 350.29123
  </code></pre>
  <p><strong>Legend:</strong></p>
  <p><strong>Cube:</strong> the actual cube, has a transform of x, y, z</p>
  <p><strong>1</strong> and <strong>2:</strong> I don't get this part, it's like traces the lines and vertices of the cube</p>
  <p>Plotting <strong>1</strong> and <strong>2</strong> returns this:
  <a href="https://i.stack.imgur.com/Z8nRi.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Z8nRi.png" alt="enter image description here" /></a></p>
  <p><strong>1 Project</strong> and <strong>2 Project:</strong> The lines to be drawn I think (1 Project is the starting point, 2 Project is the endpoint)</p>
  <p>Plotting <strong>1 Project</strong> and <strong>2 Project</strong> returns this:
  <a href="https://i.stack.imgur.com/3XMtR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3XMtR.png" alt="enter image description here" /></a></p>
  <p><strong>The code:</strong></p>
  <pre><code>public class JavaTestClassForStackoverflow {
      // dimension
      public static int WIDTH = 720, HEIGHT = 1360/2;
      // 3D stuff
      float PROJECTION_CENTER_X = WIDTH / 2f;
      float PROJECTION_CENTER_Y = HEIGHT / 2f;
      float FIELD_OF_VIEW = WIDTH * 0.8f;
      // cube const
      int[][] CUBE_LINES = {{0, 1}, {1, 3}, {3, 2}, {2, 0}, {2, 6}, {3, 7}, {0, 4}, {1, 5}, {6, 7}, {6, 4}, {7, 5}, {4, 5}};
      int[][] CUBE_VERTICES = {{-1, -1, -1}, {1, -1, -1}, {-1, 1, -1}, {1, 1, -1}, {-1, -1, 1}, {1, -1, 1}, {-1, 1, 1}, {1, 1, 1}};
  
      class Cube {
          public float x, y, z, radius;
  
          public Cube(){
              x = (float)((Math.random() - 0.5) * WIDTH);
              y = (float)((Math.random() - 0.5) * WIDTH);
              z = (float)((Math.random() - 0.5) * WIDTH);
              radius = (float)(Math.floor(Math.random() * 100 + 10));
          }
  
          class v {
              public float x;
              public float y;
              public float z;
  
              public v(float x, float y, float z){
                  this.x = x;
                  this.y = y;
                  this.z = z;
              }
          }
  
          public void tick(){}
  
          public v project(float x, float y, float z){
              float scaleProjected = FIELD_OF_VIEW / (FIELD_OF_VIEW * z);
              float xProjected = (x * scaleProjected) + PROJECTION_CENTER_X;
              float yProjected = (y * scaleProjected) + PROJECTION_CENTER_Y;
  
              return new v(xProjected, yProjected, scaleProjected);
          }
          public void render(Graphics g){
              if (z &lt; - FIELD_OF_VIEW + radius)
                  return;
  
              System.out.println(&quot;Cube: x = &quot; + x + &quot;, y = &quot; + y + &quot;, z = &quot; + z + &quot;\n&quot;);
  
              for (int i = 0; i &lt; CUBE_LINES.length; i++){
  
                  v v1 = new v(x + (radius * CUBE_VERTICES[CUBE_LINES[i][0]][0]),
                               y + (radius * CUBE_VERTICES[CUBE_LINES[i][0]][1]),
                               z + (radius * CUBE_VERTICES[CUBE_LINES[i][0]][2]));
  
                  v v2 = new v(x + (radius * CUBE_VERTICES[CUBE_LINES[i][1]][0]),
                               y + (radius * CUBE_VERTICES[CUBE_LINES[i][1]][1]),
                               z + (radius * CUBE_VERTICES[CUBE_LINES[i][1]][2]));
  
                  System.out.println(&quot;1: x = &quot; + v1.x + &quot;, y = &quot; + v1.y + &quot;, z = &quot; + v1.z);
                  System.out.println(&quot;2: x = &quot; + v2.x + &quot;, y = &quot; + v2.y + &quot;, z = &quot; + v2.z + &quot;\n&quot;);
  
                  v v1Project = project(v1.x, v1.y, v1.z);
                  v v2Project = project(v2.x, v2.y, v2.z);
  
                  System.out.println(&quot;1 Project: x = &quot; + v1Project.x + &quot;, y = &quot; + v1Project.y);
                  System.out.println(&quot;2 Project: x = &quot; + v2Project.x + &quot;, y = &quot; + v2Project.y + &quot;\n&quot;);
  
                  g.setColor(Color.GREEN);
                  g.drawLine((int)v1Project.x, (int)v1Project.y, (int)v2Project.x, (int)v2Project.y);
              }
          }
      }
  }
  </code></pre>