| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -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]) | ||
|
|
||
| def get_normals(polygons): | ||
| """ | ||
| Takes a list of polygons and return an array of their normals | ||
| """ | ||
| v1 = np.empty((len(polygons), 3)) | ||
| v2 = np.empty((len(polygons), 3)) | ||
| for poly_i, ps in enumerate(polygons): | ||
| # pick three points around the polygon at which to find the | ||
| # normal doesn't vectorize because polygons is jagged | ||
| i1, i2, i3 = 0, len(ps)//3, 2*len(ps)//3 | ||
| v1[poly_i, :] = ps[i1, :] - ps[i2, :] | ||
| v2[poly_i, :] = ps[i2, :] - ps[i3, :] | ||
| return np.cross(v1, v2) | ||
|
|
||
| # 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, get_normals(polys), lightsource) | ||
| colset, self._generate_normals(polys), lightsource) | ||
| polyc.set_facecolors(colset) | ||
| polyc.set_edgecolors(colset) | ||
| elif cmap: | ||
| Expand All | @@ -1719,7 +1705,7 @@ def get_normals(polygons): | |
| else: | ||
| if shade: | ||
| colset = self._shade_colors( | ||
| color, get_normals(polys), lightsource) | ||
| color, self._generate_normals(polys), lightsource) | ||
| else: | ||
| colset = color | ||
| polyc.set_facecolors(colset) | ||
| Expand All | @@ -1731,20 +1717,47 @@ def get_normals(polygons): | |
|
|
||
| def _generate_normals(self, polygons): | ||
| """ | ||
| Generate normals for polygons by using the first three points. | ||
| This normal of course might not make sense for polygons with | ||
| more than three points not lying in a plane. | ||
| 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. | ||
| """ | ||
|
|
||
| normals = [] | ||
| for verts in polygons: | ||
| v1 = np.array(verts[1]) - np.array(verts[0]) | ||
| v2 = np.array(verts[2]) - np.array(verts[0]) | ||
| normals.append(np.cross(v1, v2)) | ||
| return normals | ||
| 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 | ||
| 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, :] | ||
|
Comment thread
Copy link
Copy Markdown
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIs 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.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
Author
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualitySign change is only in v1 and v2, it cancels out in the cross product, so it doesn't affect the return value. I picked the convention from get_normals because that was easiest. If you want me to flip both subtractions here, I can, but it won't make any difference.
Sorry, something went wrong.
timhoffm reacted with thumbs up emoji
All reactions
|
||
| 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, :] | ||
|
Comment thread
eric-wieser marked this conversation as resolved.
|
||
| return np.cross(v1, v2) | ||
|
|
||
| def _shade_colors(self, color, normals, lightsource=None): | ||
| """ | ||
| Expand Down Expand Up | @@ -1991,9 +2004,7 @@ def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, | |
| polyc.set_norm(norm) | ||
| else: | ||
| if shade: | ||
| v1 = verts[:, 0, :] - verts[:, 1, :] | ||
| v2 = verts[:, 1, :] - verts[:, 2, :] | ||
| normals = np.cross(v1, v2) | ||
| normals = self._generate_normals(verts) | ||
| colset = self._shade_colors(color, normals, lightsource) | ||
| else: | ||
| colset = color | ||
| Expand Down Expand Up | @@ -2040,9 +2051,9 @@ def _3d_extend_contour(self, cset, stride=5): | |
| botverts[0][i2], | ||
| botverts[0][i1]]) | ||
|
|
||
| v1 = np.array(topverts[0][i1]) - np.array(topverts[0][i2]) | ||
| v2 = np.array(topverts[0][i1]) - np.array(botverts[0][i1]) | ||
| normals.append(np.cross(v1, v2)) | ||
| # 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) | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWhy the i index ?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityBecause the value of M can change between each list item - polygons[0] has shape (M_0, 3), polygons[1] has shape (M_1, 3), and it is likely that M_1 != M_0
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.