Schlagwort-Archive: Agenten

Agenten


Processing 2.0

Agenten bewegen sich entsprechend ihrer Programmierung. Hier werden sie als Objekte realisiert und bewegen sich zufällig.

Sie ändern aber nicht abrupt ihre Richtung, da wir für die Position der Agenten Vektoren verwenden, denen wir in jedem Schritt eine zufällige Abweichung addieren.

In der einfachsten Ausführung des Programms bewegen sie sich aus der Mitte heraus und prallen dann von den Rändern des Animationsfensters zurück. Dabei ist ihre Bewegung nicht gerade, sondern ändern ständig ihre Richtung.

Beispiel: einfache Agenten starte Applet

Agent [] agenten;

void setup() {
size(300, 300);
smooth();
stroke(255);

// hier wird ein Array für 10 Agenten erzeugt
agenten= new Agent[10];

// die Agenten selber werden erzeugt
for (int i=0; i<agenten.length; i++) {
agenten[i]=new Agent(width/2, height/2, 5);
}
}

void draw() {
// für den Spur, die die Agenten hinterlassen
fill(0, 2);
rect(0, 0, width, height);

//alle Agenten müssen die Position ändern
for (int i=0; i<agenten.length; i++) {
//jeder Agent wird gezeichnet
agenten[i].render();
//jeder Agent muß die Position ändern
agenten[i].move();
}
}
class Agent {

// Variablen
PVector position;
PVector direction;
//definiert die Stärke der Richtungsänderung
float spin = 0.20;
float radius; // 3. Radius

//der Konstruktor für die Agenten-Klasse
Agent (float theX, float theY, float aradius) {
position    = new PVector (theX, theY);
direction   = new PVector (10, 10);
direction.x = random (-1, 1);
direction.y = random (-1, 1);
radius = aradius;
}

//eine Methode
void render() {

//einkommentiert ergibt sich hieraus ein schönes Fächer-Muster
//line(position.x, position.y, width/2, height/2);
ellipse(position.x, position.y,5,5);
}

//Methode
void move() {

//die Agenten ändern ihre Richting nicht abrupt, sondern immer nur ein wenig!
direction.x += random (-spin, spin);
direction.y += random (-spin, spin);

//for a constant speed
direction.normalize();

// hier kann man die Geschwindigkeit ändern
direction.mult(1);

position.add(direction);

//damit die Agenten das Bild nicht verlassen
if (position.x < radius || position.x > (width-radius)) {
direction.x *= -1;
}
if (position.y < radius || position.y > (height-radius)) {
direction.y *= -1;
}
}
}

Beispiel: einfache Agenten2 starte Applet

Hier wurde der Code um Farbe und die Linien von jedem Agenten zum Mittelpunkt erweitert.

in setup();

 colorMode(HSB, 360, 100, 100);

im Agenten selbst

 int col;

...

col=(int)random(0, 360);

...

void render() {
if (col<360) {
col+=2;
} else {
col=0;
}

//reuncomment for random color
stroke(col,100,100);

Den kompletten Source-Code findest Du beim Applet!

Beispiel: einfache Agenten3 starte Applet

Hier eine Variante, bei der die Agenten miteinander durch gerade Linien verbunden werden.

Änderung in draw();

 if (i==0) {
line(agenten[i].position.x,
agenten[i].position.y,
agenten[agenten.length-1].position.x,
agenten[agenten.length-1].position.y);
}
else {
line(agenten[i].position.x, agenten[i].position.y,
agenten[i-1].position.x, agenten[i-1].position.y);
} 

Den kompletten Source-Code findest Du beim Applet!

Beispiel: einfache Agenten4 starte Applet

In diesem Beispiel wird die Bewegungsfreiheit der Agenten durch die aktuelle Mausposition in x- und y- Richtung eingeschränkt. Ist der Mauszeiger in der linken oberen Ecke, versammeln sich alle Agenten im Mittelpunkt, ist er in der rechten unteren Ecke, können sie sich (fast) frei bewegen.

Dafür platzieren wir folgende Code-Zeile in setup() und in draw(). Sie bewirkt, dass der Ursprung des Koordinatensystems in die Mitte des Rahmens verschoben wird.

 translate(width/2,height/2); 

Da wir nun vom Mittelpunkt des Rahmens als Nullpunkt ausgehen, können wir mit Hilfe der map()– Funktion die aktuelle Position (x und y) von -width/2 bis +width/2 um die aktuelle Mausposition korrigieren. Das machen wir aus optischen Gründen nun für 2 Ellipsen.

 ellipse(
      map(position.x,-width/2,width/2,-mouseX/2,mouseX/2),
      map(position.y,-height/2,height/2,-mouseY/2,mouseY/2)
      ,4,4);
       fill(100,50,255);
       ellipse(
      map(position.x,-width/2,width/2,-mouseX/2,mouseX/2),

      map(position.y,-height/2,height/2,-mouseY/2,mouseY/2)
      ,3,3);

Weiters wird nun die Grenze, an der die Agenten zurückprallen vom Fensterrahmen auf einen Kreis geändert:

    if (dist(position.x,position.y,0,0)>width/2) {
          direction.x *= -1;
          direction.y *= -1;

    }

Den kompletten Source-Code findest Du beim Applet!

Beispiel: einfache Agenten5 starte Applet

In diesem Beispiel arbeiten wir wieder im Color-Mode HSB.

colorMode(HSB, 360, 100, 100);

Außerdem erhält hier jeder Agent einen Index und ein Array mit den Indizes von 3 seiner nächsten Nachbarn. Damit kann man über 4 Punkte eine Kurve (curve() ) zeichnen und die Agenten damit dann Verbinden.

Variablendefinition in der Agenten-Klasse:

int [] neighbours = new int [4];
  int index;

Im Konstruktor des Agenten:

Start-Farbpunkt für jeden Agenten, damit alle gemeinsam das gesamte Spektrum abdecken.

 col=index*(360/agenten.length); 

Jeder Agent muss, wenn er erzeugt wird seine Nachbarn finden. Das macht er hiermit:

 for (int i=0;i<4;i++) {
      if (index+i>agenten.length-1) {
        neighbours[i]= index+i-agenten.length;
      }else {
      neighbours[i]= index+i;
      } 

In der Methode render des Agenten wird nun nichts mehr gezeichnet. Wir nutzen sie aber für die Veränderung der Farbwerte:

 if (col<360) {
      col+=2;
    } else {
      col=0;
    } 

Wir zeichnen die Kurve nun in draw():

curve(
      map(agenten[agenten[i].neighbours[0]].position.x,-width/2,width/2,-mouseX/2,mouseX/2),
      map(agenten[agenten[i].neighbours[0]].position.y,-height/2,height/2,-mouseY/2,mouseY/2),
      map(agenten[agenten[i].neighbours[1]].position.x,-width/2,width/2,-mouseX/2,mouseX/2),
      map(agenten[agenten[i].neighbours[1]].position.y,-height/2,height/2,-mouseY/2,mouseY/2),
      map(agenten[agenten[i].neighbours[2]].position.x,-width/2,width/2,-mouseX/2,mouseX/2),
      map(agenten[agenten[i].neighbours[2]].position.y,-height/2,height/2,-mouseY/2,mouseY/2),
      map(agenten[agenten[i].neighbours[3]].position.x,-width/2,width/2,-mouseX/2,mouseX/2),
      map(agenten[agenten[i].neighbours[3]].position.y,-height/2,height/2,-mouseY/2,mouseY/2)); 

Den kompletten Source-Code findest Du beim Applet!

Beispiel: einfache Agenten6 starte Applet

Hier bekommt jeder Agent einen Startpunkt zugeordnet. In diesem Fall bilden alle Agenten gemeinsam einen Kreis. Damit jeder Agent wieder in seinen Ursprung zurückkehren kann, muss er sich seine Startposition merken. Das tut er in der PVector Variablen start.

 PVector start; 

Auch der Konstruktor der Agenten wird angepasst. Die Koordinaten, die beim Erzeugen des Agenten übertragen werden, werden in der Variable start gespeichert und die Variable position wird mit den Koordinaten 0,0 gefüllt.

 //der Konstruktor für die Agenten-Klasse
 Agent (float theX, float theY, float aradius) {
 start = new PVector (theX, theY);
 position=new PVector(0,0);
 direction = new PVector (10, 10);
 direction.x = random (-1, 1);
 direction.y = random (-1, 1);
 radius = aradius;
 }
 

Beim Zeichnen der Agenten wird nun das Koordinatensystem auf die jeweilige Startposition verschoben. Und von dort ausgehend seine Position gezeichnet.

 pushMatrix();
    translate(start.x,start.y);
      ....
  popMatrix();

Mit den folgenden Zeilen legen wir die Startpositionen der Agenten fest. Sie ordnen sich kreisförmig um dem Mittelpunkt an.

 for (int i=0; i<agenten.length; i++) {
 float x,y;
 x= width/2+(cos(map(i,0,agenten.length,0,TWO_PI))*width/4);
 y= height/2+(sin(map(i,0,agenten.length,0,TWO_PI))*height/4);
 agenten[i]=new Agent(x,y, 5);
 }
 

Den kompletten Source-Code findest Du beim Applet!