处理-从屏幕边缘反弹时,球会暂时模糊

问题描述

我正在寻找一种使球接近屏幕边缘时模糊的方法。当他们接近中心时,应该过渡到清晰的焦点。

您对如何实现它有任何建议吗?

希望有道理!

   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));
     }

     //3.Actions
      void render() {
        stroke(colour,100);
        fill(colour,100);
        ellipse(xPos,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

解决方法

有几种方法可以执行此操作...尽管我觉得“正常”的方法不是您想要的。

1

首先,显而易见的是:Processing中已经有一个blur filter。但这会使整个图像模糊。您仍然可以成功使用它,方法是先绘制“模糊的圆圈”,先模糊图像,再绘制尖锐的圆圈。

但是这里有两个问题:首先,我很确定这不会是您要寻找的结果。其次,该方法的成本非常高。除非您有怪物机器,否则它将减速。

2

您可以在PImage上绘制一个已经模糊的圆圈,并在应用模糊条件时使用它代替尖锐的圆圈。尽管这种方法可行,但我仍然怀疑您是否正在寻找这种方法。如果您想自己尝试,我会给您一些代码(但仅Ball类,其余的无需更改):

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));

    // drawing a blurred circle to memory
    blurredCircle = createGraphics((int)(size+2*blurSize),(int)(size+2*blurSize),P2D);
    blurredCircle.beginDraw();
    blurredCircle.background(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,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

这只是我试图获得一些有趣结果的一种方法。我在PImage上画了一个模糊的圆圈,然后调整了算法,以便有一个“核心”圆圈,它的大小永远不会改变,而“模糊”圆圈在靠近边界时会变大:

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,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,0); // using transparency to avoid drawing a white rectangle around the circle
    blurredCircle.noStroke();
    blurredCircle.fill(colour,blurSize);
    blurredCircle.endDraw();
  }

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

    float currentSize = size * blur;
    imageMode(CENTER);
    image(blurredCircle,currentSize,currentSize);
    noStroke();
    fill(colour,100);
    ellipse(xPos,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,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;
      }
    }
  }
}

我鼓励您按照这些思路进行试验,因为我想您会想到一些精确的内容。祝你好运!