Advertisement
Guest User

Processing, Boid and Node

a guest
May 16th, 2016
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.91 KB | None | 0 0
  1. //Note: If there is 150 node, you need at least 150 boids
  2. //But you can put more boids in the screen than the number of nodes
  3.  
  4. Flock flock;
  5. int nbBoid = 300;
  6. Node[] nodes = new Node[nbBoid];
  7. int nodeCount = 150;
  8.  
  9. void setup() {
  10. size(1000, 1000, P2D);
  11. flock = new Flock();
  12. // Add an initial set of boids into the system
  13. for (int i = 0; i < nbBoid; i++) {
  14. //flock.addBoid(new Boid(random(width), random(height)));
  15. flock.addBoid(new Boid(random(width), random(height)));
  16. nodes[i] = new Node(i, nodes);
  17. }
  18. }
  19.  
  20.  
  21.  
  22. void draw() {
  23. background(0);
  24. fill(0);
  25. rect(0, 0, width, height);
  26.  
  27. flock.run();
  28.  
  29. for (int i = 0; i < nbBoid; i++) {
  30. //Set the postition of the node at the position of the boid
  31. nodes[i].setPos(flock.getPos(i));
  32. }
  33.  
  34. for (int i = 0; i < nbBoid; i++) {
  35. nodes[i].display();
  36. nodes[i].displayNetwork(nodeCount);
  37. }
  38.  
  39. //saveFrame("output/img####.tif");
  40. }
  41.  
  42.  
  43.  
  44. // The Flock (a list of Boid objects) Note: By Daniel Shiffman
  45. //I took the example from the website Processing.org
  46.  
  47. class Flock {
  48. ArrayList<Boid> boids; // An ArrayList for all the boids
  49.  
  50. Flock() {
  51. boids = new ArrayList<Boid>(); // Initialize the ArrayList
  52. }
  53.  
  54. void run() {
  55. for (Boid b : boids) {
  56. b.run(boids); // Passing the entire list of boids to each boid individually
  57. }
  58. }
  59.  
  60. PVector getPos(int _i) {
  61. return boids.get(_i).getPos();
  62. }
  63.  
  64. void addBoid(Boid b) {
  65. boids.add(b);
  66. }
  67. }
  68.  
  69.  
  70.  
  71.  
  72. // The Boid class
  73.  
  74. class Boid {
  75.  
  76. PVector location;
  77. PVector velocity;
  78. PVector acceleration;
  79. float r;
  80. float maxforce; // Maximum steering force
  81. float maxspeed; // Maximum speed
  82.  
  83. Boid(float x, float y) {
  84. acceleration = new PVector(0, 0);
  85.  
  86. // This is a new PVector method not yet implemented in JS
  87. // velocity = PVector.random2D();
  88.  
  89. // Leaving the code temporarily this way so that this example runs in JS
  90. float angle = random(TWO_PI);
  91. velocity = new PVector(cos(angle), sin(angle));
  92.  
  93. location = new PVector(x, y);
  94. r = 2.0;
  95. maxspeed = 2;
  96. maxforce = 0.03;
  97. }
  98.  
  99. PVector getPos() {
  100. return location;
  101. }
  102.  
  103. void run(ArrayList<Boid> boids) {
  104. flock(boids);
  105. update();
  106. borders();
  107. //render();
  108. }
  109.  
  110. void applyForce(PVector force) {
  111. // We could add mass here if we want A = F / M
  112. acceleration.add(force);
  113. }
  114.  
  115. // We accumulate a new acceleration each time based on three rules
  116. void flock(ArrayList<Boid> boids) {
  117. PVector sep = separate(boids); // Separation
  118. PVector ali = align(boids); // Alignment
  119. PVector coh = cohesion(boids); // Cohesion
  120. // Arbitrarily weight these forces
  121. sep.mult(1.5);
  122. ali.mult(1.0);
  123. coh.mult(1.0);
  124. // Add the force vectors to acceleration
  125. applyForce(sep);
  126. applyForce(ali);
  127. applyForce(coh);
  128. }
  129.  
  130. // Method to update location
  131. void update() {
  132. // Update velocity
  133. velocity.add(acceleration);
  134. // Limit speed
  135. velocity.limit(maxspeed);
  136. location.add(velocity);
  137. // Reset accelertion to 0 each cycle
  138. acceleration.mult(0);
  139. }
  140.  
  141. // A method that calculates and applies a steering force towards a target
  142. // STEER = DESIRED MINUS VELOCITY
  143. PVector seek(PVector target) {
  144. PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target
  145. // Scale to maximum speed
  146. desired.normalize();
  147. desired.mult(maxspeed);
  148.  
  149. // Above two lines of code below could be condensed with new PVector setMag() method
  150. // Not using this method until Processing.js catches up
  151. // desired.setMag(maxspeed);
  152.  
  153. // Steering = Desired minus Velocity
  154. PVector steer = PVector.sub(desired, velocity);
  155. steer.limit(maxforce); // Limit to maximum steering force
  156. return steer;
  157. }
  158.  
  159. void render() {
  160. // Draw a triangle rotated in the direction of velocity
  161. float theta = velocity.heading2D() + radians(90);
  162. // heading2D() above is now heading() but leaving old syntax until Processing.js catches up
  163.  
  164. fill(200, 100);
  165. stroke(255);
  166. pushMatrix();
  167. translate(location.x, location.y);
  168. rotate(theta);
  169. beginShape(TRIANGLES);
  170. vertex(0, -r*2);
  171. vertex(-r, r*2);
  172. vertex(r, r*2);
  173. endShape();
  174. popMatrix();
  175. }
  176.  
  177. // Wraparound
  178. void borders() {
  179. if (location.x < -r) location.x = width+r;
  180. if (location.y < -r) location.y = height+r;
  181. if (location.x > width+r) location.x = -r;
  182. if (location.y > height+r) location.y = -r;
  183. }
  184.  
  185. // Separation
  186. // Method checks for nearby boids and steers away
  187. PVector separate (ArrayList<Boid> boids) {
  188. float desiredseparation = 25.0f;
  189. PVector steer = new PVector(0, 0, 0);
  190. int count = 0;
  191. // For every boid in the system, check if it's too close
  192. for (Boid other : boids) {
  193. float d = PVector.dist(location, other.location);
  194. // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
  195. if ((d > 0) && (d < desiredseparation)) {
  196. // Calculate vector pointing away from neighbor
  197. PVector diff = PVector.sub(location, other.location);
  198. diff.normalize();
  199. diff.div(d); // Weight by distance
  200. steer.add(diff);
  201. count++; // Keep track of how many
  202. }
  203. }
  204. // Average -- divide by how many
  205. if (count > 0) {
  206. steer.div((float)count);
  207. }
  208.  
  209. // As long as the vector is greater than 0
  210. if (steer.mag() > 0) {
  211. // First two lines of code below could be condensed with new PVector setMag() method
  212. // Not using this method until Processing.js catches up
  213. // steer.setMag(maxspeed);
  214.  
  215. // Implement Reynolds: Steering = Desired - Velocity
  216. steer.normalize();
  217. steer.mult(maxspeed);
  218. steer.sub(velocity);
  219. steer.limit(maxforce);
  220. }
  221. return steer;
  222. }
  223.  
  224. // Alignment
  225. // For every nearby boid in the system, calculate the average velocity
  226. PVector align (ArrayList<Boid> boids) {
  227. float neighbordist = 50;
  228. PVector sum = new PVector(0, 0);
  229. int count = 0;
  230. for (Boid other : boids) {
  231. float d = PVector.dist(location, other.location);
  232. if ((d > 0) && (d < neighbordist)) {
  233. sum.add(other.velocity);
  234. count++;
  235. }
  236. }
  237. if (count > 0) {
  238. sum.div((float)count);
  239. // First two lines of code below could be condensed with new PVector setMag() method
  240. // Not using this method until Processing.js catches up
  241. // sum.setMag(maxspeed);
  242.  
  243. // Implement Reynolds: Steering = Desired - Velocity
  244. sum.normalize();
  245. sum.mult(maxspeed);
  246. PVector steer = PVector.sub(sum, velocity);
  247. steer.limit(maxforce);
  248. return steer;
  249. } else {
  250. return new PVector(0, 0);
  251. }
  252. }
  253.  
  254. // Cohesion
  255. // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location
  256. PVector cohesion (ArrayList<Boid> boids) {
  257. float neighbordist = 50;
  258. PVector sum = new PVector(0, 0); // Start with empty vector to accumulate all locations
  259. int count = 0;
  260. for (Boid other : boids) {
  261. float d = PVector.dist(location, other.location);
  262. if ((d > 0) && (d < neighbordist)) {
  263. sum.add(other.location); // Add location
  264. count++;
  265. }
  266. }
  267. if (count > 0) {
  268. sum.div(count);
  269. return seek(sum); // Steer towards the location
  270. } else {
  271. return new PVector(0, 0);
  272. }
  273. }
  274. }
  275.  
  276.  
  277. ///////////////////////////////////////////////////////////
  278.  
  279. //It might be an example from Casey Reas / ben Fry's book, Processing for visual designer
  280.  
  281. class Node {
  282.  
  283. PVector pos = new PVector(0, 0);
  284. float radius = 20;
  285. color col = 0;
  286. int ID;
  287. float r;
  288. Node[] otherNodes;
  289.  
  290. Node(int _ID, Node[] _otherNodes) {
  291. otherNodes = _otherNodes;
  292. ID = _ID;
  293. }
  294.  
  295. void setPos(PVector _pos) {
  296. pos = _pos.copy();
  297. col = color(map(pos.x + pos.y, 0, width+height, 255, 0), map(pos.x + pos.y, 0, width+height, 127, 255), map(pos.x * pos.y, 0, width*height, 0, 255));
  298. }
  299.  
  300. void display() {
  301. ellipseMode(RADIUS);
  302. noStroke();
  303.  
  304. r = (sin(frameCount*0.1)+2+noise(ID*150)*10);
  305. fill(col, map(r, 8.0, 20.0, 30, 200));
  306. ellipse(pos.x, pos.y, r, r);
  307. }
  308.  
  309. void displayNetwork(int _nodeCount) {
  310.  
  311. for (int i = ID+1; i < _nodeCount; i++) {
  312. if (overlap(otherNodes[i])) {
  313. beginShape(LINES);
  314. strokeWeight(sin(frameCount*0.1+PI)+2+noise(ID*150));
  315. stroke(col, map(r, 8.0, 20.0, 30, 200));
  316. vertex(pos.x, pos.y);
  317. stroke(otherNodes[i].col);
  318. vertex(otherNodes[i].pos.x, otherNodes[i].pos.y);
  319. endShape();
  320. }
  321. }
  322. }
  323.  
  324. boolean overlap(Node n) {
  325. float _dist = dist(pos.x, pos.y, n.pos.x, n.pos.y);
  326. float diameter = radius + n.radius;
  327.  
  328. if (_dist < diameter) {
  329. return true;
  330. } else {
  331. return false;
  332. }
  333. }
  334. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement