createShape() and lerp()

Hello everyone, from the last topic, I think it’s time to open a new one, because the argument of it it’s totally changed, so, here’s a over simplified code:

int points = 3;

ArrayList<PVector> olPosition;
ArrayList<PVector> newPosition;
ArrayList<PShape> shapes;

void setup() {
  size(500, 400);

  olPosition = new ArrayList<PVector>();
  newPosition = new ArrayList<PVector>();
  shapes = new ArrayList<PShape>();

  for (int i = 0; i < points; i++) {
    PVector randPVector = new PVector (random(width/2), random(height/2));
    olPosition.add(randPVector);
    newPosition.add(randPVector);
  }
}

void draw() {
  background(255);

  for (int i = 0; i < points; i++) {
    olPosition.set(i, olPosition.get(i).lerp(newPosition.get(i), 0.5));
  }

  for (int j = 0; j < shapes.size(); j++) {
    shapes.get(j).beginShape(TRIANGLES);
    for (int i = 0; i < olPosition.size(); i++) {
      shapes.get(j).vertex(olPosition.get(i).x, olPosition.get(i).y);
    }
    shapes.get(j).endShape(CLOSE);
    shape(shapes.get(j));
  }
}

void mousePressed() {
  for (int i = 0; i < points; i++) {
    PVector randPVector = new PVector (random(width/2), random(height/2));
    newPosition.set(i, randPVector);
  }

  PShape shape = createShape();
  shapes.add(shape);
  println(shapes.size());
}

Why it creates a shape for every lerped position and not just mantain the original PShape and only move those vertexes? As you can see in the console I println the shapes.size() and it increments only by one every click, but, you can cleary see that isn’t the right number of shape in the screen, so… why that?

Thank you!

EDIT:
OH! I forgot… this was the previous topic: Fill a mesh Delaunay object :smiley:

This is the behaviour that I want to achieve, but everytime I click the mouse a new Shape needs to be created:

int points = 3;

ArrayList<PVector> olPosition;
ArrayList<PVector> newPosition;
ArrayList<PShape> shapes;

void setup() {
  size(500, 400);

  olPosition = new ArrayList<PVector>();
  newPosition = new ArrayList<PVector>();
  shapes = new ArrayList<PShape>();

  for (int i = 0; i < points; i++) {
    PVector randPVector = new PVector (random(width/2), random(height/2));
    olPosition.add(randPVector);
    newPosition.add(randPVector);
  }
}

void draw() {
  background(255);

  for (int i = 0; i < points; i++) {
    olPosition.set(i, olPosition.get(i).lerp(newPosition.get(i), 0.5));
  }
    beginShape(TRIANGLES);
    for (int i = 0; i < olPosition.size(); i++) {
      vertex(olPosition.get(i).x, olPosition.get(i).y);
    }
    endShape(CLOSE);
}

void mousePressed() {
  for (int i = 0; i < points; i++) {
    PVector randPVector = new PVector (random(width/2), random(height/2));
    newPosition.set(i, randPVector);
  }
}

A problem is that you are writing the interpolation positions directly into the shape, using theshape.beginShape and theshape.vertex on each retrieved shape. So each of the discrete shapes ends up also containing a pile of trails shapes. There is one per click, but what is inside each one is a mess.

I think (?) what you want to do is just draw the temporary interpolations, e.g. save them into a temporary shape you discard, or render them directly with e.g. triangle() or line().

Hi, Jeremydouglass, and thank you for your answer :slight_smile:
Is that so complicated? Creating one shape and interpolate it works well, the problem is only when I create more than one…
Any example of what I can do? :slight_smile:

No, that isn’t what I said the problem is. The problem isn’t one / many. It is writing trails / not writing trails.

In your one-shape example, you don’t do this. In your many-shape example, you do. It isn’t the number of things in the loop – it is that in your many-shape example you are using shapes.get(j).vertex to write your interpollated positions into the shape. In your one-shape example you don’t do this – you don’t write your trails into the shape, which is why you don’t have trails in the shape. Does this make sense?

