python - 在 open3d 中创建箭头
问题描述
我正在使用 Open3D 来可视化一些点云。我想添加在特定点开始和结束的箭头。箭头将可视化我正在处理的一些事情。但是,我还没有找到添加这些箭头的简单方法。
我注意到有一个使用箭头创建笛卡尔坐标系的功能。因此,可以在 3D 可视化中添加箭头。
import open3d as o3d
# Create cartesian coordinate
FOR = o3d.geometry.TriangleMesh.create_coordinate_frame(
size=10, origin=[0,0,0])
# Visualize FOR
o3d.visualization.draw_geometries([FOR])
解决方案
我对没有找到在 Open3D 中创建箭头的简单方法感到沮丧,经过一段时间的努力,我想出了一个解决方案。
import open3d as o3d
import numpy as np
def draw_geometries(pcds):
"""
Draw Geometries
Args:
- pcds (): [pcd1,pcd2,...]
"""
o3d.visualization.draw_geometries(pcds)
def get_o3d_FOR(origin=[0, 0, 0],size=10):
"""
Create a FOR that can be added to the open3d point cloud
"""
mesh_frame = o3d.geometry.TriangleMesh.create_coordinate_frame(
size=size)
mesh_frame.translate(origin)
return(mesh_frame)
def vector_magnitude(vec):
"""
Calculates a vector's magnitude.
Args:
- vec ():
"""
magnitude = np.sqrt(np.sum(vec**2))
return(magnitude)
def calculate_zy_rotation_for_arrow(vec):
"""
Calculates the rotations required to go from the vector vec to the
z axis vector of the original FOR. The first rotation that is
calculated is over the z axis. This will leave the vector vec on the
XZ plane. Then, the rotation over the y axis.
Returns the angles of rotation over axis z and y required to
get the vector vec into the same orientation as axis z
of the original FOR
Args:
- vec ():
"""
# Rotation over z axis of the FOR
gamma = np.arctan(vec[1]/vec[0])
Rz = np.array([[np.cos(gamma),-np.sin(gamma),0],
[np.sin(gamma),np.cos(gamma),0],
[0,0,1]])
# Rotate vec to calculate next rotation
vec = Rz.T@vec.reshape(-1,1)
vec = vec.reshape(-1)
# Rotation over y axis of the FOR
beta = np.arctan(vec[0]/vec[2])
Ry = np.array([[np.cos(beta),0,np.sin(beta)],
[0,1,0],
[-np.sin(beta),0,np.cos(beta)]])
return(Rz, Ry)
def create_arrow(scale=10):
"""
Create an arrow in for Open3D
"""
cone_height = scale*0.2
cylinder_height = scale*0.8
cone_radius = scale/10
cylinder_radius = scale/20
mesh_frame = o3d.geometry.TriangleMesh.create_arrow(cone_radius=1,
cone_height=cone_height,
cylinder_radius=0.5,
cylinder_height=cylinder_height)
return(mesh_frame)
def get_arrow(origin=[0, 0, 0], end=None, vec=None):
"""
Creates an arrow from an origin point to an end point,
or create an arrow from a vector vec starting from origin.
Args:
- end (): End point. [x,y,z]
- vec (): Vector. [i,j,k]
"""
scale = 10
Ry = Rz = np.eye(3)
T = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
T[:3, -1] = origin
if end is not None:
vec = np.array(end) - np.array(origin)
elif vec is not None:
vec = np.array(vec)
if end is not None or vec is not None:
scale = vector_magnitude(vec)
Rz, Ry = calculate_zy_rotation_for_arrow(vec)
mesh = create_arrow(scale)
# Create the arrow
mesh.rotate(Ry, center=np.array([0, 0, 0]))
mesh.rotate(Rz, center=np.array([0, 0, 0]))
mesh.translate(origin)
return(mesh)
# Create a Cartesian Frame of Reference
FOR = get_o3d_FOR()
# Create an arrow from point (5,5,5) to point (10,10,10)
# arrow = get_arrow([5,5,5],[10,10,10])
# Create an arrow representing vector vec, starting at (5,5,5)
# arrow = get_arrow([5,5,5],vec=[5,5,5])
# Create an arrow in the same place as the z axis
arrow = get_arrow()
# Draw everything
draw_geometries([FOR,arrow])
推荐阅读
- git - 删除和创建新的存储库后如何将更改推送到存储库
- c - 是否可以仅通过使用 stdio.h 和 conio.h 标头来比较 c 中的字符串?
- excel - DAX 计算没有应用值过滤器的每个子组的值
- c# - 驱动程序初始化时出错:“无法启动浏览器 <...>\firefox.exe:其他操作系统错误 (SessionNotCreated)”
- javascript - 如何使用 Chrome DevTools 协议的 printToPDF 在页眉或页脚模板中修改第一个 pageNumber 或执行 JS
- spring-boot - ActiveDirectoryLdapAuthenticationProvider | 如何提供主要信用
- django - Django 将编译后的静态文件移动到 STATIC_ROOT
- pentaho - 向 Pentaho 输入数据的问题
- javascript - Vue V-Model Initiation Loss Selects 选择
- python - 如何编写一个字符串解释器,它将在 python 中执行一系列海龟移动命令?