PeasyCam automatic camera movements

hi. Im trying to automate movement with peasy cam. Right now with this code i have to manuale position the camera in 5 diferent places and by pressing the keys from 1 to 5, it sets those positions. Then by pressing the key 6, it chooses one of those positions at random and moves there.



void setPlaces() {

  if (keyPressed) {
    
    if (key == '1') {
      state1 = cam.getState();
    } else if (key == '2') {
      state2 = cam.getState();
    } else if (key == '3') {
      state3 = cam.getState();
    } else if (key == '4') {
      state4 = cam.getState();
    } else  if (key == '5') {
      state5 = cam.getState();
    }
  }
}

void moverCamara() {
  r= int(random(1, 5));

  if (r == 1) {
    cam.setState(state1, 10000);
  } else if (r == 2) {
    cam.setState(state2, 10000);
  } else if (r == 3) {
    cam.setState(state3, 10000);
  } else  if (r == 4) {
    cam.setState(state4, 10000);
  } else if (r == 5) {
    cam.setState(state5, 10000);
  }
}

What i want to do is to set the positions in andvanced, for example in setup, and when the program starts, just move randomly beatween those fixed points. Not having to set them up when the program begins.

I checked the pasecam documentation and i deduced that i have to declare and initialize a CameraState object. this is the constructor.

CameraState (Rotation rotation,
Vector3D center
double Distance

But i dont understand how to do it. If you could show me how to declare a cameraState object, it would be great.
Im a little newbie so i dont understand the documentation yet. Also english is not my native language so i need a litle help.

Here is the documentation for the peasyCam library, the CameraState method: http://mrfeinberg.com/peasycam/reference/peasy/CameraState.html

Thanks in advance <3

3 Likes

Hi! I hope this helps :slight_smile:

Rotation has many possible constructors, I just picked one.

import peasy.org.apache.commons.math.geometry.*;
import peasy.*;

PeasyCam cam;

public void settings() {
  size(800, 800, P3D);
}

public void setup() {
  cam = new PeasyCam(this, 400);
}

public void draw() {
  background(0);
  box(300);
}

public void keyReleased() {
  if (key == ' ') {
    Rotation rot = new Rotation(RotationOrder.XYZ, random(TAU), random(TAU), random(TAU));
    Vector3D center = Vector3D.zero; // look at the origin (0,0,0)
    double distance = random(500, 1000); // from this far away
    CameraState state = new CameraState(rot, center, distance);
    cam.setState(state, 1000);
  }
}
2 Likes

Hi! Thank you for the help. I still have some problems
1rst: i want to make the position of the CameraStates more apart from each other but always looking at the center where the figure is. I dont know what values to put in the rotation, vector3D and distance variables to make that.
2nd: . I want the camera to move Smoothly between this 3 CameraStates, so i put a moving time of 2000 ms, but the movement its shaky and stutery, i dont know why. I mean, the random value that changes the position should change only when cam.getState() == State1 (or 2 or 3), that means that it shoul only change when it has arriven at another camera position, am i right?

anyway, thank you for your help so far.

here is the whole thing:

import peasy.PeasyCam;
import peasy.org.apache.commons.math.geometry.*;
import peasy.*;


PeasyCam cam;

//Initializing the cameraStates
Rotation rot1 = new Rotation(RotationOrder.XYZ, 300, 300, 300);
Vector3D center1 = Vector3D.zero;
double distancee1 = 200; // from this far away

Rotation rot2 = new Rotation(RotationOrder.XYZ, 100, 100, 100);
Vector3D center2 = Vector3D.zero;
double distancee2 = 200; // from this far away

Rotation rot3 = new Rotation(RotationOrder.XYZ, 0, 0, 0);
Vector3D center3 = Vector3D.zero;
double distancee3 =200; // from this far away

CameraState state1 = new CameraState(rot1, center1, distancee1);
CameraState state2 = new CameraState(rot2, center2, distancee2);
CameraState state3 = new CameraState(rot3, center3, distancee3);

int r ;
ArrayList<PVector> points = new ArrayList<PVector>();

float x =0.01;
float y =0;
float z =0;

float dx;
float dy;
float dz;

float a = 10; 
float b = 28;
float c = 8.0/3.0;

float dt = 0.01;
float hu =0;

boolean coloreado = true;
float h;
float largoDeLineas;

boolean pointsOrLine = true;

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

  colorMode(HSB);
  cam = new PeasyCam(this, width/2, height/2, 0, 400);

  cam.setMinimumDistance(10);
  //Posición random inicial para la camara
  r= int(random(1, 3));
}

