Check if all points are on the same plane. Note that NaN values are ignored. Parameters ---------- xs, ys, zs : array-like The x, y, and z coordinates of the points. atol : float, default: 1e-8 The tolerance for the equality check.
(xs, ys, zs, atol=1e-8)
| 1635 | |
| 1636 | |
| 1637 | def _all_points_on_plane(xs, ys, zs, atol=1e-8): |
| 1638 | """ |
| 1639 | Check if all points are on the same plane. Note that NaN values are |
| 1640 | ignored. |
| 1641 | |
| 1642 | Parameters |
| 1643 | ---------- |
| 1644 | xs, ys, zs : array-like |
| 1645 | The x, y, and z coordinates of the points. |
| 1646 | atol : float, default: 1e-8 |
| 1647 | The tolerance for the equality check. |
| 1648 | """ |
| 1649 | xs, ys, zs = np.asarray(xs), np.asarray(ys), np.asarray(zs) |
| 1650 | points = np.column_stack([xs, ys, zs]) |
| 1651 | points = points[~np.isnan(points).any(axis=1)] |
| 1652 | # Check for the case where we have less than 3 unique points |
| 1653 | points = np.unique(points, axis=0) |
| 1654 | if len(points) <= 3: |
| 1655 | return True |
| 1656 | # Calculate the vectors from the first point to all other points |
| 1657 | vs = (points - points[0])[1:] |
| 1658 | vs = vs / np.linalg.norm(vs, axis=1)[:, np.newaxis] |
| 1659 | # Filter out parallel vectors |
| 1660 | vs = np.unique(vs, axis=0) |
| 1661 | if len(vs) <= 2: |
| 1662 | return True |
| 1663 | # Filter out parallel and antiparallel vectors to the first vector |
| 1664 | cross_norms = np.linalg.norm(np.cross(vs[0], vs[1:]), axis=1) |
| 1665 | zero_cross_norms = np.where(np.isclose(cross_norms, 0, atol=atol))[0] + 1 |
| 1666 | vs = np.delete(vs, zero_cross_norms, axis=0) |
| 1667 | if len(vs) <= 2: |
| 1668 | return True |
| 1669 | # Calculate the normal vector from the first three points |
| 1670 | n = np.cross(vs[0], vs[1]) |
| 1671 | n = n / np.linalg.norm(n) |
| 1672 | # If the dot product of the normal vector and all other vectors is zero, |
| 1673 | # all points are on the same plane |
| 1674 | dots = np.dot(n, vs.transpose()) |
| 1675 | return np.allclose(dots, 0, atol=atol) |
| 1676 | |
| 1677 | |
| 1678 | def _generate_normals(polygons): |
searching dependent graphs…