2016-06-02 28 views
0

Ich konnte Partikel um die Ellipse herum bewegen, die ich erstellt hatte, was meine vorherige Frage war. Jetzt habe ich noch einen, die Strömung der Teilchen ist nicht so glatt wie ich will, da ist diese diagonal wirkende Form, der sie folgen und wenn du die Maus bewegst (die Ellipse), kannst du meine Linien meiner "Kraft" Variable sehen. Wieder möchte ich, dass sich Teilchen bewegen wie Wasser, das um einen Felsen in einem Fluss schwimmt.Partikel um das Objekt glatter bewegen

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

} 



} 

Antwort

0

Es wird viel einfacher sein, wenn Sie versuchen, Ihr Problem zu verengen auf einen kleineren MCVE, wie ich in der Antwort auf Ihre erste Frage war:

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

Jetzt haben wir das, wir können darüber reden, wie wir es verbessern könnten.

Gerade jetzt, unsere Logik für die Teilchen mit unserem Hindernis vermeiden, ist hier:

if (dist(position.x, position.y, mouseX, mouseY) < 100) { 
    if (position.x < mouseX) { 
     position.x--; 
    } else { 
     position.x++; 
    } 
} 

Beachten Sie, dass wir immer die Teilchen um 1 Pixel bewegt, weshalb es blockartig aussieht. Was wir tun müssen, ist unseren Übergang zu glätten, indem wir den Pixel zuerst nur ein kleines bisschen bewegen und ihn dann mehr bewegen, wenn er näher an das Hindernis herankommt.

Sie könnten die lerp() oder map() Funktion dafür verwenden, aber für dieses einfache Beispiel können wir einfach die dist() Funktion verwenden.

Hier ist ein super einfach Ansatz Sie nehmen könnten:

float distance = dist(position.x, position.y, mouseX, mouseY); 

if (position.x < mouseX) { 
    position.x -= 1000/(distance*distance); 
} else { 
    position.x += 1000/(distance*distance); 
} 

Beachten Sie, dass die Entfernung von quadriert, ich habe die Einrichtung eines polynomical interpolation auf. Mit anderen Worten, das Teilchen bewegt sich schneller, je näher es der Mitte der Grenze kommt.

Nochmals, Sie müssen damit spielen, um den genauen Effekt zu erhalten, den Sie suchen, aber die Grundidee ist da: Was Sie suchen, ist eine Interpolation (wie schnell sich das Teilchen bewegt) das skaliert mit der Entfernung von der Grenze. Sie können Quadrieren verwenden, um den Effekt zu übertreiben.

Sie können auch eine grundlegende Triggerung verwenden, um das Partikel einem kreisförmigen Pfad folgen zu lassen.