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
Boid(float x,float y)16 Boid::Boid(float x, float y) :
17 mPosition(x, y) {
18 }
19
flock(const Boid * boids[],int numBoids,int index,float limitX,float limitY)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