v / bench / vectors / vectors.cs
193 lines · 153 sloc · 5.99 KB · 88cac9bdf4497ead6f199967dedaa530924fedb6
Raw
1using System;
2
3internal readonly struct Vector
4{
5 public readonly double X;
6 public readonly double Y;
7 public readonly double Z;
8
9 public Vector(double x, double y, double z)
10 {
11 X = x;
12 Y = y;
13 Z = z;
14 }
15
16 public override string ToString()
17 {
18 return $"({X}, {Y}, {Z})";
19 }
20}
21
22
23class Program
24{
25 static void Main(string[] args)
26 {
27 const int boidsCount = 10000;
28
29 var positions = new Vector[boidsCount];
30 var velocities = new Vector[boidsCount];
31
32 const double maxCoordinate = 10000.0;
33
34 var random = new Random();
35
36 for (var positionIndex = 0; positionIndex < positions.Length; positionIndex++)
37 {
38 positions[positionIndex] = new Vector(
39 x: random.NextDouble() * maxCoordinate,
40 y: random.NextDouble() * maxCoordinate,
41 z: random.NextDouble() * maxCoordinate
42 );
43 }
44
45 const double cohesionDistance = 10.0;
46 const double separationDistance = 5.0;
47
48 var closeBoids = new List<int>();
49
50 for (var boidIndex = 0; boidIndex < positions.Length; boidIndex++)
51 {
52 var position = positions[boidIndex];
53 closeBoids.Clear();
54
55 for (var otherBoidIndex = 0; otherBoidIndex < positions.Length; otherBoidIndex++)
56 {
57 if (boidIndex == otherBoidIndex)
58 {
59 continue;
60 }
61
62 var otherPosition = positions[otherBoidIndex];
63
64 var differenceX = position.X - otherPosition.X;
65 var differenceY = position.Y - otherPosition.Y;
66 var differenceZ = position.Z - otherPosition.Z;
67
68 var distance = differenceX * differenceX +
69 differenceY * differenceY +
70 differenceZ * differenceZ;
71
72 if (distance <= cohesionDistance * cohesionDistance)
73 {
74 closeBoids.Add(otherBoidIndex);
75 }
76 }
77
78 if (closeBoids.Count == 0)
79 {
80 continue;
81 }
82
83 var cohesion = new Vector(0.0, 0.0, 0.0);
84 var separation = new Vector(0.0, 0.0, 0.0);
85 var separationCount = 0;
86 var alignment = new Vector(0.0, 0.0, 0.0);
87
88 foreach (var closeBoidIndex in closeBoids)
89 {
90 var closeBoidPosition = positions[closeBoidIndex];
91
92 cohesion = new Vector(
93 cohesion.X + closeBoidPosition.X,
94 cohesion.Y + closeBoidPosition.Y,
95 cohesion.Z + closeBoidPosition.Z
96 );
97
98 var differenceFromClosest = new Vector(
99 position.X - closeBoidPosition.X,
100 position.Y - closeBoidPosition.Y,
101 position.Z - closeBoidPosition.Z
102 );
103
104 var differenceMagnitude = Math.Sqrt(differenceFromClosest.X * differenceFromClosest.X + differenceFromClosest.Y * differenceFromClosest.Y + differenceFromClosest.Z * differenceFromClosest.Z);
105
106 if (differenceMagnitude <= separationDistance)
107 {
108 separation = new Vector(
109 separation.X + differenceFromClosest.X / differenceMagnitude,
110 separation.Y + differenceFromClosest.Y / differenceMagnitude,
111 separation.Z + differenceFromClosest.Z / differenceMagnitude
112 );
113
114 separationCount++;
115 }
116
117 var closeBoidVelocity = velocities[closeBoidIndex];
118
119 alignment = new Vector(
120 alignment.X + closeBoidVelocity.X,
121 alignment.Y + closeBoidVelocity.Y,
122 alignment.Z + closeBoidVelocity.Z
123 );
124 }
125
126 cohesion = new Vector(
127 cohesion.X / closeBoids.Count,
128 cohesion.Y / closeBoids.Count,
129 cohesion.Z / closeBoids.Count
130 );
131
132 var cohesionForce = new Vector(
133 cohesion.X - position.X,
134 cohesion.Y - position.Y,
135 cohesion.Z - position.Z
136 );
137
138 if (separationCount > 0)
139 {
140 separation = new Vector(
141 separation.X / separationCount,
142 separation.Y / separationCount,
143 separation.Z / separationCount
144 );
145 }
146
147 alignment = new Vector(
148 alignment.X / closeBoids.Count,
149 alignment.Y / closeBoids.Count,
150 alignment.Z / closeBoids.Count
151 );
152
153 var currentVelocity = velocities[boidIndex];
154
155 velocities[boidIndex] = new Vector(
156 currentVelocity.X + cohesionForce.X + separation.X + alignment.X,
157 currentVelocity.Y + cohesionForce.Y + separation.Y + alignment.Y,
158 currentVelocity.Z + cohesionForce.Z + separation.Z + alignment.Z
159 );
160 }
161
162 var positionSum = new Vector(0.0, 0.0, 0.0);
163 var velocitySum = new Vector(0.0, 0.0, 0.0);
164
165 for (var boidIndex = 0; boidIndex < positions.Length; boidIndex++)
166 {
167 var position = positions[boidIndex];
168 var velocity = velocities[boidIndex];
169
170 positions[boidIndex] = new Vector(
171 position.X + velocity.X,
172 position.Y + velocity.Y,
173 position.Z + velocity.Z
174 );
175
176 positionSum = new Vector(
177 positionSum.X + position.X,
178 positionSum.Y + position.Y,
179 positionSum.Z + position.Z
180 );
181
182 velocitySum = new Vector(
183 velocitySum.X + velocity.X,
184 velocitySum.Y + velocity.Y,
185 velocitySum.Z + velocity.Z
186 );
187 }
188
189 Console.WriteLine(positionSum.ToString());
190 Console.WriteLine(velocitySum.ToString());
191 }
192}
193
194