Makes sense, but how do I can create more Shapes without creating an ArrayList and display the with that loop shapes.get(j).vertex? I’m not able to create a new shape without it… at least I dont’ know any other way.
I know that there is problem, and that line is the only substantian difference between the sketches so the problem is that…
Do you have any suggestion on how go behind it? Your fake-shape can be a solution, how you would do it?
Thank you again :slight_smile:

You create a shape without it just fine in your single-shape example. You just call vertex and draw to the screen, without writing into a shape.

It seems like you might want to logically separate your done shapes, your new destination shape (that you are tween-ing to, and doesn’t get drawn until it is added to the done shapes), and the ephemeral PShape for the current lerp state of the current frame, if any, which never needs to be stored.

Here is one approach I would recommend:

int points = 3;
float amt = 0;
float speed = 0.05;
ArrayList<PShape> shapes;
PShape tweenShape;

void setup() {
  size(500, 400);
  shapes = new ArrayList<PShape>();
}

void draw() {
  background(255);
  
  // draw the list of shapes

  // ...

  // if a tween shape exists, move amt by speed, and draw it
  // if it moved to the destination amt 1, copy it into
  // and shape list, reset the tween to null, amt to 0

  // ...
}

void mouseReleased() {
  if (shapes.size()==0) {
    shapes.add(randomPShape(points));
  } else {
    tweenShape = randomPShape(points);
  }
}

/**
 * Returns a random shape
 */
PShape randomPShape(int points) {
  PShape newPShape = createShape();

  // ...

  return newPShape;
}

/**
 * Takes two shapes, return a new shape of interpolated.
 * May give unexpected results if two shapes do not have
 * the same number of points.
 */
PShape lerpShape(PShape s1, PShape s2, float amt) {
  PShape tween = createShape();

  // ...

  return tween;
}

For past discussion and example code of lerpShape, check out:

Thank you your help is very appreciated :slight_smile:
I’ll try to do it, but for me seems to complicated and messy. I mean, if I had only this shape maybe it can be ok performing this trick, but in my case the code is 100x more complicated :frowning:

Thank you so much!

Well, if you have hundreds of things you can put these components into a class or multiple classes. I did not suggest a class-based solution because your original code examples did not contain classes.

I am not sure what you mean by “messy.” Could you explain more what you mean? Your original code uses three parallel arrays to represent a single set of objects. The approach proposes one array to represent one set of objects.

Note also that a single tween can be anything – so if you have lists of triangles, rectangles, and octagons running around, you can use a single tween PShape in three loops or fifty to render all the tweens for each type, and to store any type for any list.

ArrayList<PShape> triangles;
ArrayList<PShape> rectangles;
ArrayList<PShape> octogons;
PShape tweenShape;

Or use your own object classes with an interface:

ArrayList<MyTriangle> triangles;
ArrayList<MyRectangle> rectangles;
ArrayList<MyOctogon> octogons;
PShape tweenShape;

Or your own list classes:

TriangleList triangles;
RectangleList rectangles;
OctogonList octogons;
PShape tweenShape;

Or a superlist of all your shape interfaces:

ArrayList<MyShapes> shapes;
PShape tweenShape;

or

ShapeList shapes;
PShape tweenShape;

What I meanis that for simple task it can be a good trick to do :slight_smile:
But, in my case specifically, the shape will be not just a triangle or rectangle, but a number of triangle creating a Delaunay obj. If you will use, let’s stay easy, 10 points per Delaunay obj it will result in so many triangles, with so many duplicates and so many individual lerp calculation per point that is not convenient in computational terms :slight_smile:
In a simplified scenario (like the mesh library does) if two triangles has 2 points in common the total points are 4, but in your case I think that even if two triangles have some commons points, the total points are the sum of those, multiplied by 2 because of the functional shape you are adding, or am I wrong?

