1

I try to do detect the intersections of a ray with a polygon using pyvista. In this case the polygon is a cube. The cube is defined by points in 2d and then extruded. Why does this simple example where a ray is intersecting with the cube detect only one intersection?

import numpy as np
import pyvista as pv

points = [(0, 0), (0, 10), (10, 10), (10, 0)]

def points_2d_to_poly(points, z):
        """Convert a sequence of 2d coordinates to polydata with a polygon."""
        faces = [len(points), *range(len(points))]
        poly = pv.PolyData([p + (z,) for p in points], faces=faces)
        return poly

polygon = points_2d_to_poly(points, 0.0)
polygon_extruded = polygon.extrude((0, 0, 6.0), capping=True)
poly_surface = polygon_extruded.extract_surface()
poly_mesh = poly_surface.triangulate()

# Define line segment
start = [5, 2, -10]
stop = [5, 2, 10]

# Perform ray trace
points, ind = poly_mesh.ray_trace(start, stop, first_point=False)

# Create geometry to represent ray trace
ray = pv.Line(start, stop)
intersection = pv.PolyData(points)

# Render the result
p = pv.Plotter()
p.add_mesh(poly_mesh, show_edges=True, opacity=0.5, color="w", lighting=False, label="Test Mesh")
p.add_mesh(ray, color="blue", line_width=5, label="Ray Segment")
p.add_mesh(intersection, color="maroon", point_size=25, label="Intersection Points")
p.add_legend()
p.show()
Bulbasaur
  • 135
  • 5
  • 1
    What result do you get? I see `points = np.array([[5., 2., 6.]], dtype=float32)` which is indeed on the intersection of the raw with the cube, considering that the cube's bounds are `[0, 10, 0, 10, 6, 12]`. So based on this I'd consider this a success. Do you get different results? – Andras Deak -- Слава Україні Aug 31 '23 at 18:36
  • 1
    Hello. Thank you for your time. I made a mistake in the code posted originally for the question. I updated it - please run it again. Note that the geometry of the cube has changed and the ray intersects it twice. The problem is the ray_trace function detects only one intersection not two as I would expect. I get only `points = array([[5., 2., 0.]], dtype=float32)` when i would expect `[5., 2., 6.]` to be included aswell. – Bulbasaur Sep 01 '23 at 06:46
  • I haven't really used raytracing before, but I can't find any issue. Your updated example looks like it should return both points indeed. Under the hood `ray_trace()` uses `vtkOBBTree.IntersectWithLine()`, [one version of which says "_Return the first intersection of the specified line segment with the OBB tree_"](https://vtk.org/doc/nightly/html/classvtkOBBTree.html#a268ecf8a6ed5d343d5c98c386918c98b). This would sound like it's not _supposed_ to return multiple intersections, yet [in this official example](https://examples.vtk.org/site/Cxx/DataStructures/OBBTreeExtractCells/) it works fine. – Andras Deak -- Слава Україні Sep 01 '23 at 21:56
  • I also tried messing with the `SetTolerance()` method of the OBB Tree before we use it (for which I had to edit my local copy of PyVista), but changing the tolerance in the range of `[1e-15, 1]` didn't seem to change anything. It might be worth asking this [on the PyVista issue tracker](https://github.com/pyvista/pyvista/issues). – Andras Deak -- Слава Україні Sep 01 '23 at 21:59

0 Answers0