danieljfarrell / pvtrace

Optical ray tracing for luminescent materials and spectral converter photovoltaic devices
Other
97 stars 94 forks source link

Scene.intersections misses hits and throws exception #35

Closed chrisspen closed 4 years ago

chrisspen commented 4 years ago

I'm trying to test the Scene.intersections functionality with:

from pvtrace import Box, Node, Sphere, Scene

world = Node(
    name="world",
    geometry=Sphere(
        radius=100.0
    ),
)

floor = Node(
    name="floor",
    geometry=Box((10, 10, 0.1)),
    parent=world
)

scene = Scene(world)

# Calculate ray looking down, definitely intersects.
ret = scene.intersections(ray_origin=(0,0,10), ray_direction=(0,0,0))
hit_nodes = set(r.hit for r in ret)
print('Intersection:', ret)
assert floor in hit_nodes

# Calculate ray looking up, never intersects.
ret = scene.intersections(ray_origin=(0,0,10), ray_direction=(0,0,1000))
hit_nodes = set(r.hit for r in ret)
print('Intersection:', ret)
assert floor not in hit_nodes

and it's throwing the error:

Traceback (most recent call last):
  File "localize.py", line 21, in <module>
    ret = scene.intersections(ray_origin=(0,0,10), ray_direction=(0,0,0))
  File ".env/lib/python3.7/site-packages/pvtrace/scene/scene.py", line 82, in intersections
    all_intersections = self.root.intersections(ray_origin, ray_direction)
  File ".env/lib/python3.7/site-packages/pvtrace/scene/node.py", line 133, in intersections
    child.intersections(ray_origin_in_child, ray_direction_in_child)
  File ".env/lib/python3.7/site-packages/pvtrace/scene/node.py", line 118, in intersections
    points = self.geometry.intersections(ray_origin, ray_direction)
  File ".env/lib/python3.7/site-packages/pvtrace/geometry/mesh.py", line 48, in intersections
    ray_directions=np.array([direction])
  File ".env/lib/python3.7/site-packages/trimesh/ray/ray_triangle.py", line 107, in intersects_location
    **kwargs)
  File ".env/lib/python3.7/site-packages/trimesh/ray/ray_triangle.py", line 66, in intersects_id
    triangles_normal=self.mesh.face_normals)
  File ".env/lib/python3.7/site-packages/trimesh/ray/ray_triangle.py", line 203, in ray_triangle_id
    tree=tree)
  File ".env/lib/python3.7/site-packages/trimesh/ray/ray_triangle.py", line 311, in ray_triangle_candidates
    ray_candidates[i] = np.array(list(tree.intersection(bounds)),
  File ".env/lib/python3.7/site-packages/rtree/index.py", line 677, in intersection
    p_mins, p_maxs = self.get_coordinate_pointers(coordinates)
  File ".env/lib/python3.7/site-packages/rtree/index.py", line 353, in get_coordinate_pointers
    "Coordinates must not have minimums more than maximums")
rtree.core.RTreeError: Coordinates must not have minimums more than maximums

If I change the ray_direction so that's it's looking at (0,0,-1) instead of the origin, then it works. However, I would think it should be able to look at the origin.

Another odd error is that if I use the ray_direction of (1,1,0), which should intersect with the floor, it doesn't register a hit with the floor node.

danieljfarrell commented 4 years ago

Hi!

ray_direction=(0,0,0)

This is not a valid direction vector. Try,

ray_direction=(0,0,-1)  # ray going straight down 

This is valid vector,

ray_direction=(0,0,1000)

but not a valid direction vector because the length is not equal to 1. Try,

ray_direction=(0,0,1)  # ray going straight up

This will not intersect with the object, just the scene boundary.

Same for,

ray_direction=(0,1,1)

You need to normalise all direction vectors before passing them to pvtrace.

chrisspen commented 4 years ago

Ah, I though ray_direction was the point being looked at, not a direction vector. That makes sense. Thanks for clarifying. Works well.