写在前面
1、内容:
如何生成空间任意圆柱体点云及其轴线,任意直线的生成也就是本文轴线的生成方式。
2、环境:
open3d
2、转载请注明出处:
https://blog.csdn.net/qq_41102371/article/details/121482141
几何原理
圆柱的方程,用于拟合已有圆柱:
圆柱上的点到轴线的距离等于圆柱的底面半径
(
x
−
x
0
)
2
+
(
y
−
y
0
)
2
+
(
z
−
z
0
)
2
−
[
a
(
x
−
x
0
)
+
b
(
y
−
y
0
)
+
c
(
z
−
z
0
)
]
2
=
r
0
2
(x-x_0)^2+(y-y_0)^2+(z-z_0)^2-[a(x-x_0)+b(y-y_0)+c(z-z_0)]^2={r_0}^2
(x−x0)2+(y−y0)2+(z−z0)2−[a(x−x0)+b(y−y0)+c(z−z0)]2=r02
参考:
https://blog.csdn.net/qq_30815237/article/details/90405087
圆柱空间参数方程,用于生成圆柱:
x
=
x
0
+
r
B
A
2
+
B
2
cos
u
+
r
A
C
A
2
+
B
2
A
2
+
B
2
+
C
2
sin
u
+
A
A
2
+
B
2
+
C
2
v
y
=
y
0
−
r
B
A
2
+
B
2
cos
u
+
r
B
C
A
2
+
B
2
A
2
+
B
2
+
C
2
sin
u
+
B
A
2
+
B
2
+
C
2
v
z
=
z
0
−
r
A
2
+
B
2
A
2
+
B
2
+
C
2
sin
u
+
C
A
2
+
B
2
+
C
2
v
0
≤
u
≤
2
π
,
v
m
i
n
<
v
<
v
m
a
x
\begin{aligned} x & =x_0+r\frac{B}{\sqrt{A^2+B^2}}\cos{u}+r\frac{AC}{\sqrt{A^2+B^2}\sqrt{A^2+B^2+C^2}}\sin{u}+\frac{A}{\sqrt{A^2+B^2+C^2}}v\\ y & = y_0-r\frac{B}{\sqrt{A^2+B^2}}\cos{u}+r\frac{BC}{\sqrt{A^2+B^2}\sqrt{A^2+B^2+C^2}}\sin{u}+\frac{B}{\sqrt{A^2+B^2+C^2}}v\\ z & = z_0-r\frac{\sqrt{A^2+B^2}}{\sqrt{A^2+B^2+C^2}}\sin{u}+\frac{C}{\sqrt{A^2+B^2+C^2}}v\\ & 0\le{u}\le2\pi, v_{min}<v<v_{max} \end{aligned}
xyz=x0+rA2+B2Bcosu+rA2+B2A2+B2+C2ACsinu+A2+B2+C2Av=y0−rA2+B2Bcosu+rA2+B2A2+B2+C2BCsinu+A2+B2+C2Bv=z0−rA2+B2+C2A2+B2sinu+A2+B2+C2Cv0≤u≤2π,vmin<v<vmax
参考:
https://blog.csdn.net/inerterYang/article/details/111998278
python代码
import open3d as o3d
import numpy as np
def create_cylinder(cylinder_coefficients, height=5, step=0.5, vis=False):
"""
Args:
cylinder_coefficients: A dictionary containing cylindrical coefficients:
(r,x0,y0,z0,a,b,c
r the radius of the cylinder
x0,y0,z0 the Starting center of the cylinder
a, b, c: axis coefficient of the cylinder)
height: height_ of the cylinder
step: Density of cylinder point cloud
vis: whether to visualize the cylinder
Returns:
numpy form of the cylinder point cloud: n x 3
References:
https://blog.csdn.net/inerterYang/article/details/111998278
https://blog.csdn.net/inerterYang/article/details/111304307
@Author: Carlos_Lee 202111
"""
r = cylinder_coefficients['r']
x0 = cylinder_coefficients['x0']
y0 = cylinder_coefficients['y0']
z0 = cylinder_coefficients['z0']
a = cylinder_coefficients['a']
b = cylinder_coefficients['b']
c = cylinder_coefficients['c']
angle_ = np.arange(0, 2 * np.pi, step / 10).reshape(-1, 1)
v = np.arange(0, height, step)
npy = []
for i in v:
x = x0 + r * b / np.power(a * a + b * b, 0.5) * np.cos(angle_) + \
r * a * c / np.power(a * a + b * b, 0.5) / np.power(a * a + b * b + c * c, 0.5) * \
np.sin(angle_) + a / np.power(a * a + b * b + c * c, 0.5) * i
y = y0 - r * a / np.power(a * a + b * b, 0.5) * np.cos(angle_) + \
r * b * c / np.power(a * a + b * b, 0.5) / np.power(a * a + b * b + c * c, 0.5) * \
np.sin(angle_) + b / np.power(a * a + b * b + c * c, 0.5) * i
z = z0 - r * np.power(a * a + b * b, 0.5) / np.power(a * a + b * b + c * c, 0.5) * np.sin(angle_) + \
c / np.power(a * a + b * b + c * c, 0.5) * i
npy.append(np.concatenate([x, y, z], axis=-1))
npy = np.concatenate(npy, axis=0)
if vis:
coordinate_ = o3d.geometry.TriangleMesh.create_coordinate_frame(size=height / 2., origin=[0.0, 0.0, 0.0])
pcd_ = o3d.geometry.PointCloud()
pcd_.points = o3d.utility.Vector3dVector(npy)
o3d.visualization.draw_geometries([coordinate_, pcd_], window_name="generate cylinder",
width=960, height=900, left=960, top=100)
return npy
if __name__ == "__main__":
cylinder_coefficients = {'r': 2.0, 'x0': 0, 'y0': 0, 'z0': 0, 'a': 1, 'b': 1, 'c': 0}
cylinder_npy = create_cylinder(cylinder_coefficients=cylinder_coefficients, height=5, step=0.05, vis=True)
完整测试代码在GitHub:
https://github.com/Noel-Gallagher-Highflyingbirds/geometry
生成结果
测试
完
--------------------------------------------------------------------------------------------诺有缸的高飞鸟202111