PVectors, traveling a path

I’m trying to write a program that has a Ball object travel across paths determined by randomly placed PVector objects.
In the Ball class i’ve written a move method that moves a Ball to the nearest PVector object in the “points” ArrayList. The problem is, is that the Ball object is “teleporting” to the next PVector instead of traveling along the path.
If someone could offer some advice/suggestions on how to get the Ball to travel a path between the PVectors I would greatly appreciate it

Here’s my code:

private ArrayList<PVector> points;
Ball ball;
int destNum = 10;

public void setup() {
  size(800, 800);
  

  // These only need to be called once, not every frame in draw()
  smooth();
  frameRate(1.0);

  float randomLat;
  float randomLong;
  points = new ArrayList <PVector>();
  for (int i = 0; i < destNum; i++){
     randomLat = random(800);
     randomLong = random(800);
    while(!(Math.pow(400-randomLat,2) + Math.pow(400-randomLong,2) < Math.pow(400,2))){
     randomLat = random(800);
     randomLong = random(800);
  }
  
    points.add(i, new PVector(randomLat, randomLong));
    
  }
  for(int j = 0; j< points.size(); j++){
    ellipse(points.get(j).x, points.get(j).y, 20,20);
  }
  ball = new Ball(points);
}


public void draw() {
 // background(255);
 fill(255);
 ellipse(400,400,800,800);

  noStroke();
  fill(255, 0, 0);
  
  for (int i = 0; i < points.size(); i++){
    ellipse(points.get(i).x, points.get(i).y, 20, 20);
  }

  noStroke();
  for (int i=1; i < points.size(); i++) line(points.get(i-1).x, points.get(i-1).y, points.get(i).x, points.get(i).y);

  ball.move();
  fill(255,0,0);
  rect(20,20,15,15);
  fill(0);
  rect(20,40,15,15);
  
  text(" - Destinations",40, 30);
  text(" - Nickbot",40, 50);
}

public class Ball {
  private PVector location = new PVector();
  private ArrayList<PVector> points;
  int curr;
  float t;

  public Ball(ArrayList<PVector> points){
    this.points = points;
    location = points.get(0).get();
    curr = 0;
    t = 0;
  }

 public float calcDist (PVector a, PVector b){
    return a.dist(b);
  }
  
  public void move () {
    
    if(points.size() > 1){
      ArrayList <PVector> moving = new ArrayList <PVector>();
      int min = 1;
      for(int i = 1; i < points.size(); i++){
        if(calcDist(points.get(curr), points.get(i)) < calcDist(points.get(curr),
        points.get(min))){
          min = i;
        }
      }
      location.x = lerp(points.get(curr).x, points.get(min).x, t);
      location.y = lerp(points.get(curr).y, points.get(min).y, t);
      
      PVector temp = new PVector(location.x, location.y);
      fill(0);
      noStroke();
      ellipse(location.x, location.y, 10, 10);

     if (t < 1.0) {
      t += 0.025;
      if (t > 1.0) {
        t = 0.0;
      }
      else {
        t = 1.0;
      }
    }
          /*the following code adds the current node and the remaining nodes into the points
          ArrayList. After the "move" method has run it's course, the points ArrayList will be updated
          to exclude the previous node.
          */
          
          if(location.x > points.get(min).x - 2 && location.x < points.get(min).x + 2 &&
            location.y > points.get(min).y - 2 && location.y < points.get(min).y + 2){
              moving.add(0, points.get(min));
              
              for(int j = 1; j < points.size(); j++){
                if(points.get(j) != points.get(min)){
                  moving.add(points.get(j));
                }    
              }
            }else{
              moving.add(0, temp);
          
              for(int j = 1; j < points.size(); j++){
                if(points.get(j) != points.get(min)){
                  moving.add(points.get(j));
                }    
              }
            }
    points = moving;
      
  }
}
}
2 Likes

hey I did something similar using math (not pvectors) and it is on my YouTube with the source in the comments somewhere

it was in p5.js but if you need help translating I can assist you.

1 Like

Please Format you code correctly. You can do so by formatting the code inside processing and then pasting it within the …‘s that Show up, once you press the </> sign. And i think (might be wrong) you should use dist(a, b); instead of a.dist(b); .

1 Like

http://s000.tinyupload.com/index.php?file_id=03543518300275721849

You don’t need to use lerp on the unpacked x and y in that way. PVector has a lerp method built-in.

Your general issue is that you want to slide across a list of points. For that, I recommend a list-based interpolation like lerpVectors:

PVector lerpVectors(float amt, PVector... vecs) {
  if(vecs.length==1){ return vecs[0]; }
  float unit = 1.0/(vecs.length-1);
  return PVector.lerp(vecs[floor(amt / unit)], vecs[ceil(amt / unit)], amt%unit/unit);
}