matplotlib / matplotlib/matplotlib
Behavior of `contains()` inconsistent with fill in overlapping paths
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 23.2k
- Forks
- 8.5k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 66
Description
> How do the two cases behave with `contains()` and mouse checking on the various artists?
I've investigated this, and amusingly enough, `contains()` is not fully consistent with either fill rule. The current logic (in [this function](https://github.com/matplotlib/matplotlib/blob/284213d3701a1112521fac0ef4891e3443c5880d/src/_path.h#L108)) is essentially (and possibly unintentionally) consistent with the even-odd rule on any individual subpath (and if the subpath does not self-intersect, the non-zero winding rule is the same). However, if there are multiple subpaths, a point is considered "inside" the combined path if it is inside at least one subpath, even if the combined effect of all subpaths mean that the point should actually be "outside". This means:
* If all subpaths do not self-intersect and do not intersect with each other, `contains()` is consistent with both the non-zero winding rule and the even-odd rule (that is, both rules have the same result)
* If there is a single subpath that self-intersects, `contains()` is consistent with the even-odd rule
* If there are multiple subpaths that do not self-intersect but do intersect with each other, *and* all subpaths are the same orientation, `contains()` is consistent with the non-zero winding rule
* If none of the above, `contains()` gives a "wrong" result: it is not consistent with either rule
My inclination is that fixing `contains()` should be deferred to a future PR.
_Originally posted by @ayshih in https://github.com/matplotlib/matplotlib/issues/32253#issuecomment-5591178865_
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked contains() function in src/_path.h, then compare its behavior with the fill-rule cases described for overlapping and self-intersecting subpaths. Before implementation, establish which fill rule contains() should follow and add coverage for those cases; the issue does not define an accepted behavior or completion test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- computer-graphics, data-visualization
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 32/100