Eliminate excessively flat border triangles from the triangulation. Returns a mask *new_mask* which allows to clean the encapsulated triangulation from its border-located flat triangles (according to their :meth:`circle_ratios`). This mask is meant to be sub
(self, min_circle_ratio=0.01, rescale=True)
| 115 | return np.ma.array(circle_ratio, mask=mask) |
| 116 | |
| 117 | def get_flat_tri_mask(self, min_circle_ratio=0.01, rescale=True): |
| 118 | """ |
| 119 | Eliminate excessively flat border triangles from the triangulation. |
| 120 | |
| 121 | Returns a mask *new_mask* which allows to clean the encapsulated |
| 122 | triangulation from its border-located flat triangles |
| 123 | (according to their :meth:`circle_ratios`). |
| 124 | This mask is meant to be subsequently applied to the triangulation |
| 125 | using `.Triangulation.set_mask`. |
| 126 | *new_mask* is an extension of the initial triangulation mask |
| 127 | in the sense that an initially masked triangle will remain masked. |
| 128 | |
| 129 | The *new_mask* array is computed recursively; at each step flat |
| 130 | triangles are removed only if they share a side with the current mesh |
| 131 | border. Thus, no new holes in the triangulated domain will be created. |
| 132 | |
| 133 | Parameters |
| 134 | ---------- |
| 135 | min_circle_ratio : float, default: 0.01 |
| 136 | Border triangles with incircle/circumcircle radii ratio r/R will |
| 137 | be removed if r/R < *min_circle_ratio*. |
| 138 | rescale : bool, default: True |
| 139 | If True, first, internally rescale (based on `scale_factors`) so |
| 140 | that the (unmasked) triangles fit exactly inside a unit square |
| 141 | mesh. This rescaling accounts for the difference of scale which |
| 142 | might exist between the 2 axis. |
| 143 | |
| 144 | Returns |
| 145 | ------- |
| 146 | array of bool |
| 147 | Mask to apply to encapsulated triangulation. |
| 148 | All the initially masked triangles remain masked in the |
| 149 | *new_mask*. |
| 150 | |
| 151 | Notes |
| 152 | ----- |
| 153 | The rationale behind this function is that a Delaunay |
| 154 | triangulation - of an unstructured set of points - sometimes contains |
| 155 | almost flat triangles at its border, leading to artifacts in plots |
| 156 | (especially for high-resolution contouring). |
| 157 | Masked with computed *new_mask*, the encapsulated |
| 158 | triangulation would contain no more unmasked border triangles |
| 159 | with a circle ratio below *min_circle_ratio*, thus improving the |
| 160 | mesh quality for subsequent plots or interpolation. |
| 161 | """ |
| 162 | # Recursively computes the mask_current_borders, true if a triangle is |
| 163 | # at the border of the mesh OR touching the border through a chain of |
| 164 | # invalid aspect ratio masked_triangles. |
| 165 | ntri = self._triangulation.triangles.shape[0] |
| 166 | mask_bad_ratio = self.circle_ratios(rescale) < min_circle_ratio |
| 167 | |
| 168 | current_mask = self._triangulation.mask |
| 169 | if current_mask is None: |
| 170 | current_mask = np.zeros(ntri, dtype=bool) |
| 171 | valid_neighbors = np.copy(self._triangulation.neighbors) |
| 172 | renum_neighbors = np.arange(ntri, dtype=np.int32) |
| 173 | nadd = -1 |
| 174 | while nadd != 0: |