I am trying to understand – the problem you raise of shared points being inefficient is already present in your original example, whether or not you use lerp and whether or not you use tweening.

It sounds like you may now be describing a different problem from your initial example.

Is your goal to animate a Delaunay object, or animate a single mesh seeded by a Delaunay? If so, why is your simplified code based on an ArrayList and creating new triangles? Why store PShapes at all if they are just an ephemeral render-time object? Yes, if you represent your Delaunay object as a bunch of separate triangles, that does duplicate points. Can you describe that different problem, and / or provide a different example? Will you have one Delaunay object, or many? Is the target object a perturbation of the original points that preserves the edges, or are the edges recomputed on the point set (can lines break and reform)? Do you need to be able to perform operations like adding or deleting points or faces as the animation progresses, or are the number of points / faces conserved? Et cetera.

In general, one way of animating a mesh of triangle regions, e.g. with the mesh library, is like this:

  1. create points: float[][] points
  2. define mesh: Delaunay myDelaunay = new Delaunay(points)
  3. get links: int[][] myLinks = myDelaunay.getLinks();
  4. from links, build a list of int[][] myTriangles indexes that point to points

Now, draw / animate with the data structures myTriangles and points:

  1. animate points by changing values in points. For example, if you want to lerp, create a float[][] pointsDestinations and iterate over the points to lerp each one.
  2. iterate over myTriangles to access each one’s points and draw the updated mesh regions.

This method avoids multi-updating points. The first step that isn’t implemented in the mesh library is step 4, which you only have to do once – although I think there might be an example in the old Triangulate library.

Note that once you update the point locations on a Delaunay mesh, it may not satisfy the Delaunay condition anymore – if you resubmitted the points to define a new mesh, you might get different edges, due to “flipping”:

Of course, if you were computing a new Delaunay mesh every frame then the frame-to-frame flipping might be a pretty distracting artifact.

1 Like

I’ll try to better explain myself :slight_smile:

the problem you raise of shared points being inefficient is already present in your original example, whether or not you use lerp and whether or not you use tweening.

Are you talking about the exmples with only triangles? Every shape is a separate entity, I can’t see how they can have common points… For the Delaunay, isn’t the mesh library avoiding common points? And even if it doesn’t: already duplicated points + new duplicated points = double duplicated points.

Is your goal to animate a Delaunay object, or animate a single mesh seeded by a Delaunay?

If I understood correctly your question, are you asking me if I want to create a Delaunay object and then interpolate it’s points without another Dealunay calculation or if I want move the points continuosly calculation Delaunay triangulation? Doesn’t matter, if it’s easier even the first approach is useful, I don’t need to have a perfect Delaunay triangulation, I like that kind of shape but no needs to be perfect. Or interpolating from the center to the Delaunay position, or from the previous Delaunay points position to the new Delaunay, all without loosing from the screen the previous shape

If so, why is your simplified code based on an ArrayList and creating new triangles?

How do I mantain all the shape visible on screen without displaying them everytime iterating an Array? I’m sorry, but I only know this method
I used triangle as a generic shape, I thought that I would be able to adapt it to my Delaunay case

Why store PShapes at all if they are just an ephemeral render-time object?

Same as before, is there another method to always display shapes on screen beside storing in an ArrayList and displaying them?

Will you have one Delaunay object, or many?

many, as my previous posts and examples, I want to be able to create a new interpolating Delaunay without erase from the screen the previous. I’m able to create a new shape everytime I mouseClick, I’m able to create and interpolating Delaunay everytime I mouseClick, but I’m not able to do it in the same sketch

import megamu.mesh.*;

int numPoints = 10;
int dimension = 200;
int yoffset = 0;
float xoff = 0.0;
int coin;

float[][] points = new float[numPoints][2];
float[][] newPoints = new float[numPoints][2];
float[][] offset = new float[numPoints][2];

ArrayList<Delaunay> delaunayList = new ArrayList<Delaunay>();

int debNum = 200;

