v / bench / vectors / vectors.v
164 lines · 131 sloc · 4.0 KB · f09826e928f9612bab9299faefff7cf34a503362
Raw
1module main
2
3import rand
4import math
5
6struct Vector {
7 x f64
8 y f64
9 z f64
10}
11
12const boids_count = 10000
13const max_coordinate = 10000.0
14const cohesion_distance = 10.0
15const separation_distance = 5.0
16
17@[direct_array_access]
18fn main() {
19 mut positions := [boids_count]Vector{}
20 mut velocities := [boids_count]Vector{}
21
22 for position_index in 0 .. positions.len {
23 positions[position_index] = Vector{
24 x: rand.f64() * max_coordinate
25 y: rand.f64() * max_coordinate
26 z: rand.f64() * max_coordinate
27 }
28 }
29
30 for boid_index in 0 .. positions.len {
31 position := positions[boid_index]
32 mut close_boids_ids := []int{}
33
34 for other_boid_index in 0 .. positions.len {
35 if boid_index == other_boid_index {
36 continue
37 }
38
39 other_position := positions[other_boid_index]
40
41 difference_x := position.x - other_position.x
42 difference_y := position.y - other_position.y
43 difference_z := position.z - other_position.z
44
45 distance := difference_x * difference_x + difference_y * difference_y +
46 difference_z * difference_z
47
48 if distance <= cohesion_distance * cohesion_distance {
49 close_boids_ids << other_boid_index
50 }
51 }
52
53 if close_boids_ids.len == 0 {
54 continue
55 }
56
57 mut cohesion := Vector{}
58 mut separation := Vector{}
59 mut separation_count := 0
60 mut alignment := Vector{}
61
62 for close_boid_id in close_boids_ids {
63 close_boid_position := positions[close_boid_id]
64
65 cohesion = Vector{
66 x: cohesion.x + close_boid_position.x
67 y: cohesion.y + close_boid_position.y
68 z: cohesion.z + close_boid_position.z
69 }
70
71 difference_from_closest := Vector{
72 x: position.x - close_boid_position.x
73 y: position.y - close_boid_position.y
74 z: position.z - close_boid_position.z
75 }
76
77 difference_magnitude := math.sqrt(
78 difference_from_closest.x * difference_from_closest.x +
79 difference_from_closest.y * difference_from_closest.y +
80 difference_from_closest.z * difference_from_closest.z)
81
82 if difference_magnitude <= separation_distance {
83 separation = Vector{
84 x: separation.x + difference_from_closest.x / difference_magnitude
85 y: separation.y + difference_from_closest.y / difference_magnitude
86 z: separation.z + difference_from_closest.z / difference_magnitude
87 }
88
89 separation_count += 1
90 }
91
92 close_boid_velocity := velocities[close_boid_id]
93
94 alignment = Vector{
95 x: alignment.x + close_boid_velocity.x
96 y: alignment.y + close_boid_velocity.y
97 z: alignment.z + close_boid_velocity.z
98 }
99 }
100
101 cohesion = Vector{
102 x: cohesion.x / close_boids_ids.len
103 y: cohesion.y / close_boids_ids.len
104 z: cohesion.z / close_boids_ids.len
105 }
106
107 cohesion_force := Vector{
108 x: cohesion.x - position.x
109 y: cohesion.y - position.y
110 z: cohesion.z - position.z
111 }
112
113 if separation_count > 0 {
114 separation = Vector{
115 x: separation.x / separation_count
116 y: separation.y / separation_count
117 z: separation.z / separation_count
118 }
119 }
120
121 alignment = Vector{
122 x: alignment.x / close_boids_ids.len
123 y: alignment.y / close_boids_ids.len
124 z: alignment.z / close_boids_ids.len
125 }
126
127 current_velocity := velocities[boid_index]
128
129 velocities[boid_index] = Vector{
130 x: current_velocity.x + cohesion_force.x + separation.x + alignment.x
131 y: current_velocity.y + cohesion_force.y + separation.y + alignment.y
132 z: current_velocity.z + cohesion_force.z + separation.z + alignment.z
133 }
134 }
135
136 mut position_sum := Vector{}
137 mut velocity_sum := Vector{}
138
139 for boid_index in 0 .. positions.len {
140 position := positions[boid_index]
141 velocity := velocities[boid_index]
142
143 positions[boid_index] = Vector{
144 x: position.x + velocity.x
145 y: position.y + velocity.y
146 z: position.z + velocity.z
147 }
148
149 position_sum = Vector{
150 x: position_sum.x + position.x
151 y: position_sum.y + position.y
152 z: position_sum.z + position.z
153 }
154
155 velocity_sum = Vector{
156 x: velocity_sum.x + velocity.x
157 y: velocity_sum.y + velocity.y
158 z: velocity_sum.z + velocity.z
159 }
160 }
161
162 println('${position_sum.x} - ${position_sum.y} - ${position_sum.z}')
163 println('${velocity_sum.x} - ${velocity_sum.y} - ${velocity_sum.z}')
164}
165