Simple example of 3d movement following a point?

hi, i need a simple example to how folllow in 3d a object.
anybody can help me?

The objective is simple, object a follow the object b in 3d space.

My problem is the way to “orientation a to b” and “move” in orientation direction.

Thanks in advance!!!

1 Like

Consider:
https://processing.org/reference/modelX_.html

Add this snippet to code (from above) and observe:

  // draw another box at the same (x, y, z) coordinate as the other
  pushMatrix();
  translate(x, y, z);
  stroke(255, 0, 0);
  box(50);
  println("1:", x, y, z);
  popMatrix();
  println("2:", x, y, z);
  stroke(255, 255, 0);
  strokeWeight(10);
  point(x, y, z);
  strokeWeight(1);
}

Tell us more.

I never used modelX() so this will be useful for me!

:slight_smile:

1 Like

I assume your player b is followed by a (the camera)

My assumptions:

  • b is in the lead

  • a is always say 30 above b (y value) : a.y = b.y-30;

  • b moves only in x and z direction (the labyrinth for the player b)

The Position of a

a just takes the former position of b with an easing / damping

a is not allowed to go nearer than 75 or so (use dist())

The lookAt and up vector of the camera

  • The lookAt of the camera just use b

  • the up vector can stay as it is

Chrisir

2 Likes

Could you show me a complete example of this? yes, that’s exactly what I want, that an object B follows an object A when the distance between them is greater than a set value

No not really

You could monitor the player position in an ArrayList

This is a simple sketch for this purpose, well…
How i code the movement to B ??

int ST = 0;
object a,b;
void setup(){
    size(640, 400, P3D);
}
//..................................
void draw(){
    switch(ST){
        case 0:
            a = new object(width/2, height/2, 0);
            b = new object(width, height, -300);
            ST = 10;
            break;
        case 10:
            ambientLight(255, 127, 127);
            a.frame();
            b.frame();
            break;
    }
}
//..................................
//..................................
class object{
    int st = 0;
    float anglex, angley, anglez;
    float x, y, z;
    float size = 1.0f;
    PShape s;
    public object(float x, float y, float z){
        this.x = x;
        this.y = y;
        this.z = z;
    }
    void frame(){
        switch(st){
            case 0:
                s = createShape(BOX, 10, 10, 10);
                st = 10;
                break;
            case 10:
                
                if(this==a){
                    // move to b..
                    float distance = 0;    // distance between a to b?
                    if(distance > 20){
                        getOrientation(b);
                        this.advance3d(1.0f);
                    }
                    
                }
                
                this.draw();
                break;
        }
    }
    void draw(){
        pushMatrix();
                translate(x, y, z);
                scale(size);
                rotateX(radians(anglex));
                rotateY(radians(angley));
                rotateZ(radians(anglez));
                shapeMode(CORNERS);
                shape(s);
                popMatrix();
    }
    void getOrientation(object obj){
        /*
            anglex = ??
            angley = ??
            anglez = ??
        */
    }
    void advance3d(float distance_to_move){
        /*
            
            advance "distance_to_move" in 3d space in to orientation getted by anglex, angley and anglez..
            
        */
    }
}
//..................................
//..................................

Just tinkering a bit with your code.

int ST = 0;
object a,b;

float theta = 0;

void setup()
  {
    size(1024, 768, P3D);
        switch(ST)
      {
        case 0:
            fill(255, 255, 0);
            a = new object(0, 0, 0);
            fill(255,0, 255);
            b = new object(0, 0, 0);
            ST = 10;
            break;
        case 10:
            ambientLight(255, 127, 127);
            a.frame();
            b.frame();
            break;
    }
  }
//..................................

void draw()
  {
  background(0);
  translate(width/2, height/2);
  println(frameRate);

    theta += TAU/10;
//    a.anglex = theta;
    a.angley = theta;
    a.anglez = theta;

    a.x = 100;
    
//    b.anglex = theta;
//    b.angley = theta;
    b.anglez = theta;
 
    b.x = 150;
    
    fill(255, 255, 0);
    a.draw();
    fill(255, 0, 255);
    b.draw();
    
}
//..................................



//..................................
class object{
    int st = 0;
    float anglex, angley, anglez;
    float x, y, z;
    float size = 1.0f;
    PShape s;
    public object(float x, float y, float z){
        this.x = x;
        this.y = y;
        this.z = z;
    }
    void frame(){
        switch(st){
            case 0:
                s = createShape(BOX, 10, 10, 10);
                st = 10;
                break;
            case 10:
                
                if(this==a){
                    // move to b..
                }
                
                this.draw();
                break;
        }
    }
    
    
    void draw(){
        pushMatrix();
                
                //scale(size);
                rotateX(radians(anglex));
                rotateY(radians(angley));
                rotateZ(radians(anglez));
                translate(x, y, z);
                
                shapeMode(CORNERS);
//                shape(s);
                box(50);  
                popMatrix();
    }
}
//..................................
//..................................

