class Slug extends Walker{ float x1,x2 = 15,p1y,p2y,p1x,p2x,ym; float fx, fy, _fx, _fy; //same float t = 8; float u = 100; float v; float q; float flatness=20; float headWidth = 45; float slugHeight = 115; float SlugWidth = 20; float feelerHeight = 30; float feelerWidth = 30; float maxspeed = .5; float maxforce =.001; Slug() { super(); theta = random(360); w = 20; h = 90; //fix!!!!!! vel.set(random(-1,1),random(-1,0),0); } void update(){ super.update(); vel.limit(maxspeed); loc.add(vel); acc.mult(0); p1x = 4; p2x = 8; } void render(){ super.render(); // println("hi"); theta +=.05; p1y = -100+slugHeight/2 -10 * PApplet.sin(theta); pushMatrix(); translate(loc.x,loc.y); rotate(vel.heading2D()+radians(90)); // ellipse(0,0,w,h); beginShape(); vertex(0,0+slugHeight/2); bezierVertex(0 + flatness, 0+slugHeight/2, p1x + flatness, p1y, p1x, p1y); bezierVertex(p1x - flatness, p1y, p2x - flatness, +slugHeight/2, 0, +slugHeight/2); // println("locx " + loc.x + ", loc y " + loc.y); endShape(); calculateFeelers(); drawFeelers(); popMatrix(); } void calculateFeelers(){ float xoff = t; float yoff = u; float loff = v; float moff = q; for (int i = 0; i < width; i++) { fy = p1y-slugHeight/6-(noise(xoff)*feelerHeight); _fy = p1y-slugHeight/6-(noise(yoff)*feelerHeight); fx = (5)+(noise(loff)*feelerWidth); _fx = (+5)-(noise(moff)*feelerWidth); yoff += 0.02; xoff += 0.01; stroke(255); //line(i,height,i,height-y); } t+= 0.01; u +=.01; v +=.01; q +=.01; } void drawFeelers(){ stroke(0); noFill(); // line(x1-headWidth/4, p1y-slugHeight/2+5, _fx, _y); //line(x1+headWidth/4,p1y-slugHeight/2, 1x, y); bezier(-headWidth/4+8, p1y+5, -headWidth/6+5, p1y-h/4, _fx, _fy+5, _fx-2,_fy); bezier(+headWidth/4-7+5, p1y+5, headWidth/6+5, p1y-h/6, fx+5, fy+5, fx+5, fy-3); fill(0); ellipse(_fx-2,_fy,5,5); ellipse(fx+5,fy-3,5,5); } void drawSlug(PVector diff){ pushMatrix(); translate(loc.x,loc.y); rotate(vel.heading2D()+radians(90)); render(); popMatrix(); } PVector getLoc() { return loc.get(); } void setVel(PVector v) { vel = v.get(); } PVector steer(PVector target, boolean slowdown) { PVector steer; // The steering vector PVector desired = PVector.sub(target,loc); // A vector pointing from the location to the target float d = desired.mag(); // Distance from the target is the magnitude of the vector // If the distance is greater than 0, calc steering (otherwise return zero vector) if (d > 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 = PVector.sub(desired,vel); steer.limit(maxforce); // Limit to maximum steering force } else { steer = new PVector(0,0); } return steer; } void wander() { float wanderR = 10.0f; // Radius for our "wander circle" float wanderD = 10.0f; // Distance for our "wander circle" float change = 0.001f; wandertheta += random(-change,change); // Randomly change wander theta // Now we have to calculate the new location to steer towards on the wander circle PVector circleloc = vel.get(); // Start with velocity circleloc.normalize(); // Normalize to get heading circleloc.mult(wanderD); // Multiply by distance circleloc.add(loc); // Make it relative to boid's location PVector circleOffSet = new PVector(wanderR *cos(wandertheta),wanderR*sin(wandertheta)); PVector target = PVector.add(circleloc,circleOffSet); PVector avoid = new PVector(0,0,0); avoid.add(avoidEdge()); avoid.mult(.2); acc.add(avoid); acc.add(steer(target,false)); // Steer towards it // Render wandering circle, etc. // drawWanderStuff(loc,circleloc,target,wanderR); } PVector avoidEdge () { float desiredseparation = 100f; PVector sum = new PVector(0,0,0); PVector wall; float d; if (loc.x-slugHeight < 0){ wall = new PVector(0,loc.y); d = PVector.dist(loc,wall); } else if (loc.y-slugHeight < 0){ wall = new PVector(loc.x,0); d = PVector.dist(loc,wall); } else if (loc.x+slugHeight/2 > width-slugHeight){ wall = new PVector(width, loc.y); d = PVector.dist(loc,wall); } else if (loc.y+slugHeight/2 > height-slugHeight) { wall = new PVector(loc.x, height); d = PVector.dist(loc,wall); } else{ d = 0.0; wall = new PVector(0,0,0); } // 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 PVector diff = PVector.sub(loc,wall); diff.normalize(); diff.div(d); // Weight by distance sum.add(diff); } return sum; } void drawWanderStuff(PVector loc, PVector circle, PVector target, float rad) { stroke(0); noFill(); ellipseMode(CENTER); ellipse(circle.x,circle.y,rad*2,rad*2); ellipse(target.x,target.y,4,4); line(loc.x,loc.y,circle.x,circle.y); line(circle.x,circle.y,target.x,target.y); } }