Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.1k
MAINT: Unify calculation of normal vectors from polygons#12136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1684,28 +1684,14 @@ def plot_surface(self, X, Y, Z, *args, norm=None, vmin=None, | ||
| if fcolors is not None: | ||
| colset.append(fcolors[rs][cs]) | ||
| # note that the striding causes some polygons to have more coordinates | ||
| # than others | ||
| polyc = art3d.Poly3DCollection(polys, *args, **kwargs) | ||
| if fcolors is not None: | ||
| if shade: | ||
| colset = self._shade_colors( | ||
| colset,self._generate_normals(polys), lightsource) | ||
| polyc.set_facecolors(colset) | ||
| polyc.set_edgecolors(colset) | ||
| elif cmap: | ||
| @@ -1719,7 +1705,7 @@ def get_normals(polygons): | ||
| else: | ||
| if shade: | ||
| colset = self._shade_colors( | ||
| color,self._generate_normals(polys), lightsource) | ||
| else: | ||
| colset = color | ||
| polyc.set_facecolors(colset) | ||
| @@ -1731,20 +1717,47 @@ def get_normals(polygons): | ||
| def _generate_normals(self, polygons): | ||
| """ | ||
| Takes a list of polygons and return an array of their normals. | ||
| 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 normal of course might not make sense for polygons with more than | ||
| three points not lying in a plane, but it's a plausible and fast | ||
| approximation. | ||
| Parameters | ||
| ---------- | ||
| polygons: list of (M_i, 3) array_like, or (..., M, 3) array_like | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Why the i index ? ContributorAuthor
| ||
| A sequence of polygons to compute normals for, which can have | ||
| varying numbers of vertices. If the polygons all have the same | ||
| number of vertices and array is passed, then the operation will | ||
| be vectorized. | ||
| Returns | ||
| ------- | ||
| normals: (..., 3) array_like | ||
| A normal vector estimated for the polygon. | ||
| """ | ||
| if isinstance(polygons, np.ndarray): | ||
| # optimization: polygons all have the same number of points, so can | ||
| # vectorize | ||
| n = polygons.shape[-2] | ||
| i1, i2, i3 = 0, n//3, 2*n//3 | ||
| v1 = polygons[..., i1, :] - polygons[..., i2, :] | ||
| v2 = polygons[..., i2, :] - polygons[..., i3, :] | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Is there the sign change here intended? This is the convention of get_normals. _generate_normals had it the other way round. I know that there have been some orientation issues. But I don‘t know the state. Just want to make sure the sign change is notbslipping in unintendedly. ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Sign change is only in I picked the convention from | ||
| else: | ||
| # The subtraction doesn't vectorize because polygons is jagged. | ||
| v1 = np.empty((len(polygons), 3)) | ||
| v2 = np.empty((len(polygons), 3)) | ||
| for poly_i, ps in enumerate(polygons): | ||
| n = len(ps) | ||
| i1, i2, i3 = 0, n//3, 2*n//3 | ||
| v1[poly_i, :] = ps[i1, :] - ps[i2, :] | ||
| v2[poly_i, :] = ps[i2, :] - ps[i3, :] | ||
eric-wieser marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| return np.cross(v1, v2) | ||
| def _shade_colors(self, color, normals, lightsource=None): | ||
| """ | ||
| @@ -1991,9 +2004,7 @@ def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, | ||
| polyc.set_norm(norm) | ||
| else: | ||
| if shade: | ||
| normals = self._generate_normals(verts) | ||
| colset = self._shade_colors(color, normals, lightsource) | ||
| else: | ||
| colset = color | ||
| @@ -2040,9 +2051,9 @@ def _3d_extend_contour(self, cset, stride=5): | ||
| botverts[0][i2], | ||
| botverts[0][i1]]) | ||
| # all polygons have 4 vertices, so vectorize | ||
| polyverts= np.array(polyverts) | ||
| normals = self._generate_normals(polyverts) | ||
| colors = self._shade_colors(color, normals) | ||
| colors2 = self._shade_colors(color, normals) | ||