void setup() {
  size(600, 500, P3D);
  
  for (int i = 0; i < numPoints; i++) {
    for (int  j = 0; j < 2; j++) {
      points[i][j] = (int) random(dimension);
      newPoints[i][j] = points[i][j];
      offset[i][j] = random(0.1, 0.3);
    }
  }
}

float camNoise = 0;
float xcamoffset;

void draw() {
  background(255);

  //Change height of the camera with mouseY
  xcamoffset = map(noise(camNoise), 0.0, 1.0, -100, 100);
  camera(xcamoffset, yoffset, 400, xcamoffset, yoffset, 0, 0, 1, 0);
  camNoise+=0.01;
  
  coin = (int) random(100);
  if (coin < 10) {
    createDelaunay();
  }

  for (int i = 0; i < numPoints; i++) {
    for (int  j = 0; j < 2; j++) {
      points[i][j] = lerp(points[i][j], newPoints[i][j], offset[i][j]);
    }
  }

  for (int i = 0; i < delaunayList.size(); i++) {

    float[][] myEdges = delaunayList.get(i).getEdges();

    for (int j = 0; j < myEdges.length; j++) {
      float startX = myEdges[j][0];
      float startY = myEdges[j][1];
      float endX = myEdges[j][2];
      float endY = myEdges[j][3];
      line( startX, startY, endX, endY );
    }

    int[][] myLinks = delaunayList.get(i).getLinks();

    for (int k = 0; k < myLinks.length; k++) {
      int startIndex = myLinks[k][0];
      int endIndex = myLinks[k][1];

      float startX = points[startIndex][0];
      float startY = points[startIndex][1];
      float endX = points[endIndex][0];
      float endY = points[endIndex][1];

      line( startX, startY, endX, endY );
    }
  }
}

void createDelaunay() {
  for (int i = 0; i < numPoints; i++) {
    newPoints[i][0] = (int) random(dimension) + (map(noise(xoff), 0.0, 1.0, -width/2, width/2));
    newPoints[i][1] = (int) random(dimension) + yoffset;
  }
  xoff = xoff + 0.01;
  Delaunay myDelaunay = new Delaunay( points );
  delaunayList.add(myDelaunay);
  yoffset -= (int) random(5, 0);
}

