如何让我的函数在多次调用时产生不同的结果?

问题描述

我正在使用草图语言处理来创建尝试创建图像。在大多数情况下,我的代码关闭功能正常,但我的函数fade() 遇到了问题,该函数旨在为我绘制的形状创建淡入淡出效果。我的问题是我多次调用这个函数(对于我绘制的每个矩形),我希望这个函数效果对于每个矩形都是唯一的。我在函数fade() 中使用随机性来尝试实现这一点,但无济于事。当我运行程序时,我绘制的所有矩形都一起淡入淡出,而不是单独淡入淡出。

我在下面附上了我的代码,以便更好地了解我遇到的问题。我觉得我的代码方法论中有一个简单的解决方案,但我不能完全放置它。如果您有任何建议或认为我应该更改的地方,请告诉我。

int f = 0;
boolean fadingIn = true;
int time = millis();
float randomHold;
float randomFade;

void setup(){
  size(600,560);
  rectMode(CENTER);
}

void draw(){
  background(0);
  noFill();
  strokeWeight(3);
  
  randomHold = random(3,8);
  randomFade = random(0,2);
  
  // Bottom Right Corner
  stroke(random(0,255),random(0,fade());
  rect(540,500,100,10);
  
  // Right Side (bottom first)
  stroke(random(0,390,10);
  stroke(random(0,280,170,60,10);
}

int fade(){
  
  if (f >= 255){
    if ((millis() - time) >= (1000*randomHold))
    {
      fadingIn = false;
      time = millis();
      randomHold = random(3,8);
    }
  } else if (f <= 0){
    if ((millis() - time) >= (1000*randomHold))
    {
      fadingIn = true;
      time = millis();
      randomHold = random(3,8);
    }
  }
  
  if (fadingIn){
    f += (int)randomFade;
    randomFade = random(0,2);
  }
  
  if (!fadingIn){
    f -= (int)randomFade;
    randomFade = random(0,2);
  }
  
  return f;
}

解决方法

在数学中,您可能还记得通过“垂直线测试”的东西被称为“函数”。这意味着它对于某个输入只有一个输出,这意味着如果每次将相同的输入参数传递给一个函数,它每次都会给出相同的输出。至少,它在数学中是这样运作的。

计算机科学意义上的“函数”可以为相同的输入提供不同的输出(通常根本没有输入)。一个例子是 random(low,high) 函数。 random(low,high) 如何返回不同的值?好吧,看起来可能只有两个输入,但在数学意义上的“函数”是什么,random(low,high) 有一个 第三 输入:种子。如果您运行以下代码:

void draw() {
  randomSeed(23410832);
  println(random(0,255));
}

您会看到,如果每次都将种子设置为相同的值,则 random(low,high) 每次都会产生相同的输出。

您似乎掌握了这一点,因为您使用了“奖励”输入 ftimerandomHoldfadingIn,并且您更改了它们中的每一个每次运行该函数时*。问题是:你没有改变它们足够

*(你也有奖金变量 randomFade,但 fade() 函数不直接影响那个)

如果您以类似于上面的 draw() 循环的方式运行代码:

void draw() {
  println(fade());
}

您会注意到从一次调用到下一次调用的输出变化不大。它逐渐上升到 255,然后回落到 0,然后回升,依此类推。您正在寻找的是每五个调用逐渐变化的东西,但从一个到下一个急剧变化,有点像这样:

  • fade() 输出 1
  • fade() 输出 150
  • fade() 输出 68
  • fade() 输出 233
  • fade() 输出 100
  • fade() 输出 2
  • fade() 输出 149
  • fade() 输出 67
  • fade() 输出 234
  • fade() 输出 99

这样做的方法是给 fade() 一个输入,然后用五个不同的输入一遍又一遍地调用它:

  • fade(1) 输出 1
  • fade(2) 输出 150
  • fade(3) 输出 68
  • fade(4) 输出 233
  • fade(5) 输出 100
  • fade(1) 输出 2
  • fade(2) 输出 149
  • fade(3) 输出 67
  • fade(4) 输出 234
  • fade(5) 输出 99

这是我的解决方案:

float t = 0;
float[] inps = new float[5];

void setup(){
  size(600,560);
  rectMode(CENTER);
  colorMode(HSB);
  for (int i = 0; i < 5; i++) {
    inps[i] = random(TWO_PI);
  }
  noFill();
  strokeWeight(3);
}

void draw(){
  background(0);
  for (int i = 0; i < 5; i++) {
    stroke(random(255),255,fade(inps[i]));
    rect(540,500 - 110 * i,100,10);
  }
  t = (t + 0.01)%TWO_PI;
}

float fade(float offset){
  return map(sin(t + offset),-1,1,255);
}

里面可能有很多你不熟悉的东西,但我基本上是这样做的:

  • 创建一个连续变化的变量t(我们可以通过sin(t)获得矩形亮度的振荡值)。
  • 为新的 inps 函数创建一个包含 5 个随机输入的列表 fade()(技术上讲它是一个数组,而不是一个列表,但这里的区别并不重要)。
  • 使用颜色模式 HSB(色调、饱和度、亮度)
  • 将每个矩形与其中一个输入相关联(这是 for 内的 draw() 循环
  • 对于每个矩形,计算其关联输入的 fade(),这将是 sin(t + offset),除了它从 0 扩展到 255 而不是只是 -1 到 1。
  • 对于矩形的颜色,选择随机色调,赋予其完全饱和度 (255),并使用 fade() 值作为亮度。

这有一些缺点,但通常可以克服。如果您在处理更具体的问题时遇到问题,请告诉我。