void draw() {

  background(0);
  pushMatrix();
  translate(width/2, height/2);
  scale(6);
  box(0, 0, 0);

  dx = (a * (y - x))*dt; 
  x = x+dx;

  dy = ((x *(b-z))-y)*dt;
  y = y+dy;

  dz = (x*y- c*z)*dt;
  z = dz+z;

  //Setea dibujar lineas o puntos
  //true hace puntos, false hace una linea

  pointsOrLine = true;

  //Setea cuan largas son las lineas que se dibujan
  largoDeLineas = 500;

  //Indica si las lineas son monocromaticas(true) o tienen una gama de colores
  //Por default esta en gama de color
  //true = gama de color  false = monocromatico

  coloreado = true ;
  if ( coloreado) {
    h = 0.01;
  } else {
    h = 0;
  }
  strokeWeight(1);
  noFill();
  points.add(new PVector(x, y, z));

  hu =0;
  // El valor que se le pasa a la funcion indica cuantas lineas 
  //se van a dibujar
  cuantosDibujo(10);

  stroke(255);

  //Como se mueve la camara
  if (r == 1) {
    cam.setState(state1, 2000);
    r= int(random(1, 3));
  } else if (r == 2) {
    cam.setState(state2, 2000);
    if (cam.getState() == state2) {
      r= int(random(1, 3));
    }
  } else if (r == 3) {
    cam.setState(state3, 2000);
    if (cam.getState() == state3) {
      r= int(random(1, 3));
    }
  }





    println(cam.getState());
    box(width);
    popMatrix();
  }



  void dibujar(float mm) {

    if (pointsOrLine == false) {
      beginShape();

      for (int i =0; i<points.size()-1; i++) {
        PVector p = points.get(i);
        stroke(hu, 255, 255);
        vertex(p.x*mm, p.y, p.z); 

        hu+=h;
        if (hu>255) {
          hu = 0;
        }
        if (points.size()>largoDeLineas) {
          points.remove(0);
        }
      }

      endShape();
    } else if (pointsOrLine == true) {
      for (int i =0; i<points.size()-1; i++) {
        PVector p = points.get(i);
        stroke(hu, 255, 255);
        point(p.x*mm, p.y, p.z); 

        hu+=h;
        if (hu>255) {
          hu = 0;
        }
        if (points.size()>largoDeLineas) {
          points.remove(0);
        }
      }
    }
  }

  void cuantosDibujo(float a) {

    for (int i = 0; i <a; i++) {
      dibujar(i/3);
      dibujar(-i/3);
    }
  }

1 Like

about random

int(random(1, 3)) probably doesn’t do what you think it does. You can only get 1 or 2, never 3. Because random(1, 3) gives you a number between 1 and up to 3, but not including 3.

You can replace it by int(random(1, 4)) or maybe more clear round(random(1, 3))

about angles

Angles are specified in radians. 360 degrees is about 6.28 radians (two pi). That’s one full turn.

You specified values like 300 and 100. 300 radians is almost 50 full turns :slight_smile: And even if it’s many turns, it may actually end up pointing in the same direction as 0. See, looking towards the North is the same even if you did one full turn or 50 full turns.

Two solutions: either specify smaller values between 0 and TWO_PI, or use radians(300) to do the conversion from degrees to radians. If you want three cameras in this shape 🟀, you could do

Rotation rot1 = new Rotation(RotationOrder.XYZ, 0, radians(0), 0);
Vector3D center1 = Vector3D.zero;
double distancee1 = 200; // from this far away

Rotation rot2 = new Rotation(RotationOrder.XYZ, 0, radians(120), 0);
Vector3D center2 = Vector3D.zero;
double distancee2 = 200; // from this far away

Rotation rot3 = new Rotation(RotationOrder.XYZ, 0, radians(240), 0);
Vector3D center3 = Vector3D.zero;
double distancee3 =200; // from this far away

so they are 120 degrees apart.

jittery camera

It’s your task to wait for 2 seconds before setting a new camera target. As it is currently, on every frame it’s deciding between 2 targets, jumping back and forth.

That’s easy to do:

long nextEvent = 0; // in milliseconds
// then inside draw
  if (millis() >= nextEvent) {
    // <change your camera here>
    nextEvent = millis() + 2000; // schedule next event in 2 seconds
    // you could even have a random duration instead of always 2 seconds :)
  }

updated code

