Optimization of Lissajous table

I created code, that animates creation of lissajous table. It works properly, but sometimes, when the first circle travels almost entire lap it slows down dramatically. How can I optimize this code:

void calculations()
  {
    float line1 = 0, plane = 0, line2 = 0;
    float inside = 0, sizePlusOfset = size + offset;
    
    if (whatLine)
    {
      line1 = cols;
      line2 = rows;
      plane = height;
      centerY = offset;
    } else
    {
      line1 = rows;
      line2 = cols;
      plane = width;
      centerX = offset;
    }

    for (int i = 0; i < line1; i++) 
    {
      if (whatLine)
      {
        centerX = sizePlusOfset + i * size;
      } else
      { 
        centerY = sizePlusOfset + i * size;
      }

      inside = angle * (i + factor) - HALF_PI;

      x = radius * cos(inside);
      y = radius * sin(inside);

      for (int j = 0; j < line2; j++) 
      {

        if (whatLine)
        {
          curves.get(j).get(i).setX(centerX + x);
        } else
        {
          curves.get(i).get(j).setY(centerY + y);
        }
      }

      strokeWeight(1);
      stroke(255, 230);
      ellipse(centerX, centerY, diameter, diameter);
      strokeWeight(8);
      point(centerX + x, centerY + y);
      stroke(255, 150);
      strokeWeight(1);

      if (whatLine)
      {       
        line(centerX + x, 0, centerX + x, plane);
      } else
      {
        line(0, centerY + y, plane, centerY + y);
      }
    }
  }

  void show(boolean lisajousAction)
  {

    for (int i = 0; i < 2; i++)
    {
      calculations();
      whatLine = !whatLine;
    }   

    for (int j = 0; j < rows; j++) {
      for (int i = 0; i < cols; i++) {
        if (lisajousAction)
        {
          curves.get(j).get(i).addPoint();
        }
        curves.get(j).get(i).show();
      }
    }

    angle -= angleChange1 * delta_time;

    // If the angle is - two pi, the first circle has traveled the entire lap.
    
    float inverseFactor = abs(1/factor);
    
    if (angle < -TWO_PI * inverseFactor) {

      for (int j = 0; j < rows; j++) {
        for (int i = 0; i < cols; i++) {
          curves.get(j).get(i).reset();
        }
      }      
      angle = 0;
    }
  }

I know that one way to optimize this code would be to check if a given pixel is entered into the table and not enter it into the table, but I don’t know how to do it optimally. Entire code needed to run it is here: Lisous_Table - Pastebin.com

Hello,

There are several things I can think of.

From what I understand, you are computing the points, then add them to an array and then redraw everything every frame. It can indeed be quite a lot of things to handle.

The first thing is that you can easily compute the period for each figure. So you know that once this period is reached, you don’t need to save any new points.

Another thing possible is to pre-calculate a set of points for each figure. Then, for animating, you will need to figure out until which points you’ll have to draw based on your elapsed time.

Another way would be to not store any points at all and simply draw a straight line between the previous point and the current point on another PGraphic and display this PGraphic. The idea is to never clear this PGraphic so the lines are accumulating on it. (Not sure about the quality of the result though)…

How can I know the period of a random figure and not add points to it?

The figures are not random at all.
The period of the resulting figure will be the LCM of the period of the top circle and the period of the left circle.

So if period 1 is 2 and period 2 is 4 then LCM(2, 4) = 4 for your figure.
If period 1 is 2 and period 2 is 3 then LCM(2, 3) = 6 for you figure.

I meant choosing a random figure, not that they are random. What LCD mean?

I meant LCM, I edited my post.

It was enough to add checking if a given point was added to the list and this program doesn’t slow down now.

for (int j = 0; j < rows; j++) {
      for (int i = 0; i < cols; i++) {
        
        boolean isEqualToX = false, isEqualToY = false;

        for (int k = 0; k < curves.get(j).get(i).path.size(); k++)
        {
          if (curves.get(j).get(i).path.get(k).x >= curves.get(j).get(i).current.x - 0.01 && curves.get(j).get(i).path.get(k).x <= curves.get(j).get(i).current.x + 0.01)
          {
            isEqualToX = true;
          }

          if (curves.get(j).get(i).path.get(k).y >= curves.get(j).get(i).current.y - 0.01 && curves.get(j).get(i).path.get(k).y <= curves.get(j).get(i).current.y + 0.01)
          {
            isEqualToY = true;
          }
        }

        if (lisajousAction && !isEqualToX || !isEqualToY) 
        {
          curves.get(j).get(i).addPoint();
        }
        curves.get(j).get(i).show();
      }
    }
1 Like