This was playing at the time and went well with the animation:
image

:slight_smile:

I knew it would come in handy!

I used modelX(), modelY() and modelZ() to get the x, y, z co-ordinates and drew a line from A to B.

I will leave this as an exercise for you so you can experience the joy of coding this!

https://processing.org/reference/modelX_.html

image

:slight_smile:

Try to understand me, I have no idea of ​​3d trigonometry, I do not even know what theta means, I appreciate a lot the code, but I do not know what to do with it, I just need to know how to orient in 3D one object with another and then how to do it move in that direction.

You are very kind to help me, but I do not know how to continue or modify the code.

https://processing.org/tutorials/trig/

Theta is what I used for angle.

https://processing.org/reference/modelX_.html states:

The modelX() , modelY() , and modelZ() functions record the location of a box in space after being placed using a series of translate and rotate commands.

In your code you do translations and rotations and in my example I made use of your code to do this.

I simply returned the x, y, z of each shape and drew a line:
line(a.mx, a.my, a.mz, b.mx, b.my, b.mz);

No trigonometry involved.

ok, then, how do I direct a to b? and how do I advance it to each frame?

I give you an example in 2d of what I want to achieve in 3d? It seems to me that you have not understood me.

Just follow my idea with the arraylist and what I wrote

OR

This won’t work directly but a few lines may inspire you - see function CheckCameraMouse

If it can’t be transpiled to Pjs, you should host it someplace else, like GitHub’s Gist: :octopus:

1 Like

Parece que no se puede compilar.
it seems that you can not compile.

I just had to do a Google search on that!
https://learnopengl.com/Getting-started/Camera

More for me to explore.

:slight_smile:

I understood very clearly and shared with you my thinking on this.

I did not have an example to share with you; I did write one but I will not be sharing that.

The first thing I did was start considering this without looking at other code.

I considered the “midpoint between 2 points” and wrote a general function to place a point anywhere between the two points A and B along that line.

From there I was able to move that point anywhere along a line between 2 points A and B in 3D space:

And now I am having fun with it!

You example inspired me and I created my own project for this from scratch. Thank you!

glv

When you didn’t know lookAt, read about camera in the reference

:wink:

https://www.processing.org/reference/camera_.html

1 Like

Here is my solution:

This works like this: camera gets its position from the ball/player with a delay (easing/ damping)

LookAt = ball / Player Position

// 3D sketch: shows a ball that moves in the x/z plane (height = y = 500) and is followed by a camera.
// The goal of the sketch is to demonstrate the usage of a following camera.  

// cubes 
float angleCubes=45; // angle for the cubes in the scene

CameraClass cam; 

PVector ballPos = new PVector (300, 500, 300);
PVector ballVel = new PVector (
  random(1, 2), 
  0, 
  random(-2, -1));

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

void setup() {
  size (1400, 800, P3D);

  cam = new CameraClass ();

  cam.camPos = ballPos.copy();
  cam.camPos.x += 113;
  cam.camPos.y -= 63;
  cam.camPos.z += 113;
} // func 

void draw() {
  // clear canvas 
  background(111);

  // avoid clipping : https : // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
  perspective(PI/3.0, (float) width/height, 1, 1000000);

  // apply lights 
  lights();

  // camera follows ball
  if (! (keyPressed&&key==' ')) {
    cam.lookAtPVectorFollow(ballPos);
  }

  // apply the values of the class to the real camera
  cam.set();

  // move ball and draw it  
  if (! (keyPressed&&key=='m')) {
    ballPos.add(ballVel);
  }
  fill(0, 255, 0); // green 
  noStroke();
  mySphere(ballPos.x, ballPos.y, ballPos.z, 10);

  // contain ball in a invisible box 
  contain(ballPos, ballVel);

  // make the scene with the boxes 
  scene();

  // text upper left corner
  fill(0, 255, 0); 
  cam.HUD_text("The green ball is contained in an "
    +"red field."
    +"\nHold space bar to stop camera."
    +"\nHold 'm' to stop the Movement of the ball.");
  //
} // func 

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

