Move bubbles to the center of mass. Parameters ---------- n_iterations : int, default: 50 Number of moves to perform.
(self, n_iterations=50)
| 79 | return np.argmin(distance, keepdims=True) |
| 80 | |
| 81 | def collapse(self, n_iterations=50): |
| 82 | """ |
| 83 | Move bubbles to the center of mass. |
| 84 | |
| 85 | Parameters |
| 86 | ---------- |
| 87 | n_iterations : int, default: 50 |
| 88 | Number of moves to perform. |
| 89 | """ |
| 90 | for _i in range(n_iterations): |
| 91 | moves = 0 |
| 92 | for i in range(len(self.bubbles)): |
| 93 | rest_bub = np.delete(self.bubbles, i, 0) |
| 94 | # try to move directly towards the center of mass |
| 95 | # direction vector from bubble to the center of mass |
| 96 | dir_vec = self.com - self.bubbles[i, :2] |
| 97 | |
| 98 | # shorten direction vector to have length of 1 |
| 99 | dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec)) |
| 100 | |
| 101 | # calculate new bubble position |
| 102 | new_point = self.bubbles[i, :2] + dir_vec * self.step_dist |
| 103 | new_bubble = np.append(new_point, self.bubbles[i, 2:4]) |
| 104 | |
| 105 | # check whether new bubble collides with other bubbles |
| 106 | if not self.check_collisions(new_bubble, rest_bub): |
| 107 | self.bubbles[i, :] = new_bubble |
| 108 | self.com = self.center_of_mass() |
| 109 | moves += 1 |
| 110 | else: |
| 111 | # try to move around a bubble that you collide with |
| 112 | # find colliding bubble |
| 113 | for colliding in self.collides_with(new_bubble, rest_bub): |
| 114 | # calculate direction vector |
| 115 | dir_vec = rest_bub[colliding, :2] - self.bubbles[i, :2] |
| 116 | dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec)) |
| 117 | # calculate orthogonal vector |
| 118 | orth = np.array([dir_vec[1], -dir_vec[0]]) |
| 119 | # test which direction to go |
| 120 | new_point1 = (self.bubbles[i, :2] + orth * |
| 121 | self.step_dist) |
| 122 | new_point2 = (self.bubbles[i, :2] - orth * |
| 123 | self.step_dist) |
| 124 | dist1 = self.center_distance( |
| 125 | self.com, np.array([new_point1])) |
| 126 | dist2 = self.center_distance( |
| 127 | self.com, np.array([new_point2])) |
| 128 | new_point = new_point1 if dist1 < dist2 else new_point2 |
| 129 | new_bubble = np.append(new_point, self.bubbles[i, 2:4]) |
| 130 | if not self.check_collisions(new_bubble, rest_bub): |
| 131 | self.bubbles[i, :] = new_bubble |
| 132 | self.com = self.center_of_mass() |
| 133 | |
| 134 | if moves / len(self.bubbles) < 0.1: |
| 135 | self.step_dist = self.step_dist / 2 |
| 136 | |
| 137 | def plot(self, ax, labels, colors): |
| 138 | """ |
no test coverage detected