| 125 | return f |
| 126 | |
| 127 | def _node_repulsion(self, position, v2v_dist, k=1.0): |
| 128 | import numpy as np |
| 129 | |
| 130 | """ |
| 131 | Node repulsed by other nodes. |
| 132 | """ |
| 133 | dist = v2v_dist.copy() |
| 134 | r, c = np.diag_indices_from(dist) |
| 135 | dist[r, c] = np.inf |
| 136 | |
| 137 | f_scale = k / (dist**2) # (n, n) with diag 0 |
| 138 | f_dir = ( |
| 139 | position[:, np.newaxis, :] - position[np.newaxis, :, :] |
| 140 | ) # (n, 1, 2) - (1, n, 2) -> (n, n, 2) |
| 141 | f_dir_len = np.linalg.norm(f_dir, axis=2) # (n, n) |
| 142 | f_dir_len[r, c] = np.inf |
| 143 | # f_dir = f_dir / f_dir_len[:, :, np.newaxis] # (n, n, 2) |
| 144 | f_dir = safe_div(f_dir, f_dir_len[:, :, np.newaxis]) # (n, n, 2) |
| 145 | f = f_scale[:, :, np.newaxis] * f_dir # (n, n, 2) |
| 146 | f[r, c] = 0 |
| 147 | f = f.sum(axis=1) # (n, 2) |
| 148 | return f |
| 149 | |
| 150 | def _edge_repulsion(self, e_center, H, e2e_dist, k=1.0): |
| 151 | import numpy as np |