My sketch is smooth until i zoom in (drop to 15fps)

Hello there, for a school project, i’ve created a map with bus point and density at these bus point.
Everything works fine except the frame rate when i zoom in with the slider. But i can’t remove it cause the teacher wants it.

Can you help me with this low frame rate when zooming? :slight_smile:

float width2 = 1600;
float height2 = 900;
float zoom = 1;
int mouseTransformX = 0;
int mouseTransformY = 0;
boolean hoverSlider = false;

//Position des lignes
float roadCoord [] [] = {
  {//x1
    width2/10.2, width2/4, width2/3.2, width2/2.26, width2/2.03, width2/1.7, width2/1.49, width2/1.43, width2/1.28, width2/1.305, width2/1.455, width2/1.465, width2/1.49, width2/1.515, width2/1.76, width2/1.9, width2/2.2, width2/2.24, width2/3.02, width2/3.58, width2/5.155, width2/6.1, width2/6.66, width2/7.6
  }, 
  {//y1
    height2/2.05, height2/3.4, height2/3.7, height2/4, height2/3.95, height2/4.2, height2/3.5, height2/3.22, height2/2.9, height2/2.4, height2/2.35, height2/1.7, height2/1.5, height2/1.28, height2/1.415, height2/1.458, height2/1.62, height2/1.4, height2/1.48, height2/1.26, height2/1.205, height2/1.32, height2/1.36, height2/1.6
  }, 
  {//x2
    width2/4, width2/3.2, width2/2.26, width2/2.03, width2/1.7, width2/1.49, width2/1.43, width2/1.28, width2/1.305, width2/1.455, width2/1.465, width2/1.49, width2/1.515, width2/1.76, width2/1.9, width2/2.2, width2/2.24, width2/3.02, width2/3.58, width2/5.155, width2/6.1, width2/6.66, width2/7.6, width2/10.2
  }, 
  {//y2
    height2/3.4, height2/3.7, height2/4, height2/3.95, height2/4.2, height2/3.5, height2/3.22, height2/2.9, height2/2.4, height2/2.35, height2/1.7, height2/1.5, height2/1.28, height2/1.415, height2/1.458, height2/1.62, height2/1.4, height2/1.48, height2/1.26, height2/1.205, height2/1.32, height2/1.36, height2/1.6, height2/2.05
  }
};

//Position des Arrets
float arretCoord [] [] = {
  {
    width2/10.2, width2/3.2, width2/2.03, width2/1.28, width2/1.465, width2/1.76, width2/3.02
  }, 
  {
    height2/2.05, height2/3.7, height2/3.95, height2/2.9, height2/1.7, height2/1.415, height2/1.48
  }, 
};

Slider slider1 = new Slider();
Arret [] multArret = new Arret[arretCoord[0].length];
Road [] multRoad = new Road[roadCoord[0].length];

PImage img;

void setup() {
  size (1600, 900);
  img = loadImage("map1.jpg");  
  img.resize(width,height);
  
  frameRate(60);

  for (int i=0; i<multArret.length; i++) {
    multArret[i] = new Arret(arretCoord[0][i], arretCoord[1][i]);
  }
  for (int i=0; i<multRoad.length; i++) {
    multRoad[i] = new Road(roadCoord[0][i], roadCoord[1][i], roadCoord[2][i], roadCoord[3][i]);
  }
}

int count = 0;
int speed = 2;
int position = 0;
void draw() {
  
  count += speed;
  println(count);
  println(speed);
  if (count>200 || count <-200){
    speed = speed*-1;  
  }
  
  clear();
  scale(slider1.valueZoom());
  translate(mouseTransformX, mouseTransformY);
  image(img, position +=speed, 0, width, height);
  translate(position +=speed, 0);
  stroke(255, 0, 0);
  strokeWeight(3);

  //boucle qui affiche tous les arrêts du tableau jusqu'à ce qu'il arrive au bout
  for (int i=0; i<multArret.length; i++) {
    multArret[i].affichage();
    multArret[i].countDensity();
    multArret[i].popup(slider1.valueZoom());
  }
  for (int i=0; i<multRoad.length; i++) {
    multRoad[i].affichage();
  }

  //toutes les 101 frames, met à jour les arrêts
  if (frameCount%200 >=199) {
    for (int i=0; i<multArret.length; i++) {
      multArret[i].majPeople();
    }
  }

  slider1.affichage();
  text(frameCount, 100, 150);
  text(nf(frameRate, 1, 1)+" FPS", 100, 100);
}

