Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Issue detecting paths intersection with Path.intersects_path #6076

Closed as not planned
@afvincent

Description

@afvincent

Short Description

I think there may be a bug in the Path.intersects_path method, in path module:

Signature: Path.intersects_path(self, other, filled=True)
Docstring:
Returns *True* if this path intersects another given path.

*filled*, when True, treats the paths as if they were filled.
That is, if one path completely encloses the other,
:meth:`intersects_path` will return True.
File:      ~/anaconda/lib/python2.7/site-packages/matplotlib/path.py
Type:      instancemethod

Playing with it, I encountered some cases where this method answers that the two paths are not intersecting, while after plotting them, they do (see the example script and picture below). I still didn't have time to look into further (especially the C++ code that is wrapped by the method), but it seems to me that this behavior is not correct, is it?

Details

  • Matplotlib version, Python version and Platform (Windows, OSX, Linux ...)

Matplotlib 1.5.1, with Python 2.7.11 (and IPython 4.0.1), on Linux (CentOS 7 or Manjaro)

  • How did you install Matplotlib and Python (pip, anaconda, from source ...)

Anaconda 2.4.0 (64-bit)

  • If possible please supply a Short, Self Contained, Correct, Example
    that demonstrates the issue i.e a small piece of code which reproduces the issue
    and can be run with out any other (or as few as possible) external dependencies.
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.path import Path

cubic_bezier_codes = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]

def plot_ctrls(verts, ax, label='',
               ls='--', marker='o', ms=5, lw=1, alpha=0.6, color='Gray'):
    """Plot the control points of a Bezier curve (debugging purpose)
    """
    ax.plot(*zip(*verts), ls=ls, lw=lw, color=color, ms=ms, marker=marker,
            alpha=alpha, label=label)
    return ax

# For your viewing pleasure when plotting
detection_color = {True: "OliveDrab", False: "Crimson"}

if __name__ == "__main__":
    plt.ion()

    # A dummy path to play with
    verts_1 = [(0.5, 0.01), (0.21, 0.99), (0.99, 0.8), (0.99, 0.99)]
    path_1 = Path(verts_1, cubic_bezier_codes)

    # A path that does intersect with path_1 but for which the ad-hoc test
    # method fails
    verts_2a = [(0.5, 0.8), (0.5, 0.7), (0.6, 0.75), (0.56, 0.7)]
    path_2a = Path(verts_2a, cubic_bezier_codes)

    # Decreasing a bit the y-value of the last control point leads to a
    # correct detection of path intersecting.
    verts_2b = [(0.5, 0.8), (0.5, 0.7), (0.6, 0.75), (0.56, 0.6)]
    path_2b = Path(verts_2b, cubic_bezier_codes)

    # Plot everything to be sure
    fig, (axA, axB) = plt.subplots(ncols=2, sharex=True, sharey=True)
    title_prefix = "path_1.intersects_path(path_2):\n"
    for ax, p1, p2 in [(axA, path_1, path_2a), (axB, path_1, path_2b)]:
        # Detect if the two paths intersect
        detection = p1.intersects_path(p2)
        ax.set_title(title_prefix + "{}".format(detection))

        # Plot the two paths
        patch_1 = PathPatch(p1, lw=2, fc='none', ec='CornFlowerBlue')
        pc1 = ax.add_patch(patch_1)
        patch_2 = PathPatch(p2, lw=2, fc='none', ec=detection_color[detection])
        ax.add_patch(patch_2)

        # Plot the controls nodes for debugging
        ax = plot_ctrls(p1.vertices, ax, marker='s', color=patch_1.get_ec(),
                        label='verts_1')
        ax = plot_ctrls(p2.vertices, ax, color=patch_2.get_ec(),
                        label='verts_2')
        ax.legend(loc='lower right', handlelength=3.5)

    #fig.savefig("Issue_with_intersecting_path_detection.png", dpi=150)
  • If this is an image generation bug attach a screenshot demonstrating the issue.

The paths are plotted in solid lines, and the vertices (control points) of the paths are plotted with markers (with thin dashed lines between them, and of the same color as the path they correspond to).

  • Left panel: the red path (path_2) is indicated as non intersecting with the blue one (path_1) by path_1.intersects_path(path_2), while from the plot they seem to be intersecting…
  • Right panel: the green path (path_2) is indicated as intersecting with the blue one (path_1) by path_1.intersects_path(path_2), which seems correct from the plot…

The only difference between the two red and green paths is their last control point (on the right), which is a bit lower in the right panel case than in the left panel case.

issue_with_intersecting_path_detection

  • If this is a regression (Used to work in an earlier version of Matplotlib), please
    note where it used to work.

Never used Path.intersects_path method before, so I can't tell if it's a regression.

Metadata

Metadata

Assignees

Labels

status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.status: inactiveMarked by the “Stale” Github Actiontopic: path handling

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions