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。
您将不得不发布一个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.
}
}
}
你是说对于每个粒子
,你遍历每个粒子,然后在当前粒子
的位置画一个椭圆?这没有任何意义。如果你有100个粒子
,这意味着每个粒子
将被绘制100次!
如果您希望每个粒子的
颜色基于它与最近的另一个粒子
的距离,那么您需要修改此循环以简单地找到最近的粒子
,然后在此基础上进行计算。它可能看起来像这样:
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(其他==this){
部分。这很重要,因为否则您将比较每个粒子
本身,距离将为零!
一旦你有了ClosestNighbor
和ClosestTerance
,你就可以进行计算了。
请注意,只有当粒子的邻居距离112
像素以上时,您才会绘制粒子。这就是你想做的吗?
如果你有后续问题,请在新问题中发布更新的MCVE。不断编辑问题和答案会变得混乱,所以如果你再次陷入困境,就问一个新问题。