void mouseDragged() {
  if (hoverSlider == false) {
    if (pmouseX < mouseX) {
      mouseTransformX += 1;
    }
    if (pmouseX > mouseX) {
      mouseTransformX += -1;
    } 
    if (pmouseY < mouseY) {
      mouseTransformY +=1;
    }  
    if (pmouseY > mouseY) {
      mouseTransformY +=-1;
    }
  }
}

class Slider {
  boolean clicked;
  float value;
  int positionLineX, positionLineY, size, posX, posY;

  Slider() {
    positionLineX = 30;
    positionLineY = 30;
    size = 300 + positionLineX;
    posX = positionLineX;
    posY = positionLineY;
    value = 0;
    clicked = false;
  }

  void affichage() {
    translate(-mouseTransformX, -mouseTransformY);
    translate(-position, 0); //empêche la barre de zoom de bouger en mettant la valeur inverse du mouvement
    fill(200);
    rectMode(CORNER);
    rect(0, 0, width, 60/value);
    stroke(0);
    strokeWeight(1/value);
    line(positionLineX/value, positionLineY/value, size/value, positionLineY/value);
    stroke(125);
    fill(125);
    ellipse(posX/value, posY/value, 20/value, 20/value);
    textSize(16/value);
    text(value * 100 + "%", (size/value) + 20/value, posY/value);


    if(mousePressed){
      if (dist(posX, posY, mouseX, mouseY)<11){
        clicked = true;
      }
      if (clicked && posX >= positionLineX && posX<=size){
        posX = mouseX;
      }
      if (posX < positionLineX){
          posX = positionLineX;
      } 
      else if (posX>size){
        posX = size;
      }
    }
    else if(mousePressed == false){
      clicked = false;
      hoverSlider= false;
    }
  }

  float valueZoom() {
    value = map(posX, positionLineX, size, 1, 2.5);
    return value;
  }
}

class Road {
  float x1, x2, y1, y2;
  Road (float posX1, float posX2, float posY1, float posY2) {
    x1 = posX1;
    x2 = posX2;
    y1 = posY1;
    y2 = posY2;
  }

  //fonction qui affiche les routes
  void affichage() {
    line(x1, x2, y1, y2);
  }
}

class Arret {
  float x, y, size;
  int maxT, currentT, newT, oldT, density;
  Arret(float posX, float posY) {
    x = posX;
    y = posY;
    size = 15;
    maxT = 100;
    currentT = round(random(10, 100));
    newT = round(random(10, 35));
    oldT = round(random(10, 35));
    density = round(map(currentT, 0, maxT, 0, 100));
  }

  //fonction qui affiche les arrêts
  void affichage() {
    fill(255, 0, 0, 55);
    ellipse(x, y, density, density);
  }

  void countDensity() {
    fill(50);
    text(currentT, x+density/2, y+density/2);
    textSize(32);
  }

  //fonction qui met à jour la densité des arrêts aléatoirement
  void majPeople() {
    
    if(currentT >100 || currentT <=0 ){
      currentT = round(random(10, 35));
    }
    else {
      newT = round(random(10, 35));
      oldT = round(random(10, 35));
      currentT += -newT + oldT;
    }
    density = round(map(currentT, 0, maxT, 0, 100));
    
  }

  void popup(float value) {
    if (dist((x + mouseTransformX + position)*value, (y + mouseTransformY)*value, mouseX, mouseY)< 100) {
      if (mousePressed) {
        rectMode(CENTER);
        fill(255, 255, 255, 180);
        rect(x + 100, y, 224, 72);
        textSize(16);
        fill(0);
        text(maxT + " : touriste MAXIMUM", x +12, y-16);
        text(currentT + " : touriste ACTUEL", x  +12, y +4);
        text(density +"%"+ " : densité", x +12, y +24);
      }
    }
  }
}

Could someone help me?

Hi,

Don’t worry someone is going to answer soon or later! :wink:

I found that commenting this single line solve the problem :

image(img, position +=speed, 0, width, height);

Looks like displaying an image after scaling the whole graphics is slowing down a lot…

By default Processing is using Java2D as the renderer but looking at the actual drawImage method of the Graphics class (which is called when using image() in Processing) , I was not able to find why it’s slowing down so much…

Rotating the whole coordinate system is also slowing down to 20 fps. Modifying the affine transform of the Graphics window should slow down the rendering but not that much.

Maybe someone knows?

When you scale an image it resizes at an enormous cost of calculations, however, you can get a better result using another renderer.
Try size (1600, 900, FX2D );

1 Like