Tuesday, February 7, 2012

Processing: Flocking

This is the Processing code for a flocking algorithm as covered during a workshop on 2/6/2012.







The code used for this example is based on the structure used by Kokkugia (www.kokkugia.com) for it's agent based work. The fall off and range structure is based on Ian Couzin's work (http://icouzin.princeton.edu/) as outlined by Robert Hodgins for a Cinder tutorial on flocking (http://libcinder.org/docs/v0.8.3/hello_cinder.html).

Tab 1(flock):


  1. int agentCount = 1000;
  2. ArrayList agents;

  3. void setup(){
  4. smooth();
  5. size(1280,720);
  6. agents = new ArrayList();
  7. for(int i = 0; i < agentCount; i++){
  8. PVector startPos = new PVector(random(0,width), random(0,height));
  9. PVector startVel = new PVector(random(-1, 1), random(-1,1));
  10. startVel.normalize();
  11. float startRad = random(2,10);
  12. agent a = new agent(startPos, startVel, startRad);
  13. agents.add(a);
  14. }
  15. }

  16. void draw(){
  17. background(255);
  18. for(int i = 0; i < agents.size(); i++){
  19. agent a = (agent) agents.get(i);
  20. a.update();
  21. //a.render();
  22. }

  23. for(int i = 0; i < agents.size(); i++){
  24. agent a = (agent) agents.get(i);
  25. // a.update();
  26. a.render();
  27. }

  28. for(int i = 0; i< agents.size(); i++){
  29. agent a = (agent) agents.get(i);
  30. // a.update();
  31. a.renderE();
  32. }

  33. saveFrame();

  34. if(frameCount > 1000){
  35. exit();
  36. }
  37. }


Tab 2: agents

  1. class agent{
  2. float rad;
  3. PVector pos;
  4. PVector vel;
  5. float range;
  6. float lowThresh;
  7. float highThresh;

  8. agent(PVector _pos, PVector _vel, float _rad){
  9. rad = _rad;
  10. pos = _pos;
  11. vel = _vel;
  12. //set values for range here. range is overall distance, and the thresh variables say what percent
  13. //of that range we cut off for the different functions.
  14. range = 60;
  15. lowThresh = .40;
  16. highThresh = .60;
  17. }

  18. void update(){
  19. PVector acc = new PVector();
  20. //vel = new PVector();
  21. PVector coh = cohesion();
  22. PVector avd = avoid();
  23. PVector ali = align();

  24. //adjust the strengths of the behaviors here
  25. coh.mult(.3);
  26. avd.mult(1);
  27. ali.mult(1);

  28. acc.add(coh);
  29. acc.add(avd);
  30. acc.add(ali);

  31. vel.add(acc);
  32. vel.limit(2);
  33. pos.add(vel);
  34. borders();
  35. }

  36. void borders(){
  37. if(pos.x < 0){
  38. pos.x = width;
  39. }
  40. if(pos.y < 0){
  41. pos.y = height;
  42. }
  43. if(pos.x > width){
  44. pos.x = 0;
  45. }
  46. if(pos.y > height){
  47. pos.y = 0;
  48. }
  49. }

  50. PVector align(){
  51. PVector sum = new PVector();
  52. float threshDelta = highThresh - lowThresh;

  53. for(int i = 0; i < agents.size(); i++){
  54. agent other = (agent) agents.get(i);
  55. float dis = pos.dist(other.pos);
  56. float percent = pow(dis,2)/pow(range,2);

  57. if(percent < highThresh && dis > lowThresh){
  58. percent = (percent - lowThresh)/threshDelta;
  59. float scalar = (.5-cos(percent*2*PI)*.5 + .5) *.1;
  60. PVector temp = other.vel.get();
  61. temp.normalize();
  62. temp.mult(scalar);
  63. sum.add(temp);
  64. }
  65. }
  66. return sum;
  67. }

  68. //this makes agents avoid each other
  69. PVector avoid(){
  70. PVector sum = new PVector();

  71. for(int i = 0; i < agents.size(); i++){
  72. agent other = (agent) agents.get(i);
  73. float dis = pos.dist(other.pos);
  74. dis = pow(dis,2);
  75. float percent = dis/pow(range,2);

  76. if(dis >0 && percent < lowThresh){
  77. float scalar = (lowThresh/ percent - 1)*.01;
  78. PVector temp = pos.get();
  79. temp.sub(other.pos);
  80. temp.normalize();
  81. temp.mult(scalar);
  82. sum.add(temp);
  83. }
  84. }
  85. return sum;
  86. }

  87. PVector cohesion(){
  88. PVector sum = new PVector();
  89. float threshDelta = 1-highThresh;
  90. for(int i = 0; i < agents.size(); i++){
  91. agent other = (agent) agents.get(i);
  92. float dis = pos.dist(other.pos);
  93. float percent = pow(dis,2)/( pow(range,2));
  94. if(percent > highThresh && percent <= 1){
  95. percent = (percent - highThresh)/threshDelta;
  96. float scalar = (.5- cos(percent*PI*2)*.5 +.5)*.01;
  97. PVector temp = other.pos.get();
  98. temp.sub(pos);
  99. temp.normalize();
  100. temp.mult(scalar);
  101. sum.add(temp);
  102. }
  103. }
  104. return sum;
  105. }

  106. void render(){
  107. float closeDist = 99999;
  108. strokeWeight(.01);
  109. stroke(150);
  110. PVector target = new PVector();

  111. for(int i = 0; i < agents.size(); i++){
  112. agent other = (agent) agents.get(i);
  113. float tempDist = pos.dist(other.pos);

  114. if(tempDist < .5*range && tempDist > 0){
  115. line(pos.x, pos.y, other.pos.x, other.pos.y);
  116. }
  117. }
  118. }

  119. void renderE(){
  120. fill(0, 0,0);
  121. // stroke(150,0,0);
  122. noStroke();
  123. ellipse(pos.x, pos.y, rad, rad);
  124. }
  125. }



No comments:

Post a Comment