Why doesn't this PVector code work when I change it to toxiclibs' Vec3D?

I'm following Daniel Shiffman's Nature of Code and I want to begin working in 3D instead of the 2D used in the examples. I added a third dimension in this code he uses to show the PVector class. I don't get errors in the Vec3D version, but it doesn't work. The small points that should move remain static. Here is my PVector code, so you can see it works:

import peasy.*;

Mover[] movers = new Mover[20];
PeasyCam pcam;

void setup() {
  size(640, 360, P3D);
  background(255);
  pcam = new PeasyCam (this, 800);
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover();
  }
}

void draw() {
  background(255);
  stroke(.3);
  noFill();
  box(400);
  strokeWeight(sin(radians(frameCount))*8);
  for (int i = 0; i < movers.length; i++) {

    movers[i].update();
    movers[i].checkEdges();
    movers[i].display();
  }
}

class Mover {

  PVector location;
  PVector velocity;
  PVector acceleration;
  float topspeed;

  Mover() {
    location = new PVector(random(width), random(height), random(height));
    velocity = new PVector(0, 0, 0);
    topspeed = 4;
  }

  void update() {

    PVector mouse = new PVector(mouseX, mouseY, mouseY);
    mouse.sub(location);
    PVector dir = mouse;

    dir.normalize();
    dir.mult(0.5);
    acceleration = dir;

    velocity.add(acceleration);
    velocity.limit(topspeed);
    location.add(velocity);
  }

  void display() {
    stroke(0);
    fill(175);
    point(location.x, location.y, location.z);
    //ellipse(location.x,location.y,16,16);
  }


  void checkEdges() {

    if (location.x > width) {
      location.x = 0;
    } else if (location.x < 0) {
      location.x = width;
    }

    if (location.y > height) {
      location.y = 0;
    } else if (location.y < 0) {
      location.y = height;
    }
  }
}

Here is the Vec3D version, so you can see it uses the appropiate mmm... "methods" and is in order:

import toxi.geom.Vec3D;
import peasy.*;

Mover[] movers = new Mover[20];
PeasyCam pcam;

void setup() {
  size(640, 360, P3D);
  background(255);
  pcam = new PeasyCam (this, 800);
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover();
  }
}

void draw() {
  background(255);
  stroke(.3);
  noFill();
  box(400);
  strokeWeight(sin(radians(frameCount))*8);
  for (int i = 0; i < movers.length; i++) {

    movers[i].update();
    movers[i].checkEdges();
    movers[i].display();
  }
}

class Mover {

  Vec3D location;
  Vec3D velocity;
  Vec3D acceleration;
  float topspeed;

  Mover() {
    location = new Vec3D(random(width), random(height), random(height));
    velocity = new Vec3D(0, 0, 0);
    topspeed = 4;
  }

  void update() {

    Vec3D mouse = new Vec3D(mouseX, mouseY, mouseY);
    mouse.sub(location);
    Vec3D dir = mouse;

    dir.normalize();
    dir.scale(0.5);
    acceleration = dir;

    velocity.add(acceleration);
    velocity.limit(topspeed);
    location.add(velocity);
  }

  void display() {
    stroke(0);
    fill(175);
    point(location.x, location.y, location.z);
    //ellipse(location.x,location.y,16,16);
  }


  void checkEdges() {

    if (location.x > width) {
      location.x = 0;
    } else if (location.x < 0) {
      location.x = width;
    }

    if (location.y > height) {
      location.y = 0;
    } else if (location.y < 0) {
      location.y = height;
    }
  }
}

What's wrong?

Answers

  • Answer ✓

    A lot of things are wrong and/or inefficient (some of which already with your PVector code by the way). Here is the adapted code, which fixes many of those things. Note that your current behavior just moves everything to the same point.

    Adapted Code

    import toxi.geom.Vec3D;
    import peasy.*;
    
    Mover[] movers = new Mover[20];
    PeasyCam pcam;
    Vec3D mouse;
    
    void setup() {
      size(640, 360, P3D);
      mouse = new Vec3D();
      noFill();
      pcam = new PeasyCam (this, 800);
      for (int i=0; i<movers.length; i++) {
        movers[i] = new Mover();
      }
    }
    
    void draw() {
      background(255);
      strokeWeight(1);
      box(400);
      strokeWeight(8);
      float mx = map(mouseX, 0, width, -200, 200);
      float my = map(mouseY, 0, height, -200, 200);
      mouse.set(mx, mx, my);
      for (Mover m : movers) {
        m.update();
        m.checkEdges();
        m.display();
      }
    }
    
    class Mover {
      Vec3D location;
      Vec3D velocity;
      Vec3D acceleration;
      float topspeed;
    
      Mover() {
        location = new Vec3D(random(width), random(height), random(height));
        velocity = new Vec3D();
        topspeed = 4;
      }
    
      void update() {
        Vec3D dir = mouse.sub(location);
        dir.getNormalized().scaleSelf(0.5);
        velocity.addSelf(dir);
        velocity.limit(topspeed);
        location.addSelf(velocity);
      }
    
      void checkEdges() {
        if (location.x > 200) { location.x = -200; }
        else if (location.x < -200) { location.x = 200; }
        if (location.y > 200) { location.y = -200; }
        else if (location.y < -200) { location.y = 200; }
      }
    
      void display() {
        point(location.x, location.y, location.z);
      }
    }
    
  • Thanks. I had forgotten about this.

    I know it doesn't do much. I just wanted it first to run using Vec3D. As for the code being too ineffective is probably because its didactic purposes. (It is almost the exact code from Nature of Code).

    Thanks again.

Sign In or Register to comment.