Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: experimental/flocking_geese/nacl_app/goose.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 #include "nacl_app/goose.h"
6
7 namespace {
8 // The maximum speed of a goose. Measured in meters/second.
9 const double kMaxSpeed = 2.0;
10
11 // The maximum force that can be applied to turn a goose when computing the
12 // aligment. Measured in meters/second/second.
13 const double kMaxTurningForce = 0.05;
14
15 // The neighbour radius of a goose. Only geese within this radius will affect
16 // the flocking computations of this goose. Measured in pixels.
17 const double kNeighbourRadius = 64.0;
18
19 // The minimum distance that a goose can be from this goose. If another goose
20 // comes within this distance of this goose, the flocking algorithm tries to
21 // move the geese apart. Measured in pixels.
22 const double kPersonalSpace = 32.0;
23
24 // The distance at which attractors have effect on a goose's direction.
25 const double kAttractorRadius = 320.0;
26
27 // The goose will try to turn towards geese within this distance (computed
28 // during the cohesion phase). Measured in pixels.
29 const double kMaxTurningDistance = 100.0;
30
31 // The weights used when computing the weighted sum the three flocking
32 // components.
33 const double kSeparationWeight = 2.0;
34 const double kAlignmentWeight = 1.0;
35 const double kCohesionWeight = 1.0;
36
37 } // namespace
38
39 namespace flocking_geese {
40
41 Goose::Goose() : location_(0, 0) {
42 velocity_ = Vector2::RandomUnit();
43 }
44
45 Goose::Goose(const Vector2& location) : location_(location) {
46 velocity_ = Vector2::RandomUnit();
47 }
48
49 void Goose::SimulationTick(const std::vector<Goose>& geese,
50 const std::vector<Vector2>& attractors,
51 const pp::Rect& flockBox) {
52 Vector2 acceleration = Flock(geese, attractors);
53 velocity_.Add(acceleration);
54 // Limit the velocity to a maximum speed.
55 velocity_.Clamp(kMaxSpeed);
56 location_.Add(velocity_);
57 // Wrap the goose location to the flock box.
58 if (!flockBox.IsEmpty()) {
59 if (location_.x() < flockBox.x()) {
60 location_.set_x(flockBox.right() - 1);
61 }
62 if (location_.x() >= flockBox.right()) {
63 location_.set_x(flockBox.x());
64 }
65 if (location_.y() < flockBox.y()) {
66 location_.set_y(flockBox.bottom() - 1);
67 }
68 if (location_.y() >= flockBox.bottom()) {
69 location_.set_y(flockBox.y());
70 }
71 }
72 }
73
74 Vector2 Goose::Flock(const std::vector<Goose>& geese,
75 const std::vector<Vector2>& attractors) {
76 // Loop over all the neighbouring geese in the flock, accumulating
77 // the separation mean, the alignment mean and the cohesion mean.
78 int32_t separationCount = 0;
79 Vector2 separation;
80 int32_t alignCount = 0;
81 Vector2 alignment;
82 int32_t cohesionCount = 0;
83 Vector2 cohesion;
84
85 for (std::vector<Goose>::const_iterator goose_it = geese.begin();
86 goose_it < geese.end();
87 ++goose_it) {
88 const Goose& goose = *goose_it;
89 // Compute the distance from this goose to its neighbour.
90 Vector2 gooseDirection = Vector2::Difference(
91 location_, goose.location());
92 double distance = gooseDirection.Magnitude();
93 separationCount = AccumulateSeparation(
94 distance, gooseDirection, &separation, separationCount);
95 alignCount = AccumulateAlignment(
96 distance, goose, &alignment, alignCount);
97 cohesionCount = AccumulateCohesion(
98 distance, goose, &cohesion, cohesionCount);
99 }
100 // Compute the means and create a weighted sum. This becomes the goose's new
101 // acceleration.
102 if (separationCount > 0) {
103 separation.Scale(1.0 / static_cast<double>(separationCount));
104 }
105 if (alignCount > 0) {
106 alignment.Scale(1.0 / static_cast<double>(alignCount));
107 // Limit the effect that alignment has on the final acceleration. The
108 // alignment component can overpower the others if there is a big
109 // difference between this goose's velocity and its neighbours'.
110 alignment.Clamp(kMaxTurningForce);
111 }
112
113 // Compute the effect of the attractors and blend this in with the flock
114 // cohesion component. An attractor has to be within kAttractorRadius to
115 // effect the heading of a goose.
116 for (size_t i = 0; i < attractors.size(); ++i) {
117 Vector2 attractorDirection = Vector2::Difference(
118 attractors[i], location_);
119 double distance = attractorDirection.Magnitude();
120 if (distance < kAttractorRadius) {
121 attractorDirection.Scale(1000); // Each attractor acts like 1000 geese.
122 cohesion.Add(attractorDirection);
123 cohesionCount++;
124 }
125 }
126
127 // If there is a non-0 cohesion component, steer the goose so that it tries
128 // to follow the flock.
129 if (cohesionCount > 0) {
130 cohesion.Scale(1.0 / static_cast<double>(cohesionCount));
131 cohesion = TurnTowardsTarget(cohesion);
132 }
133 // Compute the weighted sum.
134 separation.Scale(kSeparationWeight);
135 alignment.Scale(kAlignmentWeight);
136 cohesion.Scale(kCohesionWeight);
137 Vector2 weightedSum = cohesion;
138 weightedSum.Add(alignment);
139 weightedSum.Add(separation);
140 return weightedSum;
141 }
142
143 Vector2 Goose::TurnTowardsTarget(const Vector2& target) {
144 Vector2 desiredDirection = Vector2::Difference(target, location_);
145 double distance = desiredDirection.Magnitude();
146 Vector2 newDirection;
147 if (distance > 0.0) {
148 desiredDirection.Normalize();
149 // If the target is within the turning affinity distance, then make the
150 // desired direction based on distance to the target. Otherwise, base
151 // the desired direction on MAX_SPEED.
152 if (distance < kMaxTurningDistance) {
153 // Some pretty arbitrary dampening.
154 desiredDirection.Scale(kMaxSpeed * distance / 100.0);
155 } else {
156 desiredDirection.Scale(kMaxSpeed);
157 }
158 newDirection = Vector2::Difference(desiredDirection, velocity_);
159 newDirection.Clamp(kMaxTurningForce);
160 }
161 return newDirection;
162 }
163
164 int32_t Goose::AccumulateSeparation(double distance,
165 const Vector2& gooseDirection,
166 Vector2* separation, /* inout */
167 int32_t separationCount) {
168 if (distance > 0.0 && distance < kPersonalSpace) {
169 Vector2 weightedDirection = gooseDirection;
170 weightedDirection.Normalize();
171 weightedDirection.Scale(1.0 / distance);
172 separation->Add(weightedDirection);
173 separationCount++;
174 }
175 return separationCount;
176 }
177
178 int32_t Goose::AccumulateAlignment(double distance,
179 const Goose& goose,
180 Vector2* alignment, /* inout */
181 int32_t alignCount) {
182 if (distance > 0.0 && distance < kNeighbourRadius) {
183 alignment->Add(goose.velocity());
184 alignCount++;
185 }
186 return alignCount;
187 }
188
189 int32_t Goose::AccumulateCohesion(double distance,
190 const Goose& goose,
191 Vector2* cohesion, /* inout */
192 int32_t cohesionCount) {
193 if (distance > 0.0 && distance < kNeighbourRadius) {
194 cohesion->Add(goose.location());
195 cohesionCount++;
196 }
197 return cohesionCount;
198 }
199
200 } // namespace flocking_geese
201
OLDNEW
« no previous file with comments | « experimental/flocking_geese/nacl_app/goose.h ('k') | experimental/flocking_geese/nacl_app/locking_image_data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698