void scene () {

  // Drawing of the red field   

  fill(255, 2, 2);//RED
  noStroke(); 
  mySphere(500, 500, 500, 20);
  mySphere(100, 500, 100, 20);
  mySphere(100, 500, 500, 20);
  mySphere(500, 500, 100, 20);
  //
  // rect 
  stroke(255, 2, 2);//RED
  line(500, 500, 500, 500, 500, 100);//up
  line(500, 500, 100, 100, 500, 100); //left
  line(100, 500, 100, 100, 500, 500 ); // down 
  line(100, 500, 500, 500, 500, 500 ); // down

  stroke(0);
  float z ; 

  // one wall of boxes
  for (int x = 10; x < 600; x+= 100)
  {
    fill(x/3, 2, 2);
    for (int y = 10; y < 600; y+= 100)
    {
      z = -600;
      myBox(x, y, z, 24);
      // println ( "Box: " + x + ", "+y+ " "+z);
    }
    fill(0, 0, 254);
    z=-800;
    myBox(x, 10, z, 24);
  }
  // 
  // a few additional boxes
  fill(0, 0, 254);
  z=-400;
  myBox(220, 10, z, 24);
  myBox(600, 10, z, 24);
  z=-400;
  myBox(220, 510, z, 24);
  myBox(600, 510, z, 24);
  z=399;
  myBox(220, 510, z, 24);
  myBox(600, 510, z, 24);
  z=900;
  myBox(220, 510, z, 24);
  myBox(600, 510, z, 24);
  angleCubes++;
  //
}

void myBox(float x, float y, float z, 
  float size1) {
  // one nice wrapper for build in box-command
  pushMatrix();
  translate(x, y, z);
  rotateY(radians(angleCubes));
  rotateX(radians(45));
  box(size1);
  popMatrix();
}

void mySphere(float x, float y, float z, 
  float size1) {
  // one nice wrapper for build in sphere-command
  pushMatrix();
  translate(x, y, z);
  sphere(size1);
  popMatrix();
}

void contain(PVector ballPos, PVector ballVel) {
  // contain ball

  if (ballPos.x>500) 
    ballVel.x=abs(ballVel.x)*-1;
  if (ballPos.z>500) 
    ballVel.z=abs(ballVel.z)*-1;

  if (ballPos.x<100) 
    ballVel.x=abs(ballVel.x);
  if (ballPos.z<100) 
    ballVel.z=abs(ballVel.z);
}

//
// ===============================================

class CameraClass {

  // capsules the normal camera() command and its vectors 

  PVector camPos;     // its vectors 
  PVector camLookAt;
  PVector camUp;

  PVector camPosInitial;     // its vectors - the default (unchanged) 
  PVector camLookAtInitial;
  PVector camUpInitial; 

  // for follow
  PVector camWhereItShouldBe = new PVector(0, 0, 0);
  PVector camAdd = new PVector(0, -60, 0);
  float easing = .019; // .07; // how fast it changes

  float camCurrentAngle=0;// -90;   // for cam rotation around itself (around Y-axis)
  float camRadius;             // same situation 

  // constructor without parameters
  CameraClass() {
    // constr
    // set vectors 
    camPos    = new PVector(width/2.0, height/2.0, 990);
    camLookAt = new PVector(width/2.0, height/2.0, -600);
    camUp     = new PVector( 0, 1, 0 );
    // save the initial values
    camPosInitial    = camPos.get();
    camLookAtInitial = camLookAt.get();
    camUpInitial     = camUp.get();
  }  // constr

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

  void set() {
    // apply vectors to actual camera
    camera (camPos.x, camPos.y, camPos.z, 
      camLookAt.x, camLookAt.y, camLookAt.z, 
      camUp.x, camUp.y, camUp.z);
  }

  void setLookAt (float x1, float y1, float z1) {
    camLookAt = new PVector(x1, y1, z1);
  }

  void lookAtPVectorFollowOnlyLookAt(PVector followMe) {
    // follows a player (e.g.)
    // change only look at
    camLookAt = followMe.get();
  }

  void lookAtPVectorFollow (PVector followMe) {
    // follows a ball / player (e.g.)
    // complete following (lookAt and camPos)

    // manage Look At 
    camLookAt =  followMe.get();

    // manage position of the camera
    float easing = 0.0198; 
    // x
    camPos.x    += (followMe.x-camPos.x) * easing;

    // y
    // camPos.y    += (followMe.y-camPos.y) * easing -20;
    camPos.y    = followMe.y - 50; // other principle for y by the way

    // z
    camPos.z    += (followMe.z-camPos.z) * easing;
  }

  void printData() {
    println ( "Cam at " + camPos 
      + " looking at " + camLookAt 
      + " (angle = "
      +camCurrentAngle
      +").");
  }

  void HUD_text (String a1) {
    // HUD text upper left corner 
    // this must be called at the very end of draw()

    // this is a 2D HUD 
    camera();
    hint(DISABLE_DEPTH_TEST);
    noLights();
    // ------------------
    textSize(16);
    text (a1, 20, 20);
    // ------------------
    // reset all parameters to defaults
    textAlign(LEFT, BASELINE);
    rectMode(CORNER);
    textSize(32);
    hint(ENABLE_DEPTH_TEST); // no HUD anymore
    lights();
  } // method
  //
} // class
// ======================================
1 Like