My math sucks - I need some help with ray_cast!

I’m trying to teach myself the Blender API and thought it would be fun to try out the ray_cast method.

What I’m trying to do here, is for each polygon of the objects, cast a ray in the direction of the polygon normal to the other object and see if it ‘hits’ it.

Unfortunately my math sucks and I’m a noob to the API, so I’m not sure my script is working as expected! :smiley:

I was expecting to see in the system console, some ‘False’ results, but all I see is True. I would have thought limiting the distance to 1 would have prevented any true results given the locations, so I think somethings gone badly wrong!

Any help is greatly appreciated…

Thanks

trigHelp.blend (670.5 KB)

import bpy
import numpy as np

def getDirection(loc1, loc2):

dx = loc1[0] - loc2[0]
dy = loc1[1] - loc2[1]
dz = loc1[2] - loc2[2]

distance = np.sqrt([dx * dx, dy * dy, dz * dz])

return [np.cos(dx), np.cos(dy),np.cos(dz)]

selection_names = bpy.context.selected_objects

for i in selection_names:
for poly in i.data.polygons:
for obj in selection_names:
if(i.name != obj.name):
direction = getDirection(poly.normal, obj.location)
origin = np.add(i.location,poly.normal)
print(“poly Object=”, i.name, “poly index=”, poly.index, “location object=”, obj.name, “calculated orgin =”, origin, “location=”, obj.location, “calculated direction=”, direction)

            test = bpy.context.scene.ray_cast(
                    view_layer = bpy.context.view_layer,
                    origin = origin,
                    direction = direction,
                    distance=1)
                    
            print(test)

on my phone so i can’t do a super detailed reply, but you realize you can just do direct vector math in python yeah? so to get the distance and direction, you can just do:

direction = vec1 - vec2
distance = direction.length

Thanks! Certainly helps to know what the calculation should be to get the result I’m looking for!

I’ll give that a go and check the results. :+1:t3:

Gave it a quick try, but not really seeing the expected results yet. Perhaps I’m approaching the problem incorrectly?

My ultimate goal is to be able to test whether an object is next to or within the proximity of another one. So I thought maybe shooting a ray from the polys to try and detect it would have been a way. Maybe there is some other built in methods I’m clueless about? :slight_smile:

updated script: trigHelp.blend (670.8 KB)

Scene raycast does operate in “world” coordinate system, but polygon data are in “local” object’s coordinate system.

1 Convert your poly.normal vector into world vector by adding object’s rotation
t, rot, s = obj.matrix_world.decompose()
direction = rot @ poly.normal

2 Retrieve “world” polygon center location.
origin = obj.matrix_world @ poly.center

Then perform your scene raycast, result is also in world coordinate system.

If you need to convert back into object’s coordinate system use
local_pos = obj.matrix_world.inverted() @ world_pos

That could definitely explain some of the strange results. I’ll give that a go and see what happens. Thanks!

1 Convert your poly.normal vector into world vector by adding object’s rotation
t, rot, s = obj.matrix_world.decompose()
direction = rot @ poly.normal

Struggling a bit with this calculation. The rot output from obj.matrix_world.decompose() is quaternion, but the poly normal is a vector. So far not found a method that will allow me to add them together as they are. Presuming I need to convert the quaternion to an euler or do you know of an existing method that could work with these types? Thanks

EDIT: Just found out the @ symbol is for this kind of multiplying - Doh!!

The results indicate the coordinates are now more in line with world space, which is a good start. But something doesn’t see quite right with the distance part. Even with a minuscule value, I still see a true result. If I use a 0 value then I get false as expected - seems like an all or nothing situation, where I really need to be able to limit how far the ray can travel.

ray_cast_method_test.blend (681.5 KB)

Maybe a precision issue and ray hit polygon itself.
Try to add some distance so origin is not on polygon
origin = origin + direction * 0.001

Bingo! That was the issue - now its working as expected!

Thanks for your help on this - will make a big difference in the speed of identifying the objects compared to my current workaround, which is using a weight proximity modifier applying that and testing the vertex weight values!