processing으로 장애물 방지

16818 단어 processing


시프만씨의 자율 에이전트를 응용해 그레이의 원을 회피하는 파티클군을 만들어 보았습니다.
각 파티클은 오른쪽으로 움직이는 벡터를 가지고 있지만, 원 근처에 접근하면 원의 중심에
반대 방향의 벡터가 작용하도록 설정하고 있습니다. 그러나 원에서 벗어나면 다시 오른쪽으로
돌아가고 싶기 때문에 PVector (자신의 x + 100, 원래 y)로 이동하도록하고 있습니다.
ArrayList<Agent> agents;

void setup () {

    size (800, 600, P2D);

    agents = new ArrayList<Agent> ();

    for (int i = 0; i < 1000; i++) {
        agents.add (new Agent (random (width), random (height), random (2, 4)));
    }

}

void draw () {

    background (255);

    for (Agent a : agents) {
        a.separate (agents);
        a.update ();
        a.border ();
        a.render ();
    }

    if (agents.size () > 1200) {
        agents.remove (0);
    }

    fill (200);
    stroke (127);
    ellipseMode (CENTER);
    ellipse (mouseX, mouseY, 100 * 2, 100 * 2);

}

void mouseDragged () {

    agents.add (new Agent (mouseX, mouseY, random (2, 4)));

}

class Agent {

    PVector location;
    PVector velocity;
    PVector acceleration;

    PVector circle;
    PVector diff;

    float r;
    float maxforce;
    float maxspeed;
    float base_y;

    Agent (float x, float y, float ms) {

        location = new PVector (x, y);
        velocity = new PVector (ms, 0);
        acceleration = new PVector (0, 0);

        diff = new PVector ();

        r = 100.0;
        maxforce = 0.2;
        maxspeed = ms;
        base_y = y;

    }

    void update () {

        velocity.add (acceleration);
        velocity.limit (maxspeed);
        location.add (velocity);
        acceleration.mult (0);

    }

    void render () {

        fill (127);
        stroke (0);
        strokeWeight (1);
        pushMatrix ();
        translate (location.x, location.y);
        ellipse (0, 0, 4, 4);
        popMatrix ();

    }

    void applyForce (PVector force) {

        acceleration.add (force);

    }

    void separate (ArrayList<Agent> agents) {

        float desired_separation = r * 1.4;

        circle = new PVector (mouseX, mouseY);

        for (Agent a : agents) {
            float d = PVector.dist (location, circle);
            if ((d > 0) && (d < desired_separation)) {
                PVector diff01 = PVector.sub (location, circle);
                PVector diff02 = new PVector (maxspeed * abs (circle.y - location.y) * 0.8, 0);
                diff = PVector.add (diff01, diff02);
                diff.normalize ();
                diff.div (d);
            } else {
                diff = PVector.sub (new PVector (velocity.x + 100, base_y - location.y), velocity);
                diff.normalize ();
            }
        }

        diff.setMag (maxspeed);
        PVector steer = PVector.sub (diff, velocity);
        steer.limit (maxforce);
        applyForce (steer);

    }

    void border () {

        if (location.x < -r) location.x = width + r;
        if (location.y < -r) location.y = height + r;
        if (location.x > width + r) location.x = -r;
        if (location.y > height + r) location.y = -r;

    }

}

좋은 웹페이지 즐겨찾기