1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 #include "Boid.h" 15 16 Boid::Boid(float x, float y) : 17 mPosition(x, y) { 18 } 19 20 void Boid::flock(const Boid* boids[], int numBoids, int index, float limitX, float limitY) { 21 // Reset the acceleration. 22 mAcceleration.mX = 0; 23 mAcceleration.mY = 0; 24 Vector2D separation; 25 int separationCount = 0; 26 Vector2D alignment; 27 int alignmentCount = 0; 28 Vector2D cohesion; 29 int cohesionCount = 0; 30 for (int i = 0; i < numBoids; i++) { 31 if (i != index) { 32 const Boid* b = boids[i]; 33 float dist = mPosition.distance(b->mPosition); 34 if (dist != 0) { 35 // Separation. 36 if (dist < DESIRED_BOID_DIST) { 37 Vector2D tmp = mPosition.copy(); 38 tmp.sub(b->mPosition); 39 tmp.normalize(); 40 tmp.scale(1.0f / dist); 41 separation.add(tmp); 42 separationCount++; 43 } 44 if (dist < NEIGHBOUR_RADIUS) { 45 // Alignment. 46 alignment.add(b->mVelocity); 47 alignmentCount++; 48 // Cohesion. 49 cohesion.add(b->mPosition); 50 cohesionCount++; 51 } 52 } 53 } 54 } 55 56 if (separationCount > 0) { 57 separation.scale(1.0f / separationCount); 58 separation.scale(SEPARATION_WEIGHT); 59 mAcceleration.add(separation); 60 } 61 if (alignmentCount > 0) { 62 alignment.scale(1.0f / alignmentCount); 63 alignment.limit(MAX_FORCE); 64 alignment.scale(ALIGNMENT_WEIGHT); 65 mAcceleration.add(alignment); 66 } 67 if (cohesionCount > 0) { 68 cohesion.scale(1.0f / cohesionCount); 69 cohesion.scale(COHESION_WEIGHT); 70 Vector2D desired = cohesion.copy(); 71 desired.sub(mPosition); 72 float d = desired.magnitude(); 73 if (d > 0) { 74 desired.normalize(); 75 desired.scale(MAX_SPEED * ((d < 100.0f) ? d / 100.0f : 1)); 76 desired.sub(mVelocity); 77 desired.limit(MAX_FORCE); 78 mAcceleration.add(desired); 79 } 80 } 81 82 mVelocity.add(mAcceleration); 83 mVelocity.limit(MAX_SPEED); 84 mPosition.add(mVelocity); 85 // Wrap around. 86 if (mPosition.mX < -limitX) { 87 mPosition.mX = limitX; 88 } else if (mPosition.mX > limitX) { 89 mPosition.mX = -limitX; 90 } 91 if (mPosition.mY < -limitY) { 92 mPosition.mY = limitY; 93 } else if (mPosition.mY > limitY) { 94 mPosition.mY = -limitY; 95 } 96 } 97