【问题标题】:Processing, ellipse not following alpha values?处理,椭圆不遵循阿尔法值?
【发布时间】:2016-08-30 03:19:09
【问题描述】:
  class Particle{

  PVector velocity, location; //PVector variables for each particle.

  Particle(){ //Constructor - random location and speed for each particle.
    velocity = new PVector(random(-0.5,0.5), random(-0.5,0.5));
    location = new PVector(random(0,width),random(0,width));
  }

  void update() { location.add(velocity); } //Motion method.

  void edge() {  //Wraparound case for particles.
    if (location.x > width) {location.x = 0;} 
    else if (location.x < 0) {location.x = width;}

    if (location.y > height) {location.y = 0;}
    else if (location.y < 0) {location.y = height;}
  }

  void display(ArrayList<Particle> p){ //Display method to show lines and ellipses between particles.

    for(Particle other: p){ //For every particle in the ArrayList.
     float d = PVector.dist(location,other.location); //Get distance between any two particle.
     float a = 255 - d*2.5; //Map variable 'a' as alpha based on distance. E.g. if distance is high, d = 100, alpha is low, a = 255 - 225 = 30.

     println("Lowest distance of any two particle =" + d); //Debug output.

     if(d<112){ //If the distance of any two particle falls bellow 112.
      noStroke(); //No outline.
      fill(0,a); //Particle are coloured black, 'a' to vary alpha.
      ellipse(location.x, location.y, 8, 8); //Draw ellipse based on location of particle.

      stroke(0,a); //Lines are coloured black, 'a' to vary alpha.
      strokeWeight(0.7);
      line(location.x,location.y,other.location.x,other.location.y); //Draw line between four coordinates, between two particle.
     }

    }
  }
}

ArrayList<Particle> particles = new ArrayList<Particle>(); //Create a new arraylist of type Particle.

void setup(){
  size(640,640,P2D); //Setup frame of sketch.
  particles.add(new Particle()); //Add five Particle elements into arraylist.
  particles.add(new Particle());
  particles.add(new Particle());
  particles.add(new Particle());
  particles.add(new Particle());
}

void draw(){
 background(255); //Set white background.
 for(Particle p: particles){ //For every 'p' of type Particle in arraylist particles.
   p.update(); //Update location based on velocity.
   p.display(particles); //Display each particle in relation to other particles.
   p.edge(); //Wraparound if particle reaches edge of screen.
 }
}

在上面的代码中,有形状对象、线条和椭圆。其中透明度受变量a影响。

变量 'a' 或 alpha 是从距离 'd' 外推而来的。因此,当物体更远时,物体的 alpha 值会下降。

在这种情况下,线的 alpha 值不会随时间变化,例如随着距离消退。然而,尽管代码非常相似,但省略号似乎停留在 alpha '255' 上。

如果 'a' 的值是硬编码的,例如

