Compute the normals of a list of polygons, one normal per polygon. Normals point towards the viewer for a face with its vertices in counterclockwise order, following the right hand rule. Uses three points equally spaced around the polygon. This method assumes that the points a
(polygons)
| 1676 | |
| 1677 | |
| 1678 | def _generate_normals(polygons): |
| 1679 | """ |
| 1680 | Compute the normals of a list of polygons, one normal per polygon. |
| 1681 | |
| 1682 | Normals point towards the viewer for a face with its vertices in |
| 1683 | counterclockwise order, following the right hand rule. |
| 1684 | |
| 1685 | Uses three points equally spaced around the polygon. This method assumes |
| 1686 | that the points are in a plane. Otherwise, more than one shade is required, |
| 1687 | which is not supported. |
| 1688 | |
| 1689 | Parameters |
| 1690 | ---------- |
| 1691 | polygons : list of (M_i, 3) array-like, or (..., M, 3) array-like |
| 1692 | A sequence of polygons to compute normals for, which can have |
| 1693 | varying numbers of vertices. If the polygons all have the same |
| 1694 | number of vertices and array is passed, then the operation will |
| 1695 | be vectorized. |
| 1696 | |
| 1697 | Returns |
| 1698 | ------- |
| 1699 | normals : (..., 3) array |
| 1700 | A normal vector estimated for the polygon. |
| 1701 | """ |
| 1702 | if isinstance(polygons, np.ndarray): |
| 1703 | # optimization: polygons all have the same number of points, so can |
| 1704 | # vectorize |
| 1705 | n = polygons.shape[-2] |
| 1706 | i1, i2, i3 = 0, n//3, 2*n//3 |
| 1707 | v1 = polygons[..., i1, :] - polygons[..., i2, :] |
| 1708 | v2 = polygons[..., i2, :] - polygons[..., i3, :] |
| 1709 | else: |
| 1710 | # The subtraction doesn't vectorize because polygons is jagged. |
| 1711 | v1 = np.empty((len(polygons), 3)) |
| 1712 | v2 = np.empty((len(polygons), 3)) |
| 1713 | for poly_i, ps in enumerate(polygons): |
| 1714 | n = len(ps) |
| 1715 | ps = np.asarray(ps) |
| 1716 | i1, i2, i3 = 0, n//3, 2*n//3 |
| 1717 | v1[poly_i, :] = ps[i1, :] - ps[i2, :] |
| 1718 | v2[poly_i, :] = ps[i2, :] - ps[i3, :] |
| 1719 | return np.cross(v1, v2) |
| 1720 | |
| 1721 | |
| 1722 | def _shade_colors(color, normals, lightsource=None): |
no outgoing calls
no test coverage detected
searching dependent graphs…