我能够让粒子绕过我创建的椭圆,这是我之前的问题。现在我有了另一个,粒子的流动并不像我想要的那么平滑,它们遵循这种对角线形状,当你移动鼠标(椭圆)时,你可以看到我的“力”变量的线条。我希望粒子能像水一样漂浮在河里的岩石上。
Link for the previous question I asked about same project
int NUM_PARTICLES = 9000;
ParticleSystem p;
Rock r;
void setup()
{
smooth();
size(700,700,P2D);
p = new ParticleSystem();
r = new Rock();
}
void draw()
{
background(0);
p.update();
p.render();
r.rock();
}
float speed = 2;
float rad = 100;
class Particle
{
PVector position, velocity;
float initialPosY;
Particle()
{
position = new PVector(random(width), random(height));
initialPosY = position.y;
velocity = new PVector();
}
void update()
{
velocity.x = speed;
velocity.y = 0;
float d = dist (position.x, position.y, mouseX, mouseY);
if (d < rad) {
float force = map(d, 0, rad, speed, 0);
if (position.x < mouseX) {
if (position.y < mouseY) {
velocity.y = -force;
} else {
velocity.y = force;
}
} else {
if (position.y < mouseY) {
velocity.y = force;
} else {
velocity.y = -force;
}
}
position.add(velocity);
} else {
position = new PVector(position.x+speed, initialPosY);
}
if (position.x<0)position.x+=width;
if (position.x>width)position.x-=width;
if (position.y<0)position.y+=height;
if (position.y>height)position.y-=height;
}
void render()
{
stroke(255, 255, 255, 80);
point(position.x, position.y);
}
}
class ParticleSystem
{
Particle[] particles;
ParticleSystem()
{
particles = new Particle[NUM_PARTICLES];
for (int i = 0; i < NUM_PARTICLES; i++)
{
particles[i]= new Particle();
}
}
void update()
{
for (int i = 0; i < NUM_PARTICLES; i++)
{
particles[i].update();
}
}
void render()
{
for (int i = 0; i < NUM_PARTICLES; i++)
{
particles[i].render();
}
}
}
class Rock{
void rock()
{
noFill();
stroke(255);
strokeWeight(4);
ellipse(mouseX,mouseY,50,50);
}
}
答案 0 :(得分:0)
如果您尝试将问题范围缩小到较小的MCVE,那就容易多了,就像我在第一个问题的答案中所做的那样:
PVector position;
PVector speed;
void setup() {
size(500, 500);
position = new PVector(250, 0);
speed = new PVector(0, 1);
}
void draw() {
background(0);
if (dist(position.x, position.y, mouseX, mouseY) < 100) {
fill(255, 0, 0);
if (position.x < mouseX) {
position.x--;
} else {
position.x++;
}
} else {
fill(0, 255, 0);
}
ellipse(mouseX, mouseY, 100, 100);
fill(0, 0, 255);
ellipse(position.x, position.y, 20, 20);
position.add(speed);
if (position.y > height) {
position.y = 0;
}
if (position.x < 0) {
position.x = width;
} else if (position.x > width) {
position.x = 0;
}
}
现在我们有了这个,我们可以谈谈我们如何改进它。
现在,我们让粒子避开障碍的逻辑就在这里:
if (dist(position.x, position.y, mouseX, mouseY) < 100) {
if (position.x < mouseX) {
position.x--;
} else {
position.x++;
}
}
请注意,我们总是将粒子移动1个像素,这就是它看起来很块的原因。我们需要做的是通过首先移动像素一点点来平滑我们的过渡,然后在它接近障碍物时移动它更多。
您可以为此使用lerp()
或map()
功能,但对于此简单示例,我们只需使用dist()
功能。
以下是您可能采取的超级简单方法:
float distance = dist(position.x, position.y, mouseX, mouseY);
if (position.x < mouseX) {
position.x -= 1000/(distance*distance);
} else {
position.x += 1000/(distance*distance);
}
请注意,通过平方距离,我设置polynomical interpolation。换句话说,粒子越靠近边界中心就越快移动。
同样,你必须要玩这个以获得你正在寻找的确切效果,但基本的想法是:你正在寻找的是插值(如何快速粒子移动)随着距离边界的距离而缩放。您可以使用平方来夸大效果。
您还可以使用基本触发来使粒子遵循圆形路径。