OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef GOOSE_H_ | |
6 #define GOOSE_H_ | |
7 | |
8 #include <vector> | |
9 #include "nacl_app/vector2.h" | |
10 #include "ppapi/cpp/rect.h" | |
11 | |
12 namespace flocking_geese { | |
13 | |
14 // A Goose. Each goose has a location and a velocity. Implements the | |
15 // flocking algortihm described here: | |
16 // http://processingjs.org/learning/topic/flocking with references to | |
17 // http://harry.me/2011/02/17/neat-algorithms---flocking. | |
18 class Goose { | |
19 public: | |
20 // Initialize a Goose at location (0, 0) with random velocity. | |
21 Goose(); | |
22 // Initialize a Goose at the given location with random velocity. | |
23 explicit Goose(const Vector2& location); | |
24 ~Goose() {} | |
25 | |
26 // Run one tick of the simulation. Compute a new acceleration based on the | |
27 // flocking algorithm (see Goose.flock()) and update the goose's location | |
28 // by integrating acceleration and velocity. | |
29 // @param geese The list of all the geese in the flock. | |
30 // @param attractors The list of attractors. Geese have affinity for these | |
31 // points. | |
32 // @param flockBox The geese will stay inside of this box. If the parameter | |
33 // is not given, the geese don't have boundaries. | |
34 void SimulationTick(const std::vector<Goose>& geese, | |
35 const std::vector<Vector2>& attractors, | |
36 const pp::Rect& flockBox); | |
37 | |
38 // Implement the flocking algorithm in five steps: | |
39 // 1. Compute the separation component, | |
40 // 2. Compute the alignment component, | |
41 // 3. Compute the cohesion component. | |
42 // 4. Compute the effect of the attractors and blend this in with the | |
43 // cohesion component. | |
44 // 5. Create a weighted sum of the three components and use this as the | |
45 // new acceleration for the goose. | |
46 // This is an O(n^2) version of the algorithm. There are ways to speed this | |
47 // up using spatial coherence techniques, but this version is much simpler. | |
48 // @param geese The list of all the neighbouring geese (in this | |
49 // implementation, this is all the geese in the flock). | |
50 // @param attractors The list of attractors. Geese have affinity for these | |
51 // points. | |
52 // @return The acceleration vector for this goose based on the flocking | |
53 // algorithm. | |
54 Vector2 Flock(const std::vector<Goose>& geese, | |
55 const std::vector<Vector2>& attractors); | |
56 | |
57 // Turn the goose towards a target. The amount of turning force is clamped | |
58 // to |kMaxTurningForce|. | |
59 // @param target Turn the goose towards this target. | |
60 // @return A vector representing the new direction of the goose. | |
61 Vector2 TurnTowardsTarget(const Vector2& target); | |
62 | |
63 // Accessors for location and velocoity. | |
64 Vector2 location() const { | |
65 return location_; | |
66 } | |
67 Vector2 velocity() const { | |
68 return velocity_; | |
69 } | |
70 | |
71 private: | |
72 // Add a neighbouring goose's contribution to the separation mean. Only | |
73 // consider geese that have moved inside of this goose's personal space. | |
74 // Modifies the separation accumulator |separation| in-place. | |
75 // @param distance The distance from this goose to the neighbouring goose. | |
76 // @param gooseDirection The direction vector from this goose to the | |
77 // neighbour. | |
78 // @param separation The accumulated separation from all the neighbouring | |
79 // geese. | |
80 // @param separationCount The current number of geese that have contributed to | |
81 // the separation component so far. | |
82 // @return The new count of geese that contribute to the separation component. | |
83 // If the goose under consideration does not contribute, this value is the | |
84 // same as |separationCount|. | |
85 int32_t AccumulateSeparation(double distance, | |
86 const Vector2& gooseDirection, | |
87 Vector2* separation, /* inout */ | |
88 int32_t separationCount); | |
89 | |
90 // Add a neighbouring goose's contribution to the alignment mean. Alignment | |
91 // is the average velocity of the neighbours. Only consider geese that are | |
92 // within |kNeighbourRadius|. Modifies the alignment accumulator |alignment| | |
93 // in-place. | |
94 // @param distance The distance from this goose to the neighbouring goose. | |
95 // @param goose The neighbouring goose under consideration. | |
96 // @param alignment The accumulated alignment from all the neighbouring geese. | |
97 // @param alignCount The current number of geese that have contributed to the | |
98 // alignment component so far. | |
99 // @return The new count of geese that contribute to the alignment component. | |
100 // If the goose under consideration does not contribute, this value is the | |
101 // same as |alignCount|. | |
102 int32_t AccumulateAlignment(double distance, | |
103 const Goose& goose, | |
104 Vector2* alignment, /* inout */ | |
105 int32_t alignCount); | |
106 | |
107 // Add a neighbouring goose's contribution to the cohesion mean. Cohesion is | |
108 // based on the average location of the neighbours. The goose attempts to | |
109 // point to this average location. Only consider geese that are within | |
110 // |kNeighbourRadius|. Modifies the cohesion accumulator |cohesion| in-place. | |
111 // @param {!number} distance The distance from this goose to the neighbouring | |
112 // goose. | |
113 // @param {!Goose} goose The neighbouring goose under consideration. | |
114 // @param {!goog.math.Vec2} cohesion The accumulated cohesion from all the | |
115 // neighbouring geese. | |
116 // @param {!number} cohesionCount The current number of geese that have | |
117 // contributed to the cohesion component so far. | |
118 // @return {!number} The new count of geese that contribute to the cohesion | |
119 // component. If the goose under consideration does not contribute, this | |
120 // value is the same as |cohesionCount|. | |
121 int32_t AccumulateCohesion(double distance, | |
122 const Goose& goose, | |
123 Vector2* cohesion, /* inout */ | |
124 int32_t cohesionCount); | |
125 | |
126 Vector2 location_; | |
127 Vector2 velocity_; | |
128 }; | |
129 | |
130 } // namespace flocking_geese | |
131 | |
132 #endif // GOOSE_H_ | |
OLD | NEW |