Return a measure of the triangulation triangles flatness. The ratio of the incircle radius over the circumcircle radius is a widely used indicator of a triangle flatness. It is always ``<= 0.5`` and ``== 0.5`` only for equilateral triangles. Circle ratios be
(self, rescale=True)
| 48 | 1 / np.ptp(self._triangulation.y[node_used])) |
| 49 | |
| 50 | def circle_ratios(self, rescale=True): |
| 51 | """ |
| 52 | Return a measure of the triangulation triangles flatness. |
| 53 | |
| 54 | The ratio of the incircle radius over the circumcircle radius is a |
| 55 | widely used indicator of a triangle flatness. |
| 56 | It is always ``<= 0.5`` and ``== 0.5`` only for equilateral |
| 57 | triangles. Circle ratios below 0.01 denote very flat triangles. |
| 58 | |
| 59 | To avoid unduly low values due to a difference of scale between the 2 |
| 60 | axis, the triangular mesh can first be rescaled to fit inside a unit |
| 61 | square with `scale_factors` (Only if *rescale* is True, which is |
| 62 | its default value). |
| 63 | |
| 64 | Parameters |
| 65 | ---------- |
| 66 | rescale : bool, default: True |
| 67 | If True, internally rescale (based on `scale_factors`), so that the |
| 68 | (unmasked) triangles fit exactly inside a unit square mesh. |
| 69 | |
| 70 | Returns |
| 71 | ------- |
| 72 | masked array |
| 73 | Ratio of the incircle radius over the circumcircle radius, for |
| 74 | each 'rescaled' triangle of the encapsulated triangulation. |
| 75 | Values corresponding to masked triangles are masked out. |
| 76 | |
| 77 | """ |
| 78 | # Coords rescaling |
| 79 | if rescale: |
| 80 | (kx, ky) = self.scale_factors |
| 81 | else: |
| 82 | (kx, ky) = (1.0, 1.0) |
| 83 | pts = np.vstack([self._triangulation.x*kx, |
| 84 | self._triangulation.y*ky]).T |
| 85 | tri_pts = pts[self._triangulation.triangles] |
| 86 | # Computes the 3 side lengths |
| 87 | a = tri_pts[:, 1, :] - tri_pts[:, 0, :] |
| 88 | b = tri_pts[:, 2, :] - tri_pts[:, 1, :] |
| 89 | c = tri_pts[:, 0, :] - tri_pts[:, 2, :] |
| 90 | a = np.hypot(a[:, 0], a[:, 1]) |
| 91 | b = np.hypot(b[:, 0], b[:, 1]) |
| 92 | c = np.hypot(c[:, 0], c[:, 1]) |
| 93 | # circumcircle and incircle radii |
| 94 | s = (a+b+c)*0.5 |
| 95 | prod = s*(a+b-s)*(a+c-s)*(b+c-s) |
| 96 | # We have to deal with flat triangles with infinite circum_radius |
| 97 | bool_flat = (prod == 0.) |
| 98 | if np.any(bool_flat): |
| 99 | # Pathologic flow |
| 100 | ntri = tri_pts.shape[0] |
| 101 | circum_radius = np.empty(ntri, dtype=np.float64) |
| 102 | circum_radius[bool_flat] = np.inf |
| 103 | abc = a*b*c |
| 104 | circum_radius[~bool_flat] = abc[~bool_flat] / ( |
| 105 | 4.0*np.sqrt(prod[~bool_flat])) |
| 106 | else: |
| 107 | # Normal optimized flow |