# Camera: How top down view

**URL:** https://discourse.processing.org/t/camera-how-top-down-view/1178
**Category:** Beginners
**Created:** [June 23, 2018, 8:46am UTC](https://discourse.processing.org/t/camera-how-top-down-view/1178 "2018-06-23T08:46:47Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [June 23, 2018, 8:46am UTC](https://discourse.processing.org/t/camera-how-top-down-view/1178/1 "2018-06-23T08:46:47Z")

</div>

Hello,

it is well known that

```auto
camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0), 
width/2.0, height/2.0, 0, 
0, 1, 0);

```

delivers the normal view.

I am trying to implement a top down view:

My best guess is

```auto
    camera(0, -1200, 0, 
      0, 0, 0, 
      0, 0, -1);

```

So the camera is very high above (0, -1200, 0) the scene, looking straight down (0,0,0).

My question is about the 3 last, the UP parameters. I have 0,0,-1 there hoping that means “look straight down with neg. z-axis is up”. Is that correct?

(My goal: Let’s say the camera standard front view looks toward north at a house with a car on the right. Then you want the top view in a way that the car is still right from the car (and north is at the top of the screen and not left or right) )

Are my assumptions and my camera parameters correct?

Thanks!

Best, Chrisir 😉

---

<div class="post-metadata">

### Author: ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)
#### Post date: [June 23, 2018, 11:16am UTC](https://discourse.processing.org/t/camera-how-top-down-view/1178/2 "2018-06-23T11:16:52Z")

</div>

By default the Z axis point toward the top of the screen.  
After trying an understanding the camera parameters, I think that you have to set the Z upward axis to 1 :

```auto
void setup() {
  size(400, 400, P3D);
  stroke(255, 0, 0);
  lights();
}

void draw() {
  background(0);
  lights();

  if (mousePressed) {
    camera(width/2, height/2-1200, 0, width/2, height/2, 0, 0, 0, 1);
  } else {
    camera();
  }

  translate(width/2, height/2, 0);
  fill(255);
  box(100);
  translate(100, 0, 0);
  fill(255, 0, 0);
  box(50);
  translate(-200, 0, 0);
  fill(0, 255, 0);
  box(50);
  translate(100, -100, 0);
  fill(0, 0, 255);
  box(50);
}

```

![camera_simple](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/1X/61f03859ee85a1a1f21c5c1f902ca94b5078a404.png) ![camera_changed](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/1X/9397012816251d71e1da2366fa3fdfa8ce62d438.png)

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [June 23, 2018, 1:13pm UTC](https://discourse.processing.org/t/camera-how-top-down-view/1178/3 "2018-06-23T13:13:27Z")

</div>

Excellent

thank you so much

New version with key input 0…4 for 5 different views

Chrisir

```auto

// default values are camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0), width/2.0, height/2.0, 0, 0, 1, 0).

int viewMode=3; 
String[] viewText={
  "top view", 
  "from north", 
  "from east", 
  "from south (processing default)", 
  "from west"
};

void setup() {
  size(1400, 400, P3D);
  stroke(255, 0, 0);
  // stroke(111); 
  lights();
}

void draw() {
  background(0);
  lights();

  if (!mousePressed) {

    switch (viewMode) {

    case 0:
      // top down 
      camera(width/2, height/2-400, 0, 
        width/2, height/2, 0, 
        0, 0, 1);
      break; 

    case 1: 
      //from north 
      camera(width/2, height/2, -400, 
        width/2, height/2, 0, 
        0, 1, 0);
      break; 

    case 2: 
      //from east 
      camera(width/2+500, height/2, 0, 
        width/2, height/2, 0, 
        0, 1, 0);
      break; 

    case 3:
      //from south // default 
      camera();
      break; 

    case 4:
      //from west 
      camera(width/2-500, height/2, 0, 
        width/2, height/2, 0, 
        0, 1, 0);
      break;
    default:
      println("error 55 in switch");
      exit();
      return;
    }//switch 
    //
  } else {
    // default (from south)  
    camera();
  }

  translate(width/2, height/2, 0);

  fill(255); //white 
  box(100); // big box 

  translate(100, 0, 0); // right 
  fill(255, 0, 0); // red 
  box(50);

  translate(-200, 0, 0); // left
  fill(0, 255, 0); // green 
  box(50);

  translate(100, -100, 0); // center above 
  fill(0, 0, 255); // blue 
  box(50);

  camera();
  fill(255);
  text("Camera test: Hit 0..4 for top view / north / east / south / west view. "
    +"\nClick and hold mouse to see processing default view."
    +"\nCurrent view: "
    +viewText[viewMode], 
    15, 15);
}

void keyPressed() {
  if (key>='0'&&key<='4') {
    viewMode=int(key+"");
  }
}
//

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [June 23, 2018, 2:32pm UTC](https://discourse.processing.org/t/camera-how-top-down-view/1178/4 "2018-06-23T14:32:40Z")

</div>

This sketch is based on the following assumptions:

- in 3D the scene is on a table. So placing things left and right on the table is `x`, placing it more in front or in the back is `Z` and placing it above the scene (blue box) is `Y`

- The center of the scene is at `width/2, height/2, 0`

Chrisir

---

<div class="post-metadata">

### Author: ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)
#### Post date: [June 23, 2018, 3:41pm UTC](https://discourse.processing.org/t/camera-how-top-down-view/1178/5 "2018-06-23T15:41:23Z")

</div>

Thanks for your answer @Chrisir have a nice day !

😉

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [June 23, 2018, 5:54pm UTC](https://discourse.processing.org/t/camera-how-top-down-view/1178/6 "2018-06-23T17:54:17Z")

</div>

New version with `class Carmera` and a smoother transition between the different views (`lerp()`)

```auto

/*

 New version with camera class AND smooth transitions (damping) ============================================================
 
 This sketch is based on the following assumptions:
 * in 3D the scene is on a table. So placing things left and right on the table is x, placing it more in front or in the back is Z and placing it above the scene (blue box) is Y
 * The center of the scene is at width/2, height/2, 0
 
 https://discourse.processing.org/t/camera-how-top-down-view/1178/3
 
 */

// demonstrates view from top down (above the sceen), 
// and from north, east, south and west. 

// The interesting part: the UP-vector when view from top.  

// default values are 
// camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0),
// width/2.0, height/2.0, 0, 
// 0, 1, 0).

CameraMy cam;  

// view mode and its texts  
int viewMode=3; 
String[] viewText={
  "top view", 
  "from north", 
  "from east", 
  "from south (processing default)", 
  "from west"
};

void setup() {
  size(1400, 400, P3D);
  stroke(255, 0, 0);
  cam = new CameraMy();
}

void draw() {
  background(0);
  lights();

  if (!mousePressed) {
    // apply view mode
    cam.apply();
    //
  } else {
    // default (from south)  
    camera();
  }//else 

  // draw scene 
  drawScene();

  // HUD : text
  camera();
  fill(255);
  text("Camera test: Hit 0..4 for top view / north / east / south / west view. "
    +"\nClick and hold mouse to see processing default view."
    +"\nCurrent view: "
    +viewText[viewMode], 
    15, 15);
}//func

// ---------------------------------------------------------------------------

void setViewFromViewMode() {

  switch (viewMode) {

  case 0:
    // top down 
    cam.setEye(width/2, height/2-400, 0); 
    cam.setUpVector(0, 0, 1); 
    cam.apply();
    break; 

  case 1: 
    //from north 
    cam.setEye(width/2, height/2, -400); 
    cam.setUpVectorToStandard();
    cam.apply(); 
    break; 

  case 2: 
    //from east 
    cam.setEye(width/2+500, height/2, 0); 
    cam.setUpVectorToStandard();
    cam.apply(); 
    break; 

  case 3:
    //from south // default 
    cam.reset();
    cam.apply(); 
    break; 

  case 4:
    //from west 
    cam.setEye(width/2-500, height/2, 0); 
    cam.setUpVectorToStandard();
    cam.apply(); 
    break;

  default:
    println("error 55 in switch");
    exit();
    return;
  }//switch
}//func 

void drawScene() {
  translate(width/2, height/2, 0);

  fill(255); //white 
  box(100); // big box 

  translate(100, 0, 0); // right 
  fill(255, 0, 0); // red 
  box(50);

  translate(-200, 0, 0); // left
  fill(0, 255, 0); // green 
  box(50);

  translate(100, -100, 0); // center above 
  fill(0, 0, 255); // blue 
  box(50);

  translate(0, 100, 100); // center above 
  fill(0, 0, 255); // blue 
  noStroke(); 
  sphere(12);

  translate(0, 0, -200); // center above 
  fill(0, 255, 0); // green 
  noStroke(); 
  sphere(12);
}

void keyPressed() {
  if (key>='0'&&key<='4') {
    viewMode=int(key+"");
    setViewFromViewMode();
  }
}
//===========================================================

class CameraMy {

  // standards
  final PVector eyePV_Standard = new PVector ( width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0)); // eye = camera position 
  final PVector lookAtPV_Standard = new PVector ( width/2, height/2, 0 ); // look At or center
  final PVector upPV_Standard = new PVector ( 0, 1, 0); // the up vector for rotating the camera around itself 

  // the changing values: 
  PVector eyePV, lookAtPV, upPV;

  // old PVectors
  PVector eyePVold, lookAtPVold, upPVold;

  // for lerp
  float amt = 0;

  // constr 
  CameraMy() {
    eyePV = eyePV_Standard.copy(); 
    lookAtPV = lookAtPV_Standard.copy();
    upPV = upPV_Standard.copy();

    eyePVold = eyePV.copy(); 
    lookAtPVold = lookAtPV.copy();
    upPVold = upPV.copy();
  }//constr 

  // -----

  void setEye( float x, float y, float z) {
    eyePVold=eyePV.copy(); 
    eyePV=new PVector(x, y, z);
    amt=0;
  }
  void setLookAt( float x, float y, float z) {
    lookAtPVold=lookAtPV.copy();
    lookAtPV=new PVector(x, y, z);
    amt=0;
  }
  void setUpVector( float x, float y, float z) {
    upPVold=upPV.copy();
    // set UP vector 
    upPV=new PVector(x, y, z);
    amt=0;
  }

  // ----

  void setEyeToStandard() {
    eyePVold=eyePV.copy(); 
    eyePV = eyePV_Standard.copy();
    amt=0;
  }
  void setLookAtToStandard() {
    lookAtPVold=lookAtPV.copy();
    lookAtPV = lookAtPV_Standard.copy();
    amt=0;
  }
  void setUpVectorToStandard() {
    upPVold=upPV.copy();
    upPV = upPV_Standard.copy();
    amt=0;
  }

  // ----

  void reset() {
    // reset 
    // store old values 
    eyePVold=eyePV.copy(); 
    lookAtPVold=lookAtPV.copy();
    upPVold=upPV.copy();
    // reset 
    eyePV = eyePV_Standard.copy(); 
    lookAtPV = lookAtPV_Standard.copy();
    upPV = upPV_Standard.copy();
    // set amt to 0 for lerp
    amt=0;
  }

  // ----

  void apply() {

    // apply values

    // we don't use the new values (eyePV,lookAtPV,upPV) directly but with eyePVold etc. and lerp   

    PVector eyePV2, lookAtPV2, upPV2;

    eyePV2 = lerpPV ( eyePVold, eyePV, amt );
    lookAtPV2 = lerpPV ( lookAtPVold, lookAtPV, amt );
    upPV2 = lerpPV ( upPVold, upPV, amt );

    if (amt<1)
      amt+=.05;
    else 
    amt = 1.0; 

    camera (eyePV2.x, eyePV2.y, eyePV2.z, 
      lookAtPV2.x, lookAtPV2.y, lookAtPV2.z, 
      upPV2.x, upPV2.y, upPV2.z);
  }//method

  PVector lerpPV(PVector pvOld, PVector pvNew, float amt) {

    PVector result;

    // lerp: 
    float x = lerp(pvOld.x, pvNew.x, amt);
    float y = lerp(pvOld.y, pvNew.y, amt);
    float z = lerp(pvOld.z, pvNew.z, amt);

    result = new PVector ( x, y, z ); 

    return result;
  }
  //
}//class 
//

```
