title: libGDX - perspective camera and field of view
body: <p>I have problems to understand the field of view of the perspective camera in libGDX (or maybe my calculations are wrong).</p>
  
  <p>I want to draw a box (for example 800px wide, 480px high and 20px deep). The box is placed between x- and y-axis (in other words: the width on x-axis and the height on y-axis). Now I want to stand behind the box on the x-axis (camera position) and look in a direction in such a way that I see the box on my very right screen side. 
  I made some sketches:</p>
  
  <p><img src="https://i.stack.imgur.com/rIMRr.png" alt="drawing the box"></p>
  
  <p><img src="https://i.stack.imgur.com/3fPnJ.png" alt="camera on x-axis, looking at box"></p>
  
  <p><img src="https://i.stack.imgur.com/msfNd.png" alt="box should appear on right side"></p>
  
  <p>On the last sketch, the box is on the right side of the field of view.</p>
  
  <p>Moreover, the height of the box must fit exactly in the screen. In other words: the top edge of the box must be on my screen top and the bottom edge of the box must be on my screen bottom.
  Here is some code and calculations to achieve this:</p>
  
  <pre><code>public class Box implements ApplicationListener {
  
  public PerspectiveCamera camera;
  public float SCREEN_WIDTH;   
  public float SCREEN_HEIGHT; 
  
  @Override
  public void create() {
      SCREEN_WIDTH = Gdx.graphics.getWidth(); // 800px
      SCREEN_HEIGHT = Gdx.graphics.getHeight(); // 480px
  
      // Create camera (90°) and set position
      camera = new PerspectiveCamera(90f, SCREEN_WIDTH, SCREEN_HEIGHT);
      camera.position.set(SCREEN_WIDTH + SCREEN_HEIGHT/2, SCREEN_HEIGHT/2, 0f);
      camera.lookAt(0f, SCREEN_HEIGHT/2, 0f);
      camera.near = 1;
      camera.far = 2 * SCREEN_WIDTH;
      camera.update();
  }
  
  @Override
  public void render() {
      Gdx.gl.glClearColor(Color.WHITE.r, Color.WHITE.g, Color.WHITE.b, Color.WHITE.a);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); 
  
      // Build the box - width is screenwidth and height is screenheight - one corner in origin
      ModelBuilder modelBuilder = new ModelBuilder(); 
      modelBuilder.begin();
      MeshPartBuilder mpb = modelBuilder.part("ID", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal,
              new Material(ColorAttribute.createDiffuse(Color.GREEN)));
      // bottom left corner of the box should be in (0,0,0)
      mpb.box(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, -10f, SCREEN_WIDTH, SCREEN_HEIGHT, 20f);
      Model model = modelBuilder.end();
      ModelInstance instance = new ModelInstance(model);
  
      // Build some light
      Environment environment = new Environment();
      environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
      environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
  
      // Draw the box
      ModelBatch modelBatch = new ModelBatch();
      modelBatch.begin(camera);
      modelBatch.render(instance, environment);
      modelBatch.end();
  }
  }
  </code></pre>
  
  <p>To fit the box height in the screen I must step back SCREEN_HEIGHT/2, because x = SCREEN_HEIGHT/2 / tan(45°) = SCREEN_HEIGHT/2 / 1 = SCREEN_HEIGHT/2, that's why I added this length to the x-component in the position setting.</p>
  
  <p>The code represents sketch 2 and give me that correct screenshot:</p>
  
  <p><img src="https://i.stack.imgur.com/MmJ1K.png" alt="screenshot of sketch 2"></p>
  
  <p>In order to achieve sketch 3, I must rotate my field of view about 45° to the left. But in this connection I must step back a little, because the sides of the field of view are longer than the centerline. I made two hand-drawn sketches:</p>
  
  <p><img src="https://i.stack.imgur.com/aG4tO.jpg" alt="rotation of field of view"></p>
  
  <p>Where h = SCREEN_HEIGHT. First of all, I have to compute x. x = h/2 / sin(45°) = h/sqrt(2). Now I must step back a length of x and look in a new direction (45° left from box). To calculate the point at which I will looking, I calculate the length y on this sketch:</p>
  
  <p><img src="https://i.stack.imgur.com/7Ja9n.jpg" alt="calculation y"></p>
  
  <p>y = sin(45°) * h/2 = h * sqrt(2)/4. So, the point is for example (SCREEN_WIDTH + (x-y), SCREEN_HEIGHT/2, y). Now I change the position and looking point in my code:</p>
  
  <pre><code>public void create() {
      SCREEN_WIDTH = Gdx.graphics.getWidth(); // 800px
      SCREEN_HEIGHT = Gdx.graphics.getHeight(); // 480px
  
      // Create camera (90°) and set position
      camera = new PerspectiveCamera(90f, SCREEN_WIDTH, SCREEN_HEIGHT);
      float x = (float) (SCREEN_HEIGHT / Math.sqrt(2));
      float y = (float) (SCREEN_HEIGHT * Math.sqrt(2)/4f);
      camera.position.set(SCREEN_WIDTH + x, SCREEN_HEIGHT/2, 0f);
      camera.lookAt(SCREEN_WIDTH + x - y, SCREEN_HEIGHT/2, y);
      camera.near = 1;
      camera.far = 2 * SCREEN_WIDTH;
      camera.update();
  }
  </code></pre>
  
  <p>And I get this screen:</p>
  
  <p><img src="https://i.stack.imgur.com/ihn87.png" alt="screenshot which should represent sketch 3"></p>
  
  <p>But the box isn't on the very right side :(</p>
  
  <p>So now the question: what is wrong? Is my thinking of the field of view wrong or my calculations? </p>
  
  <p>Best regards!</p>