Skip to content

[Bug]: A self-overlapping 3D polygon with a flipped surface normal face cancels out a lower face #28394

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
scottshambaugh opened this issue Jun 14, 2024 · 3 comments

Comments

@scottshambaugh
Copy link
Contributor

scottshambaugh commented Jun 14, 2024

Bug summary

A little tricky to explain, but see the outcomes below. Found while making tests for #28225

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

theta = np.linspace(0, 2*np.pi, 50)

x1 = x2 = x3 = np.cos(theta)
y1 = y2 = y3 = np.sin(theta)
z1 = np.ones_like(theta) * 0
z2 = np.ones_like(theta) * 1
z3 = np.ones_like(theta) * 2

# flip direction of this face
x3 = x3[::-1]
y3 = y3[::-1]

verts = list(zip(x1, y1, z1)) + list(zip(x2, y2, z2)) + list(zip(x3, y3, z3))
verts = np.array([verts])
poly = Poly3DCollection(verts, alpha=.7, edgecolor='k')

fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.add_collection3d(poly)
ax.auto_scale_xyz(verts[:, :, 0], verts[:, :, 1], verts[:, :, 2])
ax.set_aspect('equalxy')
plt.show()

Actual outcome

From this view, everything looks as expected
image

From this view, the overlapping area of the top and middle faces cancel out and show full transparency (bug).
image

From this view, the above is still happening, but the bottom face still shows properly even though it's in the intersection area.
image

The semi-transparent areas should really stack to a more opaque coloring as well, but that's a separate issue.

Expected outcome

If you don't reverse x3 and y3, the result looks as expected:
image

Additional information

No response

Operating system

No response

Matplotlib Version

latest main

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

git checkout

@timhoffm
Copy link
Member

Your 3D polygon is projected to 2D, resulting in a self-intersecting 2D polygon.

To be checked, but I assume this is just the way self-intersecting 2D polygons are filled and we cannot do anything about that.

@anntzer
Copy link
Contributor

anntzer commented Jun 15, 2024

I agree with @timhoffm's interpretation. In particular, if everything gets merged into a single polygon, I don't think we can distinguish (when one of the circles is within the other -- assume that their radii are different) between the case here and an annulus with an empty center.

@scottshambaugh
Copy link
Contributor Author

This all makes sense, and doesn't seem like there's an easy way to address this in the current system. Closing as won't fix.

@scottshambaugh scottshambaugh closed this as not planned Won't fix, can't repro, duplicate, stale Jun 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants