| 106 | return position, velocity, self._stop_condition(velocity, epsilon) |
| 107 | |
| 108 | def _node_attraction(self, position, e_center, v2e_dist, x0=0.1, k=1.0): |
| 109 | import numpy as np |
| 110 | |
| 111 | """ |
| 112 | Node attracted by edge center. |
| 113 | """ |
| 114 | x = deepcopy(v2e_dist) |
| 115 | x[v2e_dist > 0] -= x0 |
| 116 | f_scale = k * x # (n, m) |
| 117 | f_dir = ( |
| 118 | e_center[np.newaxis, :, :] - position[:, np.newaxis, :] |
| 119 | ) # (1, m, 2) - (n, 1, 2) -> (n, m, 2) |
| 120 | f_dir_len = np.linalg.norm(f_dir, axis=2) # (n, m) |
| 121 | # f_dir = f_dir / f_dir_len[:, :, np.newaxis] # (n, m, 2) |
| 122 | f_dir = safe_div(f_dir, f_dir_len[:, :, np.newaxis]) # (n, m, 2) |
| 123 | f = f_scale[:, :, np.newaxis] * f_dir # (n, m, 2) |
| 124 | f = f.sum(axis=1) # (n, 2) |
| 125 | return f |
| 126 | |
| 127 | def _node_repulsion(self, position, v2v_dist, k=1.0): |
| 128 | import numpy as np |