2

I'm looking for a way for the balls to blur when the approach the edge of the screen. they should transition back to sharp focus when they approach the centre.

Do you have any advice of how to achieve it?

Hope it makes sense!

   ArrayList < Ball > list = new ArrayList();

   void setup() {
    fullScreen();
     for (int iter = 0; iter < 7; iter++) //qty of balls on the screen
      list.add(new Ball());
   }

   void draw() {
     background(0);
     for (Ball thisBall: list)
       thisBall.render();
   }

   class Ball {
     //1.Attributes
     float xPos, yPos, xSpeed, ySpeed;
     float size;
     color colour;

     //2.Constructor
     Ball() {
       xPos = width / 2;
       yPos = height / 2;
       xSpeed = random(-4, 4);
       ySpeed = random(-4, 4); 
       size = random(700, 1000); 
       colour = color(random(0,255), random(0,255), random(0,255));
     }

     //3.Actions
      void render() {
        stroke(colour,100);
        fill(colour, 100);
        ellipse(xPos, yPos, size, size);
        xPos += xSpeed;
        yPos += ySpeed;
        if (xPos < 0)
         xSpeed *= -1;
        if (xPos > width)
          xSpeed *= -1;
        if (yPos < 0)
         ySpeed *= -1;
        if (yPos > height)
         ySpeed *= -1;
     }
   }

N

pronia
  • 21
  • 1
  • If the blur "progressive", as in "the closer they are to the center the less blurry they are"?? – laancelot Nov 02 '20 at 23:37
  • May be you must try to work around the shader. Few time ago I work around that, may be you can find something that can help you https://github.com/StanLepunK/Shader – Knupel Nov 03 '20 at 08:58
  • @laancelot - yes, it would be great if it was progressive! – pronia Nov 03 '20 at 09:39
  • @Knupel, thank you,I'll give it a try and will get back to you if I have any questions! – pronia Nov 03 '20 at 09:40

1 Answers1

1

There are several ways to do this... although I feel like the "normal" ones won't be what you're looking for.

1

First, the obvious: there's a blur filter already available in Processing. But it blurs the whole image. You could still use it successfully by drawing the "blurred circles" first, blurring the image then drawing the sharp circles.

But There's two problems here: first I'm pretty sure that it won't be the result you're looking for. Second, that method is awfully costly. Unless you have a monster machine, it'll slow down.

2

You can draw an already blurred circle to a PImage and use it instead of the sharp circle when the blur conditions applies. While this approach would work, I still doubt that you're looking for this. I'm giving you some code in case you want to try it yourself (but only the Ball class, as the rest doesn't have to change):

class Ball {
  //1.Attributes
  PGraphics blurredCircle;
  boolean blur;
  float xPos, yPos, xSpeed, ySpeed, blurSize;
  float size;
  color colour;

  //2.Constructor
  Ball() {
    blur = false;
    blurSize = 200;
    xPos = width / 2;
    yPos = height / 2;
    xSpeed = random(-4, 4);
    ySpeed = random(-4, 4); 
    size = random(700, 1000);
    colour = color(random(0, 255), random(0, 255), random(0, 255));

    // drawing a blurred circle to memory
    blurredCircle = createGraphics((int)(size+2*blurSize), (int)(size+2*blurSize), P2D);
    blurredCircle.beginDraw();
    blurredCircle.background(0, 0, 0, 0); // using transparency to avoid drawing a white rectangle around the circle
    blurredCircle.stroke(colour, 100);
    blurredCircle.fill(colour, 100);
    blurredCircle.ellipseMode(CENTER);
    blurredCircle.ellipse(blurredCircle.width/2, blurredCircle.height/2, size, size);
    blurredCircle.filter(BLUR, blurSize);
    blurredCircle.endDraw();
  }

  //3.Actions
  void render() {
    if (blur) {
      imageMode(CENTER);
      image(blurredCircle, xPos, yPos);
    } else {
      stroke(colour, 100);
      fill(colour, 100);
      ellipse(xPos, yPos, size, size);
    }

    UpdateSpeed();
    UpdateBlur();
  }

  void UpdateSpeed() {
    xPos += xSpeed;
    yPos += ySpeed;

    // direction
    if (xPos < 0 || xPos > width) {
      xSpeed *= -1;
    }
    if (yPos < 0 || yPos > height) {
      ySpeed *= -1;
    }
  }

  void UpdateBlur() {
    int blurDistance = 50;
    blur = xPos < 0 + blurDistance || xPos > width - blurDistance || yPos < 0 + blurDistance || yPos > height - blurDistance;
  }
}

3

This one is kind of just me trying to get some interesting result. I drew a blurred circle to a PImage then adjusted the algorithm so there's a "core" circle which size never change with a "blurred" circle getting bigger as it gets near the border:

Custom technique

ArrayList < Ball > list = new ArrayList();

void setup() {
  //fullScreen(P2D);
  size(500, 500, P2D);
  for (int iter = 0; iter < 5; iter++) //qty of balls on the screen
    list.add(new Ball());
}

void draw() {
  background(0);

  // way better!
  for (Ball thisBall : list)
    thisBall.render();
}

class Ball {
  //1.Attributes
  PGraphics blurredCircle;
  float xPos, yPos, xSpeed, ySpeed, blurSize, blur, blurDistance, maxBlurPercentIncrease;
  float size;
  color colour;

  //2.Constructor
  Ball() {
    blur = 1;
    blurSize = 200;
    blurDistance = 200;
    maxBlurPercentIncrease = 75;
    xPos = width / 2;
    yPos = height / 2;
    xSpeed = random(-2, 2);
    ySpeed = random(-2, 2); 
    size = random(200, 400);
    colour = color(random(0, 255), random(0, 255), random(0, 255));

    // drawing a blurred circle to memory
    blurredCircle = createGraphics((int)(size+2*blurSize), (int)(size+2*blurSize), P2D);
    blurredCircle.beginDraw();
    blurredCircle.background(0, 0, 0, 0); // using transparency to avoid drawing a white rectangle around the circle
    blurredCircle.noStroke();
    blurredCircle.fill(colour, 100);
    blurredCircle.ellipseMode(CENTER);
    blurredCircle.ellipse(blurredCircle.width/2, blurredCircle.height/2, size, size);
    blurredCircle.filter(BLUR, blurSize);
    blurredCircle.endDraw();
  }

  //3.Actions
  void render() {
    UpdateBlur();

    float currentSize = size * blur;
    imageMode(CENTER);
    image(blurredCircle, xPos, yPos, currentSize, currentSize);
    noStroke();
    fill(colour, 100);
    ellipse(xPos, yPos, size/2, size/2);
    fill(255);

    UpdateSpeed();
  }

  void UpdateSpeed() {
    xPos += xSpeed;
    yPos += ySpeed;

    // direction
    if (xPos < 0 || xPos > width) {
      xSpeed *= -1;
    }
    if (yPos < 0 || yPos > height) {
      ySpeed *= -1;
    }
  }

  void UpdateBlur() {
    float[] values = { xPos, yPos, abs(xPos-width), abs(yPos-height) };
    float min = min(values);
    if (min == 0) {
      min = 1;
    }

    blur = 1;
    if (min < blurDistance) {
      float adjustment = ((blurDistance-min)/blurDistance)*maxBlurPercentIncrease;
      if (adjustment > 5) {
        blur += adjustment/100;
      }
    }
  }
}

I'm encouraging you to experiment along these lines as I imagine you have something precise in mind. Good luck!

laancelot
  • 3,138
  • 2
  • 14
  • 21