1 import matplotlib.pyplot as plt 2 from mpl_toolkits.mplot3d import Axes3D 3 import numpy as np 4 import nibabel as nib 5 6 def bresenham_3d(p0, p1, thickness): 7 ''' 8 Bresenham's Line Algorithm in 3D with adjustable thickness\n 9 CONFIRMED 10 ''' 11 12 def add_thickness(points, thickness): 13 '''Add thickness to the line''' 14 if thickness <= 1: 15 return points 16 thick_points = set() 17 r = thickness // 2 18 for x, y, z in points: 19 for dx in range(-r, r + 1): 20 for dy in range(-r, r + 1): 21 for dz in range(-r, r + 1): 22 if dx ** 2 + dy ** 2 + dz ** 2 <= r ** 2: 23 thick_points.add((x + dx, y + dy, z + dz)) 24 return list(thick_points) 25 26 points = [] 27 x0, y0, z0 = [int((num)) for num in p0] 28 x1, y1, z1 = [int((num)) for num in p1] 29 dx, dy, dz = np.abs(x1 - x0), np.abs(y1 - y0), np.abs(z1 - z0) 30 sx, sy, sz = np.sign(x1 - x0), np.sign(y1 - y0), np.sign(z1 - z0) 31 32 if dx >= dy and dx >= dz: 33 err1, err2 = 2 * dy - dx, 2 * dz - dx 34 while x0 != x1: 35 points.append((x0, y0, z0)) 36 if err1 >= 0: 37 y0 += sy 38 err1 -= 2 * dx 39 if err2 >= 0: 40 z0 += sz 41 err2 -= 2 * dx 42 err1 += 2 * dy 43 err2 += 2 * dz 44 x0 += sx 45 elif dy >= dx and dy >= dz: 46 err1, err2 = 2 * dx - dy, 2 * dz - dy 47 while y0 != y1: 48 points.append((x0, y0, z0)) 49 if err1 >= 0: 50 x0 += sx 51 err1 -= 2 * dy 52 if err2 >= 0: 53 z0 += sz 54 err2 -= 2 * dy 55 err1 += 2 * dx 56 err2 += 2 * dz 57 y0 += sy 58 else: 59 err1, err2 = 2 * dy - dz, 2 * dx - dz 60 while z0 != z1: 61 points.append((x0, y0, z0)) 62 if err1 >= 0: 63 y0 += sy 64 err1 -= 2 * dz 65 if err2 >= 0: 66 x0 += sx 67 err2 -= 2 * dz 68 err1 += 2 * dy 69 err2 += 2 * dx 70 z0 += sz 71 points.append((x1, y1, z1)) 72 73 # Apply thickness 74 return add_thickness(points, thickness) 75 76 77 # 创建一个图形对象 78 fig = plt.figure() 79 80 # 在图形中添加一个子图,参数为行数、列数和子图索引 81 ax = fig.add_subplot(1, 1, 1, projection='3d') 82 83 # 设置坐标轴的标签 84 ax.set_xlabel('X') 85 ax.set_ylabel('Y') 86 ax.set_zlabel('Z') 87 88 data = np.zeros((50, 50, 50)) 89 90 # 定义两个三维空间中的点 91 p0 = (20, 20, 20) # 起始点 92 p1 = (30, 30, 30) # 结束点 93 94 # 定义线宽 95 thickness = 25 96 97 # 调用函数 98 line_with_thickness = bresenham_3d(p0, p1, thickness) 99 100 # 打印结果 101 for point in line_with_thickness: 102 data[point[0], point[1], point[2]] = 1 103 104 # 创建一个新的Nifti1Image对象 105 solid_image = nib.Nifti1Image(data, np.eye(4)) 106 107 # 保存为nii.gz文件 108 nib.save(solid_image, 't25.nii.gz') 109 110 # 绘制体素图 111 ax.voxels(data) 112 113 # 显示图形 114 plt.show()
结果:
thickness = 1 时
thickness = 4 时
thickness = 7 时
thickness = 10 时
thickness = 25 时
标签:直线,bresenham,thickness,dz,dx,dy,err2,err1,3d From: https://www.cnblogs.com/hxqmw/p/18254476