pythongeometrylineintersectionpyvista

How can I intersect 2 lines using PyVista?


I would like to intersect 2 lines using PyVista, get the coordinates of this intersection and plot the result.

I tried the following code:

import pyvista as pv

line1 = pv.Line(pointa=(-1,0,0), pointb=(2,0,0))
line2 = pv.Line(pointa=(0,-1,0), pointb=(0,2,0))
intersection = line1.intersection(line2)

plotter = pv.Plotter()
plotter.add_mesh(line1)
plotter.add_mesh(line2)
plotter.add_mesh(intersection)

plotter.show()

But the problem is that I got a tuple of 3 empty PolyData elements:

(PolyData (0x2634b15bee0)
   N Cells:    0
   N Points:   0
   N Strips:   0
   X Bounds:   1.000e+299, -1.000e+299
   Y Bounds:   1.000e+299, -1.000e+299
   Z Bounds:   1.000e+299, -1.000e+299
   N Arrays:   0,
 PolyData (0x2634b15bac0)
   N Cells:    0
   N Points:   0
   N Strips:   0
   X Bounds:   1.000e+299, -1.000e+299
   Y Bounds:   1.000e+299, -1.000e+299
   Z Bounds:   1.000e+299, -1.000e+299
   N Arrays:   0,
 PolyData (0x2634b14a100)
   N Cells:    0
   N Points:   0
   N Strips:   0
   X Bounds:   1.000e+299, -1.000e+299
   Y Bounds:   1.000e+299, -1.000e+299
   Z Bounds:   1.000e+299, -1.000e+299
   N Arrays:   0)

And I can't plot a tuple in relation with the line: plotter.add_mesh(intersection). This made me think that there was no intersection but that's impossible.


Solution

  • There are two mistakes here.

    The first mistake is that intersect() returns 3 meshes, not 1:

        Returns
        -------
        pyvista.PolyData
            The intersection line.
        
        pyvista.PolyData
            The first mesh split along the intersection. Returns the
            original first mesh if ``split_first=False``.
        
        pyvista.PolyData
            The second mesh split along the intersection. Returns the
            original second mesh if ``split_second=False``.
    

    If you wanted only the intersection, you'd have to pick out the first (index 0) item in the returned tuple.

    The second mistake is that the intersect() filter, according to its docs,

    returns the surface intersection from two meshes (which often resolves as a line)

    Looking at the docs of the underlying vtkIntersectionPolyDataFilter, it also has very strong suggestions that this filter is meant to be used to intersect surfaces. It can't even intersect coplanar polygons. As you already know, it also has issues intersecting non-triangulated surfaces.

    I'm afraid this filter won't be able to intersect lines for you. In the general case the intersection of lines isn't even trivial to compute, because you would have to find a single point in real space with the added complication of floating-point uncertainty in numerical implementations. This is all just to say that I wouldn't take it for granted that VTK can do this task for you at all. You're probably better off solving the intersection's equation on paper (or solving the equivalent system of linear equations with code).