光线和 STL 文件之间的光线追踪(或投射)
Ray-tracing (or casting) between rays and STL file
我有一个 3D 形状(骨头)作为 STL 格式的三角形网格,我正在使用 Python 语言。
然后我有一条射线及其来源和方向,我需要知道:
- 网格的哪个面与这条射线发生碰撞
- 交点坐标
- 我的光线与碰撞面的法向量之间的角度
我知道 'pycaster' ( https://pyscience.wordpress.com/2014/09/21/ray-casting-with-python-and-vtk-intersecting-linesrays-with-surface-meshes/ ) 但它只适用于 Python 2.x,我需要使用 Python 3.x。
我知道 'trimeshgeom' class ( http://cgkit.sourceforge.net/doc2/_sources/trimeshgeom.txt ) 来自 cgkit 但 PyCharm 无法将其安装为解释器(不明白为什么)。
有谁知道我如何做我想做的事?
谢谢,
干杯,
大卫
我们曾经有过类似的任务,最终实现了相当简单的
Möller-Trumbore-Algorithm.
代码可以从 printrun:
窃取
def ray_triangle_intersection(ray_near, ray_dir, v123):
"""
Möller–Trumbore intersection algorithm in pure python
Based on http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
"""
v1, v2, v3 = v123
eps = 0.000001
edge1 = v2 - v1
edge2 = v3 - v1
pvec = numpy.cross(ray_dir, edge2)
det = edge1.dot(pvec)
if abs(det) < eps:
return False, None
inv_det = 1. / det
tvec = ray_near - v1
u = tvec.dot(pvec) * inv_det
if u < 0. or u > 1.:
return False, None
qvec = numpy.cross(tvec, edge1)
v = ray_dir.dot(qvec) * inv_det
if v < 0. or u + v > 1.:
return False, None
t = edge2.dot(qvec) * inv_det
if t < eps:
return False, None
return True, t
对于角度计算,您可以使用例如angle_between_vectors()
来自 transformations.py
我有一个 3D 形状(骨头)作为 STL 格式的三角形网格,我正在使用 Python 语言。
然后我有一条射线及其来源和方向,我需要知道:
- 网格的哪个面与这条射线发生碰撞
- 交点坐标
- 我的光线与碰撞面的法向量之间的角度
我知道 'pycaster' ( https://pyscience.wordpress.com/2014/09/21/ray-casting-with-python-and-vtk-intersecting-linesrays-with-surface-meshes/ ) 但它只适用于 Python 2.x,我需要使用 Python 3.x。
我知道 'trimeshgeom' class ( http://cgkit.sourceforge.net/doc2/_sources/trimeshgeom.txt ) 来自 cgkit 但 PyCharm 无法将其安装为解释器(不明白为什么)。
有谁知道我如何做我想做的事?
谢谢, 干杯,
大卫
我们曾经有过类似的任务,最终实现了相当简单的 Möller-Trumbore-Algorithm.
代码可以从 printrun:
窃取def ray_triangle_intersection(ray_near, ray_dir, v123):
"""
Möller–Trumbore intersection algorithm in pure python
Based on http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
"""
v1, v2, v3 = v123
eps = 0.000001
edge1 = v2 - v1
edge2 = v3 - v1
pvec = numpy.cross(ray_dir, edge2)
det = edge1.dot(pvec)
if abs(det) < eps:
return False, None
inv_det = 1. / det
tvec = ray_near - v1
u = tvec.dot(pvec) * inv_det
if u < 0. or u > 1.:
return False, None
qvec = numpy.cross(tvec, edge1)
v = ray_dir.dot(qvec) * inv_det
if v < 0. or u + v > 1.:
return False, None
t = edge2.dot(qvec) * inv_det
if t < eps:
return False, None
return True, t
对于角度计算,您可以使用例如angle_between_vectors()
来自 transformations.py