# 3D camera rotation

**URL:** <https://discourse.processing.org/t/3d-camera-rotation/23742>\
**Category:** Coding Questions\
**Created:** [September 8, 2020, 4:24pm UTC](https://discourse.processing.org/t/3d-camera-rotation/23742 "2020-09-08T16:24:41Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kport1](https://avatars.discourse-cdn.com/v4/letter/k/278dde/32.png) [@Kport1](https://discourse.processing.org/u/Kport1)\
**Post date:** [September 8, 2020, 4:24pm UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/1 "2020-09-08T16:24:41Z")

</div>

Hello! im trying to create a 3D camera that rotates when mouse is dragged.  
I created something that works, but the movement feels very strange.  
Here’s my code:

```auto
Planet p = new Planet(new PVector(width / 2, height / 2, 100), 15);

PVector camPos = new PVector(width / 2, height / 2, 0);
PVector camDir = new PVector(width / 2, height / 2, 100);

float aYZ = 0;
float aXZ = 0;

void setup() {
  size(900, 900, P3D);

  perspective(PI / 2, float(width) / float(height), 0.1, 1000000);
}

void draw() {
  background(0);

  float camDirX = 100 * sin(aYZ) * cos(aXZ) + camPos.x;
  float camDirY = 100 * sin(aYZ) * sin(aXZ) + camPos.y;
  float camDirZ = 100 * cos(aYZ) + camPos.z;

  camDir = new PVector(camDirX, camDirY, camDirZ);

  println(sin(aYZ));

  camera(camPos.x, camPos.y, camPos.z, camDir.x, camDir.y, camDir.z, 0, 1, 0);

  if (keyPressed) {
    if (key == 'w') {
      camPos = camPos.add(camDir.copy().sub(camPos).normalize());
      camDir = camDir.add(camDir.copy().sub(camPos).normalize());
    } else if (key == 's') {
      camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(-1));
      camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(-1));
    }
  }

  p.show();
}

void mouseDragged() {
  float dx = mouseX - pmouseX;
  float dy = mouseY - pmouseY;

  aXZ += dy / 100;
  aYZ += dx / 100;
}

```

there is also a Planet and Body3D class:

```auto
class Body3D{
  PVector pos;
  PVector vel = new PVector(0,0,0);
  PVector acc = new PVector(0,0,0);
  
  float m;
  
  void applyAcc(PVector acc_){
    acc = acc.add(acc_);
  }
  
  void update(){
    vel = vel.add(acc);
    pos = pos.add(vel);
    
    acc = new PVector(0,0,0);
    
  }
}

```

```auto
class Planet extends Body3D{
  
  
  Planet(PVector pos_, float m_){
    this.pos = pos_;
    this.m = m_;
  }
  
  
  void show(){
    lights();
    noStroke();
    fill(255);
    translate(pos.x,pos.y,pos.z);
    sphere(this.m * 1.3);
  }
}

```

Thanks!

---

<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:** [September 8, 2020, 7:11pm UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/2 "2020-09-08T19:11:43Z")

</div>

> [@Kport1](#):
>
> `camera(camPos.x, camPos.y, camPos.z,`

1. 

center in 3D is 0,0,0, NOT width/2 height/2

1. 

When your planet is in the center and you want to rotate the cam around it, the `camDir` stays fixed at 0,0,0; and camPos rotates around the planet

1. 

there is a nice trigonometry primer in the tutorials : [Tutorials / Processing.org](https://www.processing.org/tutorials/)

* * *

**Edit: Example**

```auto

Planet p = new Planet(new PVector(0, 0, 0), 15);
Planet p2 = new Planet(new PVector(110, 0, 110), 43);

PVector camPos = new PVector(0, 9, 0);
PVector camDir = new PVector(0, 0, 0);

void setup() {
  size(900, 900, P3D);
  perspective(PI / 2, float(width) / float(height), 0.1, 1000000);
}

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

  float angle = map (mouseX, 
    0, width, 
    -PI, TWO_PI); 

  camPos = new PVector( 700 * cos( angle ) + camDir.x, 
    map(mouseY, 0, height, -1333, 1333), 
    700 * sin( angle ) + camDir.z);

  camera( camPos.x, camPos.y, camPos.z, 
    camDir.x, camDir.y, camDir.z, 
    0, 1, 0);

  if (keyPressed) {
    if (key == 'w') {
      // camPos = camPos.add(camDir.copy().sub(camPos).normalize());
      camDir = camDir.add(camDir.copy().sub(camPos).normalize());
    } else if (key == 's') {
      // camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(-1));
      camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(-1));
    }
  }

  p.show();
  p2.show();

  camera();
  noLights();
  fill(255);
  textSize(19);
  textMode(SHAPE);
  text("height of cam is "+ str( map(mouseY, 0, height, -1333, 1333)), 
    -117, -117);
}

void mouseDragged() {
  //float dx = mouseX - pmouseX;
  //float dy = mouseY - pmouseY;

  //aXZ += dy / 100;
  //aYZ += dx / 100;
}
//---------------------------------------------------------------

class Planet extends Body3D {

  Planet(PVector pos_, float m_) {
    this.pos = pos_;
    this.m = m_;
  }

  void show() {
    lights();
    noStroke();
    fill(255);
    translate(pos.x, pos.y, pos.z);
    sphere(this.m * 1.3);
  }
}

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

class Body3D {
  PVector pos;
  PVector vel = new PVector(0, 0, 0);
  PVector acc = new PVector(0, 0, 0);

  float m;

  void applyAcc(PVector acc_) {
    acc = acc.add(acc_);
  }

  void update() {
    vel = vel.add(acc);
    pos = pos.add(vel);

    acc = new PVector(0, 0, 0);
  }
}

```

---

<div class="post-metadata">

**Author:** ![Kport1](https://avatars.discourse-cdn.com/v4/letter/k/278dde/32.png) [@Kport1](https://discourse.processing.org/u/Kport1)\
**Post date:** [September 10, 2020, 8:48am UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/3 "2020-09-10T08:48:03Z")

</div>

thanks! But im trying to rotate the camera around its own axis and not around a object on the canvas. Like pressing the Left arrow will rotate the camera left, but with the mouse

---

<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:** [September 10, 2020, 12:34pm UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/4 "2020-09-10T12:34:51Z")

</div>

I see.

My formula is correct just swap position and lookAt

---

<div class="post-metadata">

**Author:** ![Kport1](https://avatars.discourse-cdn.com/v4/letter/k/278dde/32.png) [@Kport1](https://discourse.processing.org/u/Kport1)\
**Post date:** [September 11, 2020, 1:27pm UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/5 "2020-09-11T13:27:35Z")

</div>

yes. I know camDir must rotate, but i dont know how to translate mouse movement into this rotation.

---

<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:** [September 11, 2020, 1:43pm UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/6 "2020-09-11T13:43:14Z")

</div>

It’s really just like in my code

map mouse to angle and use this angle

Coming from my code swap cam pos and  
cam lookAt

---

<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:** [September 12, 2020, 8:42am UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/7 "2020-09-12T08:42:00Z")

</div>

I am sorry, I didn’t post my Sketch above.

I posted it now

cam is moving around center here

---

<div class="post-metadata">

**Author:** ![Kport1](https://avatars.discourse-cdn.com/v4/letter/k/278dde/32.png) [@Kport1](https://discourse.processing.org/u/Kport1)\
**Post date:** [September 12, 2020, 9:54am UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/8 "2020-09-12T09:54:45Z")

</div>

Thx. This is great, but is it possible to have the y coordinate be a circle too? So you can keep looking up and then eventually come bak to where you were.

---

<div class="post-metadata">

**Author:** ![Kport1](https://avatars.discourse-cdn.com/v4/letter/k/278dde/32.png) [@Kport1](https://discourse.processing.org/u/Kport1)\
**Post date:** [September 12, 2020, 10:01am UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/9 "2020-09-12T10:01:31Z")

</div>

Right now the camDir has a maximum and minimum y coordinate, but in space there would not be a up or down, so the camera sould be able to rotate freely in every direction.

---

<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:** [September 12, 2020, 10:25am UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/10 "2020-09-12T10:25:17Z")

</div>

That’s true

I don’t know how to do this ad hoc

we have to ask one of the gurus

could you post your entire code to help them please?

---

<div class="post-metadata">

**Author:** ![Kport1](https://avatars.discourse-cdn.com/v4/letter/k/278dde/32.png) [@Kport1](https://discourse.processing.org/u/Kport1)\
**Post date:** [September 12, 2020, 11:40am UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/11 "2020-09-12T11:40:24Z")

</div>

I just addes some code for gravity wich also doesnt work… pls help

```auto
ArrayList<Planet> planets = new ArrayList<Planet>();

PVector camPos = new PVector(0, 0, 100);
PVector camDir = new PVector(0, 0, 0);

float aYZ = 0;
float aXZ;

float G = 0.01;

void setup() {
  size(900, 900, P3D);

  perspective(PI / 2, float(width) / float(height), 0.1, 1000000);

  aXZ = height / 2;

  planets.add(new Planet(new PVector(100, 0, 0), 5));
  planets.add(new Planet(new PVector(0, 100, 0), 5));
}

void draw() {
  background(0);

  if (aXZ > height) {
    aXZ = height;
  } else if (aXZ < 0) {
    aXZ = 0;
  }

  float angle = map (aYZ, 0, width, -PI, TWO_PI); 

  float camDirX = 700 * cos(angle) + camPos.x;
  float camDirY = map(aXZ, 0, height, -1333, 1333);
  float camDirZ = 700 * sin(angle) + camPos.z;

  camDir = new PVector(camDirX, camDirY, camDirZ);

  camera(camPos.x, camPos.y, camPos.z, camDir.x, camDir.y, camDir.z, 0, 1, 0);

  for (Planet p : planets) {
    p.show();
  }

  for (Planet b1 : planets) {
    for (Planet b2 : planets) {
      if (b1 != b2) {

        float r = dist(b1.pos.x, b1.pos.y, b1.pos.z, b2.pos.x, b2.pos.y, b2.pos.z);

        PVector p1 = new PVector(b2.pos.x, b2.pos.y, b2.pos.z);
        PVector p2 = new PVector(b1.pos.x, b1.pos.y, b1.pos.z);

        p1 = p1.sub(b1.pos);
        p2 = p2.sub(b2.pos);

        float a = G * ((b1.m * b2.m) / (r * r));

        b1.applyAcc(p1.mult(a).mult(1));
        b2.applyAcc(p2.mult(a).mult(1));
      }
    }
  }

  for (Planet p : planets) {
    p.update();
  }

  if (keyPressed) {
    if (key == 'w') {
      camPos = camPos.add(camDir.copy().sub(camPos).normalize());
      camDir = camDir.add(camDir.copy().sub(camPos).normalize());
    } else if (key == 's') {
      camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(-1));
      camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(-1));
    }
  }
}

void mouseDragged() {
  float dx = mouseX - pmouseX;
  float dy = mouseY - pmouseY;

  aXZ += dy / 1;
  aYZ += dx / 1;
}

```

```auto
class Body3D {
  PVector pos;
  PVector vel = new PVector(0, 0, 0);
  PVector acc = new PVector(0, 0, 0);

  float m;

  void applyAcc(PVector acc_) {
    acc = acc.add(acc_);
    
    strokeWeight(10);
    stroke(255);
    point(acc.x * 50 + pos.x,acc.y * 50 + pos.y,acc.z * 50 + pos.z);
  }

  void update() {
    vel = vel.add(acc.div(m));
    acc = new PVector(0, 0, 0);
    pos = pos.add(vel);
  }
}

```

```auto
class Planet extends Body3D{
  
  
  Planet(PVector pos_, float m_){
    this.pos = pos_;
    this.m = m_;
  }
  
  
  void show(){
    lights();
    noStroke();
    fill(255);
    translate(pos.x,pos.y,pos.z);
    sphereDetail(60);
    sphere(this.m * 1.3);
  }
}

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [September 12, 2020, 11:05pm UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/12 "2020-09-12T23:05:05Z")

</div>

This is a good resource for coding forces:  
[https://natureofcode.com/book/](https://natureofcode.com/book/)

`:)`

---

<div class="post-metadata">

**Author:** ![Kport1](https://avatars.discourse-cdn.com/v4/letter/k/278dde/32.png) [@Kport1](https://discourse.processing.org/u/Kport1)\
**Post date:** [September 13, 2020, 8:22am UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/13 "2020-09-13T08:22:08Z")

</div>

I have done this before in 2d, but after copy pasting the code into 3d it didnt work

---

<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:** [September 14, 2020, 7:58pm UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/14 "2020-09-14T19:58:22Z")

</div>

cam rotates around itself now, but y still traditional

```auto

// cam rotates around ITSELF  
// Looking at center 

Planet p = new Planet(new PVector(0, 0, 0), 15);
Planet p2 = new Planet(new PVector(110, 0, -110), 13);
Planet p3 = new Planet(new PVector(210, 0, -110), 13);

final PVector camPos = new PVector(333, 9, 333);
PVector camDir = new PVector(0, 0, 0);

void setup() {
  size(900, 900, P3D);
  perspective(PI / 2, float(width) / float(height), 0.1, 1000000);
}

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

  float angle = map (mouseX, 
    0, width, 
    -PI, TWO_PI); 

  camDir = new PVector( 1200 * cos( angle ) + 0, 
    map(mouseY, 0, height, -1333, 1333), 
    1200 * sin( angle ) + 0);

  camera( camPos.x, camPos.y, camPos.z, 
    camDir.x, camDir.y, camDir.z, 
    0, 1, 0);

  if (keyPressed) {
    if (key == 'w') {
      // camPos = camPos.add(camDir.copy().sub(camPos).normalize());
      camDir = camDir.add(camDir.copy().sub(camPos).normalize());
    } else if (key == 's') {
      // camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(-1));
      camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(-1));
    }
  }

  p.show();
  p2.show();
  p3.show();

  // HUD 
  camera();
  noLights();
  fill(255);
  textSize(19);
  textMode(SHAPE);
  text("cam rotates around ITSELF. Height of cam is "+ str( map(mouseY, 0, height, -1333, 1333)), 
    -117, -117);
}

void mouseDragged() {
  //float dx = mouseX - pmouseX;
  //float dy = mouseY - pmouseY;

  //aXZ += dy / 100;
  //aYZ += dx / 100;
}
//---------------------------------------------------------------

class Planet extends Body3D {

  color col = color (random(255), 33, 333); 

  Planet(PVector pos_, float m_) {
    this.pos = pos_;
    this.m = m_;
  }

  void show() {
    lights();
    noStroke();
    fill(col);
    translate(pos.x, pos.y, pos.z);
    sphere(this.m);
  }
}

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

class Body3D {
  PVector pos;
  PVector vel = new PVector(0, 0, 0);
  PVector acc = new PVector(0, 0, 0);

  float m;

  void applyAcc(PVector acc_) {
    acc = acc.add(acc_);
  }

  void update() {
    vel = vel.add(acc);
    pos = pos.add(vel);

    acc = new PVector(0, 0, 0);
  }
}

```

---

<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:** [September 15, 2020, 6:12am UTC](https://discourse.processing.org/t/3d-camera-rotation/23742/15 "2020-09-15T06:12:11Z")

</div>

Libraries

Please look at Peasycam