This is the behaviour I want to achieve, but with the mesh library (and I can’t use the mesh library because I wasn’t able to find a way to fill the Delaunay object :disappointed_relieved:

Do you need to be able to perform operations like adding or deleting points or faces as the animation progresses, or are the number of points / faces conserved?

No, they remains always the same number

In general, one way of animating a mesh of triangle regions, e.g. with the mesh library, is like this:
etc

The code I provided you is an already working interpolating Delaunay object with the mesh library

I hope I didn’t forgot anything :smiley: Thank you!

Well, yes and no.

Your code is drawing collections of edges.

line( startX, startY, endX, endY );

Above I suggested a similar approach, but with the key difference that you draw collections of triangles.

Then you can render them with, e.g., fill() and triangle().

This is key. If your points are organized in lines, you don’t have to store a bunch of “line” PShapes to loop over. You can just create a loop and call line(), as you do in your last example. So: If you points are organized in triangles, then again – no ArrayList of PShapes needed. Just loop over your points array and call triangle().

Thank you jeremydouglass, but I really can’t understand and practice with what you’re saying

Above I suggested a similar approach, but with the key difference that you draw collections of triangles .

How do I do that? as you see, I’ve got a collection of points from which I create line(), how do I arrange those lines to create a triangle()?

This is key. If your points are organized in lines, you don’t have to store a bunch of “line” PShapes to loop over. You can just create a loop and call line(), as you do in your last example. So: If you points are organized in triangles, then again – no ArrayList of PShapes needed. Just loop over your points array and call triangle().

in the example of my last post, line() is actually called in the draw() loop, are you saying that if I remove the iteration for the ArrayList it should work?

for (int i = 0; i < delaunayList.size(); i++) { // Can I remove this iteration?

float myEdges = delaunayList.get(i).getEdges();

for (int j = 0; j < myEdges.length; j++) {
  float startX = myEdges[j][0];
  float startY = myEdges[j][1];
  float endX = myEdges[j][2];
  float endY = myEdges[j][3];
  line( startX, startY, endX, endY );    // it's called inside draw()
}

int[][] myLinks = delaunayList.get(i).getLinks();

for (int k = 0; k < myLinks.length; k++) {
  int startIndex = myLinks[k][0];
  int endIndex = myLinks[k][1];

  float startX = points[startIndex][0];
  float startY = points[startIndex][1];
  float endX = points[endIndex][0];
  float endY = points[endIndex][1];

  line( startX, startY, endX, endY );     // it's called inside draw()
}

}

Here is one approach.

Created a TriangleMesh class that begins like this:

class TriangleMesh {
  float[][] points;       // point location data [pointID][x, y]
  int[][] links;          // links between points [linkID][id1, id2]
  int[][] linked;         // points linked to each point [pointID][pointID, pointID, ... pointID]
  int[][] trianglelinks;  // triangles listed by pointIDs [triangleID][pointID, pointID, pointID]
  int[] triangleColors;   // one color per triangle, used for filling
  TriangleMesh(float[][] points) {
    this.points = points;
    update();
  }
  [...]

Now the update() function needs to take points and use it to populate the other arrays: links, linked, and trianglelinks. This is a one-time computation. From then on, you can modify points in the array (with random drift, lerp, etc.) and you don’t need to update the trianglelinks, which index those points.

Let’s assume you have set up your links with Delaunay.getEdges (check that there are no bad edges), and your linked with Delaunay.getLinked (check that there are no bad entries). You can create a Delaunay from the mesh library during constructor / update time and then throw it away – you don’t need to store it in the object.

Now, how to index triangles? Here is an example of a naive class method:

  /**
   * Discover triangles in edges and list each triangle by point indices.
   * 
   * Uses a niave triangle finder. It explores all three-step links for
   * which the fourth point is equal to the first (a triangle).
   * It then checks for and removes triangles that enclose groups of other
   * triangles (a rare case).
   * 
   * @param pointCount  number of points indexed by edge list
   * @param linked      the list of edges, [edgeID][pid1, pid2]
   */
  void updateTriangles(int pointCount, int[][] linked) {
    HashSet<List<Integer>> triangles = new HashSet<List<Integer>>();
    for (int p1=0; p1<pointCount; p1++) {
      for (int p2 : linked[p1]) {
        for (int p3 : linked[p2]) {
          if (p3 != p1) {
            for (int orig : linked[p3]) {
              if (orig == p1) {
                List<Integer> tpoints = new ArrayList<Integer>();
                tpoints.add(p1);
                tpoints.add(p2);
                tpoints.add(p3);
                Collections.sort(tpoints);
                triangles.add(tpoints);
              }
            }
          }
        }
      }
    }

    this.cull(triangles); // cull rare enclosing triangles from triangles list

    // copy triangles into object
    this.trianglelinks = new int[triangles.size()][];
    int i=0;
    for (List<Integer> list : triangles) {
      // println(list.get(0), list.get(1), list.get(2));
      trianglelinks[i] = new int[]{list.get(0), list.get(1), list.get(2)};
      i+=1;
    }
  }
}

void updateTriangles() {
  this.updateTriangles(this.points.length, this.linked);
}

Note that this is totally unoptimized – but if you aren’t creating lots of meshes every frame, it might not matter, because it only runs once per object setup. Two general discussions of triangle finding algorithms: 1 2

The above class data structure and method gives me pretty good results looping over either links:points with line() or trianglelinks:points with triangle()

2 Likes

Sorry, I can’t understand this… how it can “save” and display all the previous object at the same time?
See this simple example (for not complicate it too much (for me ahah)):

void setup() {
  size(500, 400, P3D);
  frameRate(1);
}

void draw() {
  background(0);
  Boxx box = new Boxx();
}

class Boxx:

class Boxx {

  int boxWidth, posX, posY;

  Boxx() {
    boxWidth = 50;
    posX = (int) random(width);
    posY = (int) random(height);
    display();
  }

  void display() {
    translate(posX, posY);
    box(boxWidth);
  }
}

As you can see I call display(); method in the contructor, and I’m creating a Boxx in draw, but when I created a new Boxx the old one disappear… How do I let it stay on screen without iteration an ArrayList of Boxx?

Sorry man if I’m not on your level!
Thank you so much!

1 Like

As I mentioned above, there are many ways to do that, but you had one correct approach initially – globals for:

  1. an array of past (unmoving) objects
  2. a current, moving object
  3. a destination

Like this:

ArrayList<Boxx> pastBoxxes;  // non-moving boxxes -- was ArrayList<PShape> shapes
Boxx currentBoxx;  // the moving boxx -- was ArrayList<PVector> olPosition
Boxx futureBoxx;  // the inviisble mouse click target boxx -- ArrayList<PVector> newPosition
  • setup():
    • create a currentBoxx at the middle of the screen
    • , then add it to pastBoxxes.
  • mouseReleased(): (not mousePressed)
    • create a futureBoxx at the mouse point
  • draw():
    • loop over pastBoxxes and draw them. **or display image – (see note)
    • check if futureBoxx exists (we are moving). If it does:
      • lerp currentBoxx towards futureBoxx by amt
        • If the first point of future and first point of current are equal: (we arrived)
          • set futureBoxx to null
          • add copy currentBoxx to postBoxxes
          • **optionally, draw last pastBoxx onto image – (see note)
          • break out of the lerp (all other points will also be equal)
      • draw the currentBoxx

** Note: there is a way to greatly optimize this step by replacing it with an image() call to a PGraphics buffer. Now instead of drawing every pastBoxx every frame, you only draw a single new pastBoxx on top of the existing PGraphics image once every time currentBoxx arrives at a destination. The PGraphics image accumulates your collection of past Boxxes as a pure image, and you display it once every frame, which is blazing fast compared to redrawing everything every time. If you need to modify the past Boxxes then you redraw the full PGraphics buffer from the ArrayList.

So, to summarize, there are two major optimizations:

  1. compute triangle links only once as index lookups, which makes drawing triangle meshes simple and avoids the need for costly duplicate point interpolations.
  2. as in the Note, accumulate your background drawing on an image, and only redraw things that are actually moving – your current Boxx.
ArrayList<Boxx> pastBoxxes;  // non-moving boxxes -- was ArrayList<PShape> shapes
Boxx currentBoxx;  // the moving boxx -- was ArrayList<PVector> olPosition
Boxx futureBoxx;  // the invisible mouse click target boxx -- ArrayList<PVector> newPosition
Boolean futureBoxxExist;

void setup() {
  size(500, 400, P3D);
  pastBoxxes = new ArrayList<Boxx>();
  currentBoxx = new Boxx(width/2, height/2);
  //pastBoxxes.add(currentBoxx);
  futureBoxxExist = false;
}

void draw() {
  background(255);

  for (Boxx box : pastBoxxes) {
    box.display();
  }

  if (futureBoxxExist) {
    currentBoxx.move((int) lerp(currentBoxx.getPosX(), futureBoxx.getPosX(), 0.5), (int) lerp(currentBoxx.getPosY(), futureBoxx.getPosY(), 0.5));
    if (currentBoxx.getPosX() == futureBoxx.getPosX()) {
      futureBoxx = null;
      pastBoxxes.add(currentBoxx);
      futureBoxxExist = false;
    }
    currentBoxx.display();
  }
}

void mouseReleased() {
  futureBoxx = new Boxx(mouseX, mouseY);
  futureBoxxExist = true;
}

class Boxx {

  int boxWidth, posX, posY;

  Boxx(int posX, int posY) {
    boxWidth = 50;
    this.posX = posX;
    this.posY = posY;
  }
  
  void move(int posX, int posY){
    this.posX = posX;
    this.posY = posY;
  }

  void display() {
    translate(posX, posY);
    box(boxWidth);
  }

  int getPosX() {
    return posX;
  }

  int getPosY() {
    return posY;
  }
}

Thank you so much for your help and patience, is really appreciated here :slight_smile:

So… like this we are creating two Boxx, a “fake” one where the real will be, and the real. They are both created when mouseRelease() and then, the real move towards the fake. When the real reach the fake, there’s no need to write them anymore because nothing is moving so, we remove the fake one. But doesn’t we always iterate and draw (like I did) one shape?

Would you please write a direct comparation of the two codes? Because right now I can’t see this behaviour… Please keep it simple as the Boxx example I posted :slight_smile:

In my example, now I’m actually drawing Boxxes following your instructions, but as you can see, something go wrong with the move() method and translate()…

Thank you soooo much!

1 Like

Let’s deal with that first. Your “translate()” statements are commands to the main canvas, so they pile up – each box is translated relative to the previous box, by the sum of all the previous boxes.

To fix that, isolate with pushMatrix:

  void display() {
    pushMatrix();
    translate(posX, posY);
    box(boxWidth);
    popMatrix();
  }

Now you can see that all of your boxes are always in the same place – what is going on?

Well, they are all the same box!

  for(Boxx boxx : pastBoxxes){
    println(boxx);
  }

sketch_180926a$Boxx@6b3b2539
sketch_180926a$Boxx@6b3b2539
sketch_180926a$Boxx@6b3b2539
sketch_180926a$Boxx@6b3b2539

So every time you do this:

pastBoxxes.add(currentBoxx);

…you are adding yet another reference to the same box, over and over again. The ArrayList has many references to the same object, so when you update the object, all the entries in the list slide (they are all one thing).

To get around this, add a copy method to the object.

  Boxx copy() {
    return new Boxx(posX, posY);
  }

…and use it:

      pastBoxxes.add(currentBoxx.copy());
2 Likes

There is also something tricky going on with your use of lerp. It relates to Zeno’s paradox – your lerp may never reach it’s exact destination (equal floating point values), depending on the amount setting and the direction of relative motion.

To make that more robust, add some global variables:

float lerpSpeed;
int lerpNear;

…and define them in setup:

  lerpSpeed = 0.05;
  lerpNear = (int)(1/lerpSpeed) + 1;

…and then use them in your arrival check:

  for (Boxx box : pastBoxxes) {
    stroke(0);
    box.display();
  }
  if (futureBoxx!=null) {
    currentBoxx.move((int) lerp(currentBoxx.getPosX(), futureBoxx.getPosX(), lerpSpeed), (int) lerp(currentBoxx.getPosY(), futureBoxx.getPosY(), lerpSpeed));
    println(1/lerpSpeed, ':', abs(currentBoxx.getPosX() - futureBoxx.getPosX()));
    if (abs(currentBoxx.getPosX() - futureBoxx.getPosX()) < lerpNear) {
      pastBoxxes.add(currentBoxx.copy());
      futureBoxx = null;
      println(pastBoxxes.size());
    }
    stroke(255,0,0);
    currentBoxx.display();
  }

Now notice also that when you check only x, steep movement angles are a problem – for example, try clicking directly below or above, and you will see that your shape stops immediately. You want to check distance instead (you could use PVector for this).

Another approach to this entire problem is not to have a currentBoxx at all – instead, keep a global amt variable that you increment from 0-1 during movement time time, and draw the moving boxx image as a live interpolation of that amt value and the positions, rather than incrementing individually stored x and y variables. This approach is, in general, much more robust, because you aren’t doing compound floating point division. On the downside, you don’t get that nice decelerating effect at slow speeds unless you add it back in.