if(d<112){ //If the distance of any two particle falls bellow 112.
      noStroke(); //No outline.

      fill(0,100); //Particle are coloured black, set alpha 'a' to be 100, grey tint.

      ellipse(location.x, location.y, 8, 8); //Draw ellipse based on location of particle.

椭圆按预期将颜色变为灰色。

编辑:我相信我找到了问题的根源。变量“a”不区分正在迭代的粒子。因此,alpha 可能会卡住/加起来最多 255。

【问题讨论】:

  • 你可能想看看 pushStyle()/popStyle() 来隔离绘图样式,以防万一你有一些东西在你不期望的地方弄乱了 alpha。详情请查看this answer
  • @George Profenza 感谢您的反馈,我已经测试了 push/pop 方法,但不影响结果。
  • 请在交叉帖子之间链接:forum.processing.org/two/discussion/18015/…

标签: processing ellipse extrapolation


【解决方案1】:

您将不得不发布MCVE。请注意,这不应该是你的整个草图,只是一些硬编码的行,所以我们都在使用相同的代码。我们应该能够将您的代码复制并粘贴到我们自己的机器中以查看问题。另外,请尝试正确格式化您的代码。没有缩进让你的代码难以阅读。

话虽如此,我可以尝试在一般意义上提供帮助。首先,您打印出a 的值,但您没有告诉我们它的值是多少。它的价值是你所期望的吗?如果是这样,您是在绘制椭圆之前清除之前的帧,还是在之前绘制的椭圆之上绘制它们?您是否在代码的其他地方绘制了椭圆?

从空白草图重新开始,并添加足够多的线条来显示问题。这是您可以使用的示例MCVE

stroke(0);
fill(0);
ellipse(25, 25, 25, 25);
line(0, 25, width, 25);

stroke(0, 128);
fill(0, 128);
ellipse(75, 75, 25, 25);
line(0, 75, width, 75);

此代码先绘制黑色线和椭圆,然后绘制透明线和椭圆。请从您的代码中硬编码 a 值,或添加足够的代码,以便我们可以确切地看到发生了什么。

编辑:感谢 MCVE。您更新的代码仍然存在问题。我不明白这个循环:

for(Particle other: p){ //For every particle in the ArrayList.
     float d = PVector.dist(location,other.location); //Get distance between any two particle.
     float a = 255 - d*2.5; //Map variable 'a' as alpha based on distance. E.g. if distance is high, d = 100, alpha is low, a = 255 - 225 = 30.

     println("Lowest distance of any two particle =" + d); //Debug output.

     if(d<112){ //If the distance of any two particle falls bellow 112.
      noStroke(); //No outline.
      fill(0,a); //Particle are coloured black, 'a' to vary alpha.
      ellipse(location.x, location.y, 8, 8); //Draw ellipse based on location of particle.

      stroke(0,a); //Lines are coloured black, 'a' to vary alpha.
      strokeWeight(0.7);
      line(location.x,location.y,other.location.x,other.location.y); //Draw line between four coordinates, between two particle.
     }

    }
  }

您是说对于每个Particle,循环遍历每个粒子,然后在Particle 的当前位置绘制一个椭圆?这没有任何意义。如果你有 100 个Particles,这意味着每个Particle 将被绘制 100 次!

如果您希望每个Particle's 颜色都基于其与最近的另一个Particle 的距离,那么您需要修改此循环以简单地找到最近的Particle,然后以此为基础进行计算。它可能看起来像这样:

Particle closestNeighbor = null;
float closestDistance = 100000;

for (Particle other : p) { //For every particle in the ArrayList.

  if (other == this) {
    continue;
  }


  float d = PVector.dist(location, other.location);
  if (d < closestDistance) {
    closestDistance = d;
    closestNeighbor = other;
  }
}

注意if (other == this) { 部分。这很重要,因为否则您会将每个 Particle 与其自身进行比较,并且距离将为零!

获得closestNeighborclosestDistance 后,您就可以进行计算了。

请注意,只有当粒子的邻居距离小于112 像素时,您才会绘制粒子。那是你想做的吗?

如果您有后续问题,请在新问题中发布更新的 MCVE。不断编辑问题和答案会让人感到困惑,所以如果再次卡住,请提出一个新问题。

【讨论】:

  • 感谢您的回复。我已经制定了一个更简单的 MCVE 草图,它应该可以更好地突出问题。
  • “if(other==this)”帮助解决了我的问题!谢谢。如果我希望粒子保持在固定的 alpha 值,比如 30,然后在靠近相邻粒子时变得更加不透明,该怎么办?
  • @user4985 您可以在您的if(d&lt;whatever) 语句中添加一个else 子句,然后在其中绘制您想要的任何内容。如果您有后续问题,请在新问题中发布更新的 MCVE,我们将从那里开始。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-04
  • 1970-01-01
  • 2011-11-22
  • 2015-12-04
  • 2016-03-03
  • 1970-01-01
相关资源
最近更新 更多