import peasy.PeasyCam;
import peasy.org.apache.commons.math.geometry.*;
import peasy.*;

PeasyCam cam;

//Initializing the cameraStates
Rotation rot1 = new Rotation(RotationOrder.XYZ, radians(30), radians(240), 0);
Vector3D center1 = Vector3D.zero;
double distancee1 = 500; // from this far away

Rotation rot2 = new Rotation(RotationOrder.XYZ, 0, radians(120), radians(30));
Vector3D center2 = Vector3D.zero;
double distancee2 = 500; // from this far away

Rotation rot3 = new Rotation(RotationOrder.XYZ, 0, 0, 0);
Vector3D center3 = Vector3D.zero;
double distancee3 =500; // from this far away

CameraState state1 = new CameraState(rot1, center1, distancee1);
CameraState state2 = new CameraState(rot2, center2, distancee2);
CameraState state3 = new CameraState(rot3, center3, distancee3);

int r ;
ArrayList<PVector> points = new ArrayList<PVector>();

float x =0.01;
float y =0;
float z =0;

float dx;
float dy;
float dz;

float a = 10; 
float b = 28;
float c = 8.0/3.0;

float dt = 0.01;
float hu =0;

boolean coloreado = true;
float h;
float largoDeLineas;

boolean pointsOrLine = true;

long nextEvent = 0;

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

  colorMode(HSB);
  cam = new PeasyCam(this, width/2, height/2, 0, 400);

  cam.setMinimumDistance(10);
  //Posición random inicial para la camara
  r= int(random(0, 3));
}

void draw() {

  background(0);
  pushMatrix();
  //translate(width/2, height/2);
  scale(6);
  box(0, 0, 0);

  dx = (a * (y - x))*dt; 
  x = x+dx;

  dy = ((x *(b-z))-y)*dt;
  y = y+dy;

  dz = (x*y- c*z)*dt;
  z = dz+z;

  //Setea dibujar lineas o puntos
  //true hace puntos, false hace una linea

  pointsOrLine = true;

  //Setea cuan largas son las lineas que se dibujan
  largoDeLineas = 500;

  //Indica si las lineas son monocromaticas(true) o tienen una gama de colores
  //Por default esta en gama de color
  //true = gama de color  false = monocromatico

  coloreado = true ;
  if ( coloreado) {
    h = 0.01;
  } else {
    h = 0;
  }
  strokeWeight(1);
  noFill();
  points.add(new PVector(x, y, z));

  hu =0;
  // El valor que se le pasa a la funcion indica cuantas lineas 
  //se van a dibujar
  cuantosDibujo(10);

  stroke(255);

  //Como se mueve la camara
  if (millis() >= nextEvent) {
    // avanza 1 o 2 cámaras
    r += int(random(1, 3));
    // Si nos pasamos del máx, retrocede una "página"
    if(r > 2) {
      r -= 3;
    }
    if (r == 0) {
      cam.setState(state1, 2000);
    } else if (r == 1) {
      cam.setState(state2, 2000);
    } else if (r == 2) {
      cam.setState(state3, 2000);
    }
    nextEvent = millis() + 2000;
    println(r, cam.getState());
  }

  box(width);
  popMatrix();
}



void dibujar(float mm) {

  if (pointsOrLine == false) {
    beginShape();

    for (int i =0; i<points.size()-1; i++) {
      PVector p = points.get(i);
      stroke(hu, 255, 255);
      vertex(p.x*mm, p.y, p.z); 

      hu+=h;
      if (hu>255) {
        hu = 0;
      }
      if (points.size()>largoDeLineas) {
        points.remove(0);
      }
    }

    endShape();
  } else if (pointsOrLine == true) {
    for (int i =0; i<points.size()-1; i++) {
      PVector p = points.get(i);
      stroke(hu, 255, 255);
      point(p.x*mm, p.y, p.z); 

      hu+=h;
      if (hu>255) {
        hu = 0;
      }
      if (points.size()>largoDeLineas) {
        points.remove(0);
      }
    }
  }
}

void cuantosDibujo(float a) {
  for (int i = 0; i <a; i++) {
    dibujar(i/3);
    dibujar(-i/3);
  }
}
4 Likes

Thank you for your contributions! here is the github repository where i uploaded the code.


Coulden`t have made it without you!

also here is the coding train page from where i got the idea.

https://thecodingtrain.com/CodingChallenges/012-lorenzattractor.html

cheers!

2 Likes

for another approach, see Camera Animation: Move camera on 3D curve

3 Likes