This browser does not have a Java Plug-in.
Get the latest Java Plug-in here.

Press F1 for Manual. / import processing.opengl.*; Flock schwarm; PFont font; float mx = 1400; float my = 875; float mz = 540; float rx = mx*0.8; float ry = my*0.8; float rz = mz*0.8; float max_f = 20.0f; float obs_f = 0.4*max_f; //Zeppelinabwehrkraft float pre_f = max_f*3; //AbschreckungdurchJaeger float bou_f =0.9*max_f; //Grenzwall float sep_f =0.7*max_f; float ali_f =0.5*max_f; float coh_f =0.25*max_f; float Zbou_f =0.008*max_f; float Zsep_f =0.03*max_f; Vector3D eye; Vector3D eyeAt; Vector3D eMi; float CamRotX; float CamRotY; float CamRotZ; boolean schweif = false; boolean licht = true; boolean boundviz = false; boolean showSep = false; boolean showCoh = false; boolean showAli = false; boolean showObs = false; boolean MenuScreen = true; int view; float rel_div; int shape = 1; int traceCount = 0; int deadCount = 0; //statistik float minDist; float BoVMax; float BoVMin; float WaVMax; float WaVMin; float ZeVMax; float ZeVMin; float Ufak; String report = ""; String repAli = ""; String repSep = ""; String repCoh = ""; int Zmax=6; int Bmax=90; int Wmax=3; void setup() { size(1280,750,OPENGL); smooth(); colorMode(RGB,255,255,255,100); font = loadFont ("Ziggurat-HTF-Black-32.vlw"); schwarm = new Flock(); ZeppelinAdd(7); for (int i = 0; i < 90; i++) { schwarm.addBoid(new Boid(new Vector3D(mx,my,mz),max_f/5,max_f/700)); } view = 1; eMi = new Vector3D (mx,my,mz); eye = new Vector3D (50,50,50); eyeAt = new Vector3D(eMi.x-200,eMi.y,eMi.z-50); rel_div = 2400; repSep = Balken (sep_f, max_f); repAli = Balken (ali_f, max_f); repCoh = Balken (coh_f, max_f); } void draw() { frameRate(15); if (view == 4){ beginCamera(); camera(eye.x,eye.y+150,eye.z,//0,0,0,// eyeX, eyeY, eyeZ eye.x,eye.y-400,eye.z, // centerX, centerY, centerZ 0,0,-1.0); // upX, upY, upZ //rotateZ(CamRotZ); //rotateX (-CamRotX+HALF_PI); //rotateY (-CamRotY+HALF_PI); endCamera(); } else{ camera(eye.x, eye.y, eye.z, // eyeX, eyeY, eyeZ eyeAt.x, eyeAt.y, eyeAt.z, // centerX, centerY, centerZ 0.0, 0.0, -1.0); // upX, upY, upZ } // STYLE SETTINGS strokeWeight (1); if (licht == true){ lights(); background(70); } else { background(30); } // Ellipse for (int i=8;i>0;i--){ noFill (); if (licht == false){ stroke(150,i*20,i*30); } ellipse (mx,my, rx*i/4, ry*i/4); } DrawFlughafen(); //outgesourct if (view==4){ DrawFullEllipse(rx,ry,rz); } schwarm.run(); //HUD if (licht == true){ stroke(150); fill (255); } else { fill (120,120,0); } float reportX=-82; float reportY=-90; float reportZ=17-view*20; textFont(font,1.3+view*0.4); if (MenuScreen == true){ textFont(font,2.8); fill(255,255,0,100); reportX += 0; reportY += 0; reportZ += 85; report = "NUMBER OF AGENTS"; report += char(10)+">>B<< add 90 boids >>N<< remove 90 boids (max. 360)"; report += char(10)+">>H<< add 1 hunter >>J<< remove all hunters (max. 3)"; report += char(10)+">>Z<< add 2 zeppelins >>U<< remove 1 zeppelin (max. 7)"; report += char(10); report += char(10); report += char(10)+"POWER MANAGEMENT"; report += char(10)+">>Q<< increase separation >>A<< decrease separation >>Y<< visualize sep."; report += char(10)+">>W<< increase alignment >>S<< decrease alignment >>X<< visualize ali."; report += char(10)+">>E<< increase cohesion >>D<< decrease cohesion >>C<< visualize coh."; report += char(10)+">>F<< reset forces to default"; report += char(10); report += char(10); report += char(10)+"FURTHER VISUALIZATION"; report += char(10)+">>V<< change view >>L<< change lighting"; report += char(10)+">>K<< show boundaries >>O<< show obstacle avoidance"; report += char(10)+">>T<< show smoketail >>G<< reduce detail"; report += char(10); report += char(10)+">>Click in screen<< to call or hide this menu"; } if (view!=4){ pushMatrix(); translate(eye.x,eye.y,eye.z); rotate (PI-atan((eye.x-eyeAt.x)/(eye.y-eyeAt.y))); translate(reportX,reportY,reportZ); rotateX(-HALF_PI); text (report,10,10,1000,1000); popMatrix(); } if (traceCount%6==0){ minDist=100; BoVMax = 0; BoVMin = 100; WaVMax = 0; WaVMin = 100; ZeVMax = 0; ZeVMin = 100; } if (traceCount > 200){ traceCount=0; } if (deadCount >= 9000){ deadCount=299; } // Schweif_Timer traceCount++; // schlaf timer deadCount++; // AUTOMATISMEN if (deadCount%150==0){ switch (deadCount){ case 300: schweif =true; break; case 750: schweif =false; showObs =true; break; case 900: boundviz =true; break; case 1050: boundviz=false; showSep =true; break; case 1200: showSep =false; showAli =true; break; case 1350: showAli =false; showCoh =true; showObs =false; break; case 1500: schweif=true; break; case 1650: showCoh =false; break; case 1800: licht=false; break; } } if (deadCount%500==0){ view++; if (view >4){ view=1; } switch (view){ case 1: eye = new Vector3D (50,50,50); eyeAt = new Vector3D(eMi.x-200,eMi.y,eMi.z-50); rel_div = 2000; break; case 2: eye = new Vector3D (rx*2.5,ry*1.8,600); eyeAt = eMi; rel_div = 3000; break; case 3: eye = new Vector3D (mouseX*5,mouseY*5,600); eyeAt = eMi; rel_div = eye.distance(eye,eMi)+700; break; case 4: rel_div =200; break; } } if (deadCount%140==0 && deadCount >=420){ if (schwarm.boids.size() < 360){ for (int i = 0; i < Bmax; i++) { //int zufallszahl = round (random(-100,100)); schwarm.addBoid(new Boid(new Vector3D(mx,my,mz),max_f/3,max_f/700)); } } } if (deadCount%120==0 && deadCount >=1080){ int groesze = schwarm.walters.size(); if (groesze < Wmax){ for (int i = 0; i < 2; i++) { //int zufallszahl = round (random(-100,100)); schwarm.addWalter(new Walter(new Vector3D(mx,my,mz),max_f*0.55,max_f/500)); } } } } void mouseMoved (){ deadCount = 0; if (view ==3){ eye = new Vector3D (mouseX*1.7,mouseY*1.7,600); rel_div = eye.distance(eye,eMi)+700; } } void mouseClicked (){ deadCount = 0; if (MenuScreen==false){ MenuScreen=true; } else{ MenuScreen=false; } } // Add new boids into the System class Flock { ArrayList boids; // An arraylist for all the boids ArrayList zepps; ArrayList walters; Flock() { boids = new ArrayList(); // Initialize the arraylist zepps = new ArrayList(); walters = new ArrayList(); } void run() { for (int i = 0; i < zepps.size(); i++) { Zepp z = (Zepp) zepps.get(i); z.run(zepps); // Zeppelin ist blind fuer andere Klassen } for (int j = 0; j < boids.size(); j++) { Boid b = (Boid) boids.get(j); b.run(boids,zepps, walters); // Boids brauchen Kollegen-, Walter und Zeppelininfos } for (int k = 0; k < walters.size(); k++) { Walter w = (Walter) walters.get(k); w.run(boids,zepps,walters); // Walter-Klasse benoetigt Boid, Zeppelin und 'Klassenkameraden' } } void addBoid(Boid b) { boids.add(b); } void addZepp(Zepp z) { zepps.add(z); } void addWalter(Walter w) { walters.add(w); } } class Walter { Vector3D Wloc; Vector3D Wvel; Vector3D Wacc; Vector3D Wepo; float GrenzDiff ; float Wr; float Wmax_force; // Maximum steering force float Wmaxspeed; // Maximum speed float Wminspeed; float Wrel_eye; color WtailColor = color (random(100,200),255,250); float Wtail[] = new float[0]; float miniWtail[] = new float[0]; float Wrel_tpo; Walter(Vector3D l, float ms, float mf) { Wacc = new Vector3D(0,0,0); Wvel = new Vector3D(random(-10,10),random(-10,10),random(-10,10)); Wepo = new Vector3D (0,0); Wloc = l.copy(); Wr = 2.2f; Wmaxspeed = ms; Wminspeed = ms/2; Wmax_force = mf; } void run(ArrayList boids, ArrayList zepps, ArrayList walters) { Wflock(boids, zepps, walters); Wborders(); Wupdate(); Wrender(); } // We accumulate a new acceleration each time based on three rules void Wflock(ArrayList boids, ArrayList zepps, ArrayList walters) { Vector3D obs = obstacle(zepps); // avoid obstacle Vector3D bou = borderline(); // avoid borderline Vector3D sep = separate(walters); // Separation Vector3D hun = hunt(boids); // Cohesion // Arbitrarily weight these forces obs.mult(obs_f); bou.mult(bou_f*0.8); sep.mult(sep_f/2); hun.mult(coh_f*2); Wacc.add(obs); Wacc.add(bou); Wacc.add(sep); Wacc.add(hun); } // Method to update location void Wupdate() { // Update velocity Wvel.add(Wacc); // Limit speed Wvel.limit(Wmaxspeed); Wvel.ulimit(Wminspeed); if (Wvel.magnitude()>WaVMax){ WaVMax=Wvel.magnitude(); } if (Wvel.magnitude() 0) { // Normalize desired desired.normalize(); // Two options for desired vector magnitude (1 -- based on distance, 2 -- Wmaxspeed) if ((slowdown) && (d < 100.0f)) desired.mult(Wmaxspeed*(d/100.0f)); // This damping is somewhat arbitrary else desired.mult(Wmaxspeed); // Steering = Desired minus Velocity steer = target.sub(desired,Wvel); steer.limit(Wmax_force); // Limit to maximum steering force } else { steer = new Vector3D(0,0); } return steer; } void Wrender() { // Farbe Wrel_eye = Wloc.distance (Wloc,eye)/rel_div; float theta = Wvel.headingXY()+PI+HALF_PI; float beta = Wvel.headingZ()+PI; // Daten fuer EGO-Persp uebermitteln if (view==4){ eye = Wloc; CamRotX=beta; CamRotY=beta; CamRotZ=theta; } //zumwi pushMatrix(); translate(Wloc.x,Wloc.y,Wloc.z); rotateZ(theta); rotateX (beta); rotateY (beta); if (licht == false){ noFill(); strokeWeight (0.5); stroke(210,100,Wrel_eye*120); } else{ fill(210,100,80); if (view <4){ noStroke(); }else{ fill(200,200,80); strokeWeight (0.7); stroke(210,200,255); } } switch (shape){ case 1: //Rotor beginShape(TRIANGLE_FAN); vertex( 0.0000 ,-3.5481 , 0.0000); vertex( 0.0000 ,-2.6421 , 0.3310); vertex( 0.3300 ,-2.6581 ,-0.3300); vertex(-0.3300 ,-2.6581 ,-0.3300); endShape(); // CORPUS Top beginShape(TRIANGLE_STRIP); vertex(-0.8067,-2.4973,0.4143); vertex( 0.8067,-2.4973,0.4143); vertex(-0.9500,-0.4381,0.5276); vertex(0.9500,-0.4381,0.5276); vertex(-0.6825,1.4219,0.7398); vertex( 0.6835,1.4219,0.7398); vertex(-0.3109,2.4231,1.2506); vertex( 0.3119,2.4231,1.2506); vertex(-0.0781,3.3129,1.3538); vertex( 0.0787,3.3129,1.3592); vertex(-0.4756,5.4775,1.0525); vertex( 0.4765,5.4775,1.0525); vertex(-0.3005,7.1457,0.7797); vertex( 0.3005,7.1457,0.7797); vertex(-0.0496,8.1483,2.6200); endShape(); // CORPUS Sides beginShape(TRIANGLE_STRIP); vertex(-0.05,9.0795,2.6200); vertex(-0.05,8.1483,2.6200); vertex(-0.0374,9.6523,-0.2070); vertex(-0.3005,7.1457,0.7797); vertex(-0.4512,5.7098,-0.6182); vertex(-0.4756,5.4775,1.0525); vertex(-0.7228,3.1219,-0.8592); vertex(-0.6825,1.4219,0.7398); vertex(-0.7522,0.1160,-1.0282); vertex(-0.9500,-0.4381,0.5276); vertex(-0.80,-2.2692,-0.8898); vertex(-0.8060,-2.4973,0.4143); vertex( 0.0000,-2.4818,-0.6081); vertex( 0.8060,-2.4973,0.4143); vertex(0.80,-2.2692,-0.8898); vertex(0.9500,-0.4381,0.5276); vertex(0.7522,0.1160,-1.0282); vertex(0.6825,1.4219,0.7398); vertex(0.7228,3.1219,-0.8592); vertex(0.4756,5.4775,1.0525); vertex(0.4512,5.7098,-0.6182); vertex(0.3005,7.1457,0.7797); vertex(0.0374,9.6523,-0.2070); vertex(0.05,8.1483,2.6200); vertex(0.05,9.0795,2.6200); endShape(); // Cockpitseiten beginShape(TRIANGLE_STRIP); vertex( 0.4765,5.4775,1.0525); vertex( 0.0790,3.3129,1.3538); vertex( 0.5800,3.4497,0.8961); vertex( 0.3119,2.4231,1.2506); vertex( 0.6835,1.4219,0.7398); endShape(); beginShape(TRIANGLE_STRIP); vertex( -0.4765,5.4775,1.0525); vertex( -0.0790,3.3129,1.3538); vertex( -0.5800,3.4497,0.8961); vertex( -0.3119,2.4231,1.2506); vertex( -0.6835,1.4219,0.7398); endShape(); // WINGS beginShape(TRIANGLE_STRIP); vertex(7.5000,0.0419,-0.3457); vertex(7.5000,1.9419,-0.3457); vertex( 0.0000,-0.5077,-0.3457); vertex( 0.0000,3.2478,-0.3457); vertex(-7.5000,0.0419,-0.3457); vertex(-7.5000,1.9419,-0.3457); endShape(); // TAIL beginShape(TRIANGLE_STRIP); vertex(-3.1996,8.9219,0.5936); vertex(-3.1996,7.7203,0.5936); vertex( 0.0000,9.1381,0.5936); vertex( 0.0000,7.0593,0.5936); vertex( 3.2004,8.9219,0.5936); vertex( 3.2004,7.7203,0.5936); endShape(); // Gear beginShape(TRIANGLE_STRIP); vertex(1.7426 , 0.6742 ,-2.1340); vertex(1.7764 , 0.5546 ,-2.3393); vertex(1.8566 ,-0.4661 ,-1.9365); vertex(1.8601 ,-0.9817 ,-2.4453); vertex(1.7403 ,-1.2181 ,-2.2015); vertex(1.6174 ,-0.9850 ,-2.4438); vertex(1.6226 ,-0.4661 ,-1.9365); vertex(1.7043 , 0.5546 ,-2.3393); vertex(1.7426 , 0.6742 ,-2.1340); endShape(); beginShape(TRIANGLE_STRIP); vertex(-1.7426 , 0.6742 ,-2.1340); vertex(-1.7764 , 0.5546 ,-2.3393); vertex(-1.8566 ,-0.4661 ,-1.9365); vertex(-1.8601 ,-0.9817 ,-2.4453); vertex(-1.7403 ,-1.2181 ,-2.2015); vertex(-1.6174 ,-0.9850 ,-2.4438); vertex(-1.6226 ,-0.4661 ,-1.9365); vertex(-1.7043 , 0.5546 ,-2.3393); vertex(-1.7426 , 0.6742 ,-2.1340); endShape(); break; case 2: beginShape(TRIANGLE_FAN); vertex(0, -Wr*5,0); vertex(-Wr,Wr*2,0); vertex(Wr,Wr*2,0); vertex(0, Wr,Wr/3); endShape(); break; } popMatrix(); if (schweif == true){ if (traceCount%8==0){ Wtail = append (Wtail,Wloc.x); Wtail = append (Wtail,Wloc.y); Wtail = append (Wtail,Wloc.z); if (Wtail.length > 39){ // laenge auf 33 halten Wtail = reverse (Wtail); Wtail = shorten (Wtail); Wtail = shorten (Wtail); Wtail = shorten (Wtail); Wtail = reverse (Wtail); } } if (traceCount%1==0){ miniWtail = append (miniWtail,Wloc.x); miniWtail = append (miniWtail,Wloc.y); miniWtail = append (miniWtail,Wloc.z); if (miniWtail.length >6){ // laenge auf 6 halten miniWtail = reverse (miniWtail); miniWtail = shorten (miniWtail); miniWtail = shorten (miniWtail); miniWtail = shorten (miniWtail); miniWtail = reverse (miniWtail); } } } // array leerlaufen lassen else{ if (traceCount%6==0){ if (miniWtail.length > 2){ miniWtail = reverse (miniWtail); miniWtail = shorten(miniWtail); miniWtail = shorten(miniWtail); miniWtail = shorten(miniWtail); miniWtail = reverse (miniWtail); } if(Wtail.length>2){ Wtail = reverse (Wtail); Wtail = shorten (Wtail); Wtail = shorten (Wtail); Wtail = shorten (Wtail); Wtail = reverse (Wtail); } } } noFill(); // langer Schweif beginShape(); strokeWeight(3); if (Wtail.length >2){ for (int k=0 ; k 2){ for (int j=0;j < miniWtail.length;j+=3){ // Wrel_tpo aus vorschleife uebernehmen if (licht == true){ stroke (red(WtailColor),green(WtailColor),250*Wrel_tpo,40); } else{ stroke (120,120,20); } curveVertex(miniWtail[j],miniWtail[j+1],miniWtail[j+2]); } } endShape(); } //renderend // Wraparound void Wborders() { Wepo = ellipsoid (Wloc); GrenzDiff = Wepo.distance(Wepo,eMi)-Wloc.distance(Wloc,eMi); } // Borderline Vector3D borderline () { Vector3D sum = new Vector3D(0,0,0); if (GrenzDiff<0){ return steer(Wepo,false); } return sum; } // obstacle // Vector3D obstacle (ArrayList zepps) { float obsdist = 250.0f; float kpodist = 190.0f; Vector3D sum = new Vector3D(0,0,0); // Start with empty vector to accumulate all locations int count = 0; // For every Zepp in the system, check if it's too close for (int i = 0 ; i < zepps.size(); i++) { Zepp ze = (Zepp) zepps.get(i); float d = Wloc.distance(Wloc,ze.Zloc); // Grobcheck if (d < obsdist) { for (int j = 0; j < ze.kpo.length; j+=3){ // Kollisionsarray auslesen Vector3D obsV = new Vector3D(ze.kpo[j],ze.kpo[j+1],ze.kpo[j+2]); float d2 = Wloc.distance(Wloc,obsV); if (d2 < kpodist){ // Calculate vector pointing away from obstacle; Vector3D diff = Wloc.sub(Wloc,obsV); diff.normalize(); diff.div(d2); // Weight by distance sum.add(diff); } } } } // Average -- divide by how many if (count > 0) { sum.div((float)count); } return sum; } // Separation // Method checks for nearby boids and steers away Vector3D separate (ArrayList walters) { float desiredseparation = 300.0f; Vector3D sum = new Vector3D(0,0,0); int count = 0; // For every walter in the system, check if it's too close for (int i = 0 ; i < walters.size(); i++) { Walter other = (Walter) walters.get(i); float d = Wloc.distance(Wloc,other.Wloc); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < desiredseparation)) { if (d < minDist){ minDist=d; } // Calculate vector pointing away from neighbor Vector3D diff = Wloc.sub(Wloc,other.Wloc); diff.normalize(); diff.div(d); // Weight by distance sum.add(diff); count++; // Keep track of how many } } // Average -- divide by how many if (count > 0) { sum.div((float)count); } return sum; } // Hunting // basiert auf Kohesion Vector3D hunt (ArrayList boids) { float preydist = 200.0f; Vector3D sum = new Vector3D(0,0,0); // Start with empty vector to accumulate all locations int count = 0; for (int i = 0 ; i < boids.size(); i++) { Boid prey = (Boid) boids.get(i); float d = Wloc.distance(Wloc,prey.loc); if ((d > 0) && (d < preydist)) { if (d < minDist){ minDist=d; } sum.add(prey.loc); // Add location count++; } } if (count > 0) { sum.div((float)count); return steer(sum,false); // Steer towards the location } return sum; } } class Zepp { private Vector3D Zloc; private Vector3D Zvel; private Vector3D Zacc; private Vector3D Zepo; float kpo[]=new float [42]; float Zr; float Zmax_force; // Maximum steering force float Zmaxspeed; // Maximum speed float Zminspeed; float Zrel_eye; float Zrel_0; boolean crossed = false; int turning = 90; Zepp(Vector3D l, float ms, float mf) { Zacc = new Vector3D(0,0,0); Zvel = new Vector3D(random(-0.5,0.5),random(-0.5,0.5),random(-0.3,0.3)); Zepo = new Vector3D (0,0); Zloc = l.copy(); Zr = 12f; Zmaxspeed = ms; Zminspeed = ms/3; Zmax_force = mf; } void run(ArrayList zepps) { Zflock (zepps); Zupdate(); Zborders(); Zrender(); } // We accumulate a new acceleration each time based on three rules void Zflock(ArrayList zepps) { Vector3D bou = borderline(); // avoid borderline Vector3D sep = separate(zepps); // Separation // Arbitrarily weight these forces bou.mult(Zbou_f); sep.mult(Zsep_f); // Add the force vectors to acceleration Zacc.add(bou); Zacc.add(sep); } // Method to update location void Zupdate() { // Update velocity Zvel.add(Zacc); // Limit speed Zvel.limit(Zmaxspeed); Zvel.z*=0.7; Zvel.ulimit(Zminspeed); Zloc.add(Zvel); if (Zvel.magnitude()>ZeVMax){ ZeVMax=Zvel.magnitude(); } if (Zvel.magnitude()0;i--){ float phi = PI*i/imax+0.5*PI/imax; float phi2 = PI*(i+1)/imax+0.5*PI/imax; if (licht == false){ noFill(); strokeWeight (0.5); stroke(210,100,Zrel_eye*120); } else{ fill(90,90,255*Zrel_eye); noStroke(); } beginShape (QUAD_STRIP); int jmax = 20; for (int j=jmax;j>-1;j--){ float omega = TWO_PI/jmax*j; // z ist Laengsachse float ze = 2*Zr*cos(phi)*cos(omega); float ye = 2*Zr*sin(phi)*cos(omega); float ze2 = 2*Zr*cos(phi2)*cos(omega); float ye2 = 2*Zr*sin(phi2)*cos(omega); float xe = 10*Zr*sin(omega); stroke (60,60*i,255*Zrel_eye); // 42 Kollisionspunkte einspeisen in Array kpo if (i==1 && j%3==0){ stroke (255,255,0); // Koordinaten aus rotateZ() Befehl herauslesen Vector3D kpoV; kpoV = new Vector3D (xe,ye,ze); kpoV = kpoV.rot (0,0,theta); Vector3D kpoH; kpoH = new Vector3D (xe,ze,ye); kpoH = kpoH.rot (0,0,theta); // absolute Ortsvektoren generieren und nach xyz ins Array kpo [3*int(j/1.5)] = Zloc.x+kpoV.x; kpo [3*int(j/1.5)+1] = Zloc.y+kpoV.y; kpo [3*int(j/1.5)+2] = Zloc.z+kpoV.z; // schnitt einmal an laengsachse drehen kpo [3*int(j/1.5+1)] = Zloc.x+kpoH.x; kpo [3*int(j/1.5+1)+1] = Zloc.y+kpoH.y; kpo [3*int(j/1.5+1)+2] = Zloc.z+kpoH.z; } // Zeppelin zeichnen vertex (xe,ye,ze); vertex (xe,ye2,ze2); } endShape (); } popMatrix(); noFill(); } //Genzen pruefen void Zborders() { Zepo = ellipsoid (Zloc); } // Borderline Vector3D borderline () { float borderdist = 100.0f; Vector3D sum = new Vector3D(0,0,0);// Start with empty vector to accumulate all locations float d = Zloc.distance(Zloc,Zepo); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < borderdist)) { // Calculate vector pointing away from borderline; Vector3D diff = Zloc.sub(Zloc,Zepo); diff.normalize(); diff.div(20); // feintuning sum.add(diff); } return sum; } // Separation // Method checks for nearby boids and steers away Vector3D separate (ArrayList zepps) { float desiredseparation = 180.0f; float kpodist = 40.0f; Vector3D sum = new Vector3D(0,0,0); int count = 0; // For every Zepp in the system, check if it's too close for (int i = 0 ; i < zepps.size(); i++) { Zepp other = (Zepp) zepps.get(i); float d = Zloc.distance(Zloc,other.Zloc); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < desiredseparation)) { // Calculate vector pointing away from neighbor Vector3D diff = Zloc.sub(Zloc,other.Zloc); diff.normalize(); diff.div(d); // Weight by distance sum.add(diff); count++; // Keep track of how many } // Average -- divide by how many if (count > 0) { sum.div((float)count); } } return sum; } } // BOID KLASSE class Boid { Vector3D loc; Vector3D vel; Vector3D acc; Vector3D epo; float r; float max_force; // Maximum steering force float maxspeed; // Maximum speed float minspeed; float rel_0; float dist_0; float rel_eye; color tailColor = color (random (0,255),random(0,255),random(0,120)); float tail[] = new float[0]; float minitail[] = new float[0]; float rel_tpo; Boid(Vector3D l, float ms, float mf) { acc = new Vector3D(0,0,0); vel = new Vector3D(random(-1,1),random(-1,1),random(-1,1)); epo = new Vector3D (0,0); loc = l.copy(); r = 1.6f; maxspeed = ms; minspeed = ms*0.45; max_force = mf; } void run(ArrayList boids, ArrayList zepps, ArrayList walters) { Bflock(boids, zepps, walters); Bupdate(); Bborders(); Brender(); } // We accumulate a new acceleration each time based on three rules void Bflock(ArrayList boids, ArrayList zepps, ArrayList walters) { if (traceCount%15==0){ Ufak = frameRate*1.8; report = round(frameRate)+"fps "; report+=boids.size()+" Ranger@ "+round(BoVMin*Ufak)+"-"+round(BoVMax*Ufak)+"km/h "; report+=walters.size()+" EXTRA@ "+ round(WaVMin*Ufak)+"-"+round(WaVMax*Ufak)+"km/h "; report+=zepps.size()+" Zeppelin@ "+ round(ZeVMin*Ufak)+"-"+round(ZeVMax*Ufak)+"km/h minDist "+minDist/2+"m"; report+=char(10)+"Sep "+repSep+" Ali " +repAli+" Coh "+repCoh; } Vector3D obs = obstacle(zepps); // avoid obstacle Vector3D pre = predator(walters); // avoid predators Vector3D bou = borderline(); // avoid borderline Vector3D sep = separate(boids); // Separation Vector3D ali = align(boids); // Alignment Vector3D coh = cohesion(boids); // Cohesion // Arbitrarily weight these forces obs.mult(obs_f); pre.mult(pre_f); bou.mult(bou_f); sep.mult(sep_f); ali.mult(ali_f); coh.mult(coh_f); // Add the force vectors to acceleration acc.add(obs); acc.add(pre); acc.add(bou); acc.add(sep); acc.add(ali); acc.add(coh); } // Method to update location void Bupdate() { // Update velocity vel.add(acc); // Limit speed vel.limit(maxspeed); vel.ulimit(minspeed); loc.add(vel); if (vel.magnitude()>BoVMax){ BoVMax=vel.magnitude(); } if (vel.magnitude() 0) { // Normalize desired desired.normalize(); // Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed) if ((slowdown) && (d < 100.0f)) desired.mult(maxspeed*(d/100.0f)); // This damping is somewhat arbitrary else desired.mult(maxspeed); // Steering = Desired minus Velocity steer = target.sub(desired,vel); steer.limit(max_force); // Limit to maximum steering force } else { steer = new Vector3D(0,0); } return steer; } void Brender() { // Farbe rel_0 = loc.distance (loc,eMi)/epo.distance (epo,eMi); rel_eye = loc.distance (loc,eye)/rel_div; // Draw a triangle rotated in the direction of velocity float theta = vel.headingXY()+PI+HALF_PI; float beta = vel.headingZ()+PI; pushMatrix(); translate(loc.x,loc.y,loc.z); rotateZ(theta); rotateX (beta); rotateY (beta); if (licht == false){ noFill(); strokeWeight (0.5); stroke(210,210,rel_eye*120); } else{ fill(0); noStroke(); } switch (shape){ case 1: // CORPUS beginShape(TRIANGLE_STRIP); vertex(-0.2798,-3.5400, 0.4000); vertex(-0.3589,-3.360 , 0.0000); vertex(-0.4200,-2.0400, 0.9000); vertex(-0.4198,-2.0400, 0.0000); vertex(-0.4200,0.6400, 0.9000); vertex(-0.4200,0.6400, 0.0000); vertex(-0.3008,1.3650, 0.9000); vertex(-0.3008,1.3650, 0.2000); vertex( 0.3008,1.3650, 0.9000); vertex( 0.3008,1.3650, 0.2000); vertex( 0.4200,0.6400, 0.9000); vertex( 0.4202,0.6400, 0.0000); vertex( 0.4200,-2.0400, 0.9000); vertex( 0.4200,-2.0400, 0.0000); vertex( 0.2802,-3.5400, 0.4000); vertex( 0.3537,-3.360, 0.0000); vertex(-0.3589,-3.360, 0.0000); vertex( 0.2802,-3.5400, 0.4000); vertex(-0.2798,-3.5400, 0.4000); vertex( 0.4200,-2.0400, 0.9000); vertex(-0.4200,-2.0400, 0.9000); vertex( 0.4200,0.6400, 0.9000); vertex(-0.4200,0.6400, 0.9000); endShape(); // HUTZE beginShape(TRIANGLE_STRIP); vertex( 0.5700, 0.4500, 0.4500); vertex( 0.3500, 1.5200, 0.4500); vertex( 0.5700, 0.4500, 0.9000); vertex( 0.3500, 1.5200, 0.9000); vertex(-0.5700, 0.4500, 0.9000); vertex(-0.3500, 1.5200, 0.9000); vertex(-0.5700, 0.4500, 0.4500); vertex(-0.3500, 1.5200, 0.4500); endShape(); // WINGS beginShape(TRIANGLE_STRIP); vertex(-5.7011, 0.5682, 0.0800); vertex(-5.2930,-0.2806,0); vertex(-5.2611, 0.5607,0); vertex(-1.2348,-0.8489,0); vertex(-1.1828, 0.6605,0); vertex( 1.2048,-0.8909,0); vertex( 1.2048, 0.6193,0); vertex( 5.2802,-0.4627,0); vertex( 5.2773, 0.3792,0); vertex( 5.7172, 0.3716, 0.0800); endShape(); // TAIL beginShape(TRIANGLE_STRIP); vertex(-1.5506,4.1500,0.168); vertex(-1.4900,4.9500,0.2); vertex( 1.5506,4.1500,0.168); vertex( 1.4900,4.9500,0.2); endShape(); beginShape(TRIANGLE_STRIP); vertex(-1.1160, 0.0000,0); vertex(-1.1160, 4.9500,0.2); vertex(-1.1160, 4.1500,0.168); vertex(-1.1160, 5.4711, 1.5); vertex(-1.1160, 5.1666, 1.5); endShape(); beginShape(TRIANGLE_STRIP); vertex(1.1160, 0.0000,0); vertex(1.1160, 4.9500,0.2); vertex(1.1160, 4.1500,0.168); vertex(1.1160, 5.4711, 1.5); vertex(1.1160, 5.1666, 1.5); endShape(); break; case 2: beginShape(TRIANGLE_FAN); vertex(0, -r*5,0); vertex(-r,r*2,0); vertex(r, r*2,0); vertex(0, r,r/3); vertex(-r,r*2,0); endShape(); break; } popMatrix(); if (schweif == true){ if (traceCount%11==0){ tail = append (tail,loc.x); tail = append (tail,loc.y); tail = append (tail,loc.z); if (tail.length > 33){ // laenge auf 33 halten tail = reverse (tail); tail = shorten (tail); tail = shorten (tail); tail = shorten (tail); tail = reverse (tail); } } if (traceCount%2==0){ minitail = append (minitail,loc.x); minitail = append (minitail,loc.y); minitail = append (minitail,loc.z); if (minitail.length >6){ // laenge auf 6 halten minitail = reverse (minitail); minitail = shorten (minitail); minitail = shorten (minitail); minitail = shorten (minitail); minitail = reverse (minitail); } } } // array leerlaufen lassen else{ if (traceCount%6==0){ if (minitail.length > 2){ minitail = reverse (minitail); minitail = shorten(minitail); minitail = shorten(minitail); minitail = shorten(minitail); minitail = reverse (minitail); } if(tail.length>2){ tail = reverse (tail); tail = shorten (tail); tail = shorten (tail); tail = shorten (tail); tail = reverse (tail); } } } noFill(); // langer Schweif beginShape(); strokeWeight(1.2); if (tail.length >2){ for (int k=0 ; k 2){ for (int j=0;j < minitail.length;j+=3){ // rel_tpo aus vorschleife uebernehmen stroke (red(tailColor),green(tailColor),180*rel_tpo,40); //stroke (red(tailColor)*(1-j/minitail.length)+60,green(tailColor)*(1-j/minitail.length)+60,blue(tailColor)*rel_tpo+60,50); curveVertex(minitail[j],minitail[j+1],minitail[j+2]); } } endShape(); } //renderend // Wraparound void Bborders() { epo = ellipsoid (loc); } // Borderline Vector3D borderline () { float borderdist = 80.0f; Vector3D sum = new Vector3D(0,0,0);// Start with empty vector to accumulate all locations if (rel_0>0.7){ float d = loc.distance(loc,epo); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < borderdist)) { // Calculate vector pointing away from borderline; Vector3D diff = loc.sub(loc,epo); diff.normalize(); diff.div(d); // Weight by distance sum.add(diff); } } return sum; } // obstacle // Vector3D obstacle (ArrayList zepps) { float obsdist = 90.0f; float kpodist = 60.0f; Vector3D sum = new Vector3D(0,0,0); // Start with empty vector to accumulate all locations int count = 0; // For every Zepp in the system, check if it's too close for (int i = 0 ; i < zepps.size(); i++) { Zepp ze = (Zepp) zepps.get(i); float d = loc.distance(loc,ze.Zloc); // Grobcheck if (d < obsdist) { for (int j = 0; j < ze.kpo.length; j+=3){ // Kollisionsarray auslesen Vector3D obsV = new Vector3D(ze.kpo[j],ze.kpo[j+1],ze.kpo[j+2]); float d2 = loc.distance(loc,obsV); if (d2 < kpodist){ if (showObs==true){ stroke (255,255,100); line (loc.x,loc.y,loc.z,obsV.x,obsV.y,obsV.z); } // Calculate vector pointing away from obstacle; Vector3D diff = loc.sub(loc,obsV); diff.normalize(); diff.div(d2); // Weight by distance sum.add(diff); } } } } // Average -- divide by how many if (count > 0) { sum.div((float)count); } return sum; } // Predator Evasion // Method checks for nearby boids and steers away Vector3D predator (ArrayList walters) { float desiredseparation = 150.0f; Vector3D sum = new Vector3D(0,0,0); int count = 0; // For every walter in the system, check if it's too close for (int i = 0 ; i < walters.size(); i++) { Walter predator = (Walter) walters.get(i); float d = loc.distance(loc,predator.Wloc); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < desiredseparation)) { // Calculate vector pointing away from predator Vector3D diff = loc.sub(loc,predator.Wloc); diff.normalize(); diff.div(d); // Weight by distance sum.add(diff); count++; // Keep track of how many } } // Average -- divide by how many if (count > 0) { sum.div((float)count); } return sum; } // Separation // Method checks for nearby boids and steers away Vector3D separate (ArrayList boids) { float desiredseparation = 85.0f; Vector3D sum = new Vector3D(0,0,0); int count = 0; // For every boid in the system, check if it's too close for (int i = 0 ; i < boids.size(); i++) { Boid other = (Boid) boids.get(i); float d = loc.distance(loc,other.loc); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < desiredseparation)) { // Calculate vector pointing away from neighbor if (showSep==true){ stroke (0,255,255); line (loc.x,loc.y,loc.z,other.loc.x,other.loc.y,other.loc.z); } if (d < minDist){ minDist=d; } Vector3D diff = loc.sub(loc,other.loc); diff.normalize(); diff.div(d); // Weight by distance sum.add(diff); count++; // Keep track of how many } } // Average -- divide by how many if (count > 0) { sum.div((float)count); } return sum; } // Alignment // For every nearby boid in the system, calculate the average velocity Vector3D align (ArrayList boids) { float neighbordist = 90.0f; Vector3D sum = new Vector3D(0,0,0); int count = 0; for (int i = 0 ; i < boids.size(); i++) { Boid other = (Boid) boids.get(i); float d = loc.distance(loc,other.loc); if ((d > 0) && (d < neighbordist)) { if (showAli==true){ stroke (255,0,255); line (loc.x,loc.y,loc.z,other.loc.x,other.loc.y,other.loc.z); } sum.add(other.vel); count++; } } if (count > 0) { sum.div((float)count); sum.limit(max_force); } return sum; } // Cohesion // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location Vector3D cohesion (ArrayList boids) { float neighbordist = 100.0f; Vector3D sum = new Vector3D(0,0,0); // Start with empty vector to accumulate all locations int count = 0; for (int i = 0 ; i < boids.size(); i++) { Boid other = (Boid) boids.get(i); float d = loc.distance(loc,other.loc); if ((d > 0) && (d < neighbordist)) { if (showCoh==true){ stroke (0,255,0); line (loc.x,loc.y,loc.z,other.loc.x,other.loc.y,other.loc.z); } sum.add(other.loc); // Add location count++; } } if (count > 0) { sum.div((float)count); return steer(sum,false); // Steer towards the location } return sum; } } // Simple Vector3D Class static class Vector3D { float x; float y; float z; Vector3D(float x_, float y_, float z_) { x = x_; y = y_; z = z_; } Vector3D(float x_, float y_) { x = x_; y = y_; z = 0f; } Vector3D() { x = 0f; y = 0f; z = 0f; } void setX(float x_) { x = x_; } void setY(float y_) { y = y_; } void setZ(float z_) { z = z_; } void setXY(float x_, float y_) { x = x_; y = y_; } void setXYZ(float x_, float y_, float z_) { x = x_; y = y_; z = z_; } void setXYZ(Vector3D v) { x = v.x; y = v.y; z = v.z; } float magnitude() { return (float) Math.sqrt(x*x + y*y + z*z); } Vector3D copy() { return new Vector3D(x,y,z); } Vector3D copy(Vector3D v) { return new Vector3D(v.x, v.y,v.z); } void add(Vector3D v) { x += v.x; y += v.y; z += v.z; } void sub(Vector3D v) { x -= v.x; y -= v.y; z -= v.z; } void mult(float n) { x *= n; y *= n; z *= n; } void div(float n) { x /= n; y /= n; z /= n; } void normalize() { float m = magnitude(); if (m > 0) { div(m); } } void limit(float maxi) { if (magnitude() > maxi) { normalize(); mult(maxi); } } void ulimit(float mini) { if (magnitude() < mini) { normalize(); mult(mini); } } float headingXY() { float angle = (float) Math.atan2(-y, x); return -1*angle; } float headingYZ() { float angle = (float) Math.atan2(-z, y); return -1*angle; } float headingZX() { float angle = (float) Math.atan2(-x, z); return -1*angle; } float headingZ() { float xy = dist (0,0,x,y); float angle = (float) Math.atan2(-z, xy); return -1*angle; } Vector3D add(Vector3D v1, Vector3D v2) { Vector3D v = new Vector3D(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z); return v; } Vector3D sub(Vector3D v1, Vector3D v2) { Vector3D v = new Vector3D(v1.x - v2.x,v1.y - v2.y,v1.z - v2.z); return v; } Vector3D div(Vector3D v1, float n) { Vector3D v = new Vector3D(v1.x/n,v1.y/n,v1.z/n); return v; } Vector3D mult(Vector3D v1, float n) { Vector3D v = new Vector3D(v1.x*n,v1.y*n,v1.z*n); return v; } Vector3D rot (float xAng,float yAng,float zAng) { Vector3D v = new Vector3D(x,y,z); if (xAng>0){ float exAng=atan2(v.z,v.y); float len = dist(0,0,v.y,v.z); v.y = len*cos(xAng+exAng); v.z = len*sin(xAng+exAng); } if (yAng>0){ float exAng=atan2(v.x,v.z); float len = dist(0,0,v.x,v.z); v.x = len*cos(yAng+exAng); v.z = len*sin(yAng+exAng); } if (zAng>0){ float exAng=atan2(v.y,v.x); float len = dist(0,0,v.x,v.y); v.x = len*cos(zAng+exAng); v.y = len*sin(zAng+exAng); } return v; } float distance (Vector3D v1, Vector3D v2) { float dx = v1.x - v2.x; float dy = v1.y - v2.y; float dz = v1.z - v2.z; return (float) Math.sqrt(dx*dx + dy*dy + dz*dz); } } void keyPressed(){ deadCount = 0; if (key == 'q'){ if (sep_f0.0f){ sep_f-=1.0f; } } if (key == 'x'){ if (showSep==false){ showSep =true; } else{ showSep=false; } } if (key == 'w'){ if (ali_f0.0f){ ali_f-=1.0f; } } if (key == 'y'){ if (showAli==false){ showAli=true; } else{ showAli=false; } } if (key == 'e'){ if (coh_f0.0f){ coh_f-=1.0f; } } if (key == 'c'){ if (showCoh==false){ showCoh=true; } else{ showCoh=false; } } if (key == 'o'){ if (showObs==false){ showObs=true; } else{ showObs=false; } } if (key == 't'){ if (schweif==false){ schweif =true; } else{ schweif=false; } } if (key == 'l'){ if (licht==false){ licht =true; } else{ licht=false; } } if (key == 'k'){ if (boundviz==false){ boundviz =true; } else{ boundviz=false; } } /* if (key == 'R' || key == 'r') { // Press R to save the file record = true; }

Source code: flok308

Built with Processing