批量绘盒场景下,如何在Mayavi中无循环绘不连续线并自定义颜色
自定义大量立方体线段颜色的解决方案
当用线段拼接大量立方体时,要自定义颜色,核心是给每条线段(或每组线段)绑定对应的颜色值,再通过Mayavi的颜色映射机制来渲染。以下是具体实现步骤:
1. 准备数据结构
首先,需要把所有立方体的线段坐标整理成连续的点数组,同时为每个线段(或每个立方体的所有线段)分配对应的标量值(用来映射颜色)。
比如,一个立方体有12条边,每个边由两个点组成。假设你有N个立方体,那么点数组的形状是(12*N*2, 3),对应的标量数组形状是(12*N*2,)(每个点对应一个标量,或者每条线段的两个点用同一个标量,这样整条线段颜色一致)。
2. 基于颜色映射的高效实现
直接用mlab.plot3d性能不足,改用底层管线可以兼顾效率与颜色自定义:
import numpy as np from mayavi import mlab def create_cube_points(center, size): # 生成一个立方体的12条边的点对 half = size / 2 corners = np.array([ [center[0]-half, center[1]-half, center[2]-half], [center[0]+half, center[1]-half, center[2]-half], [center[0]+half, center[1]+half, center[2]-half], [center[0]-half, center[1]+half, center[2]-half], [center[0]-half, center[1]-half, center[2]+half], [center[0]+half, center[1]-half, center[2]+half], [center[0]+half, center[1]+half, center[2]+half], [center[0]-half, center[1]+half, center[2]+half], ]) # 12条边的索引对 edges = [ (0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7) ] points = [] for i,j in edges: points.append(corners[i]) points.append(corners[j]) return np.array(points) # 生成两个立方体的点数据 cube1 = create_cube_points([0,0,0], 1) cube2 = create_cube_points([2,2,2], 1) all_points = np.vstack([cube1, cube2]) # 为每个立方体的线段分配标量值(cube1用0,cube2用1) scalars = np.zeros(len(all_points)) scalars[len(cube1):] = 1 # 创建管线并连接线段 src = mlab.pipeline.scalar_scatter(all_points[:,0], all_points[:,1], all_points[:,2], scalars) src.mlab_source.dataset.lines = np.array([[i, i+1] for i in range(0, len(all_points), 2)]) lines = mlab.pipeline.stripper(src) # 渲染线段并设置配色方案 mlab.pipeline.surface(lines, line_width=2, colormap='cool') mlab.show()
3. 直接指定RGB颜色的方法
如果不需要依赖颜色映射表,想直接给每个立方体指定固定RGB颜色,可以通过给点数据绑定颜色数组实现:
import numpy as np from mayavi import mlab # 复用上面的create_cube_points函数生成点数据 cube1 = create_cube_points([0,0,0], 1) cube2 = create_cube_points([2,2,2], 1) all_points = np.vstack([cube1, cube2]) # 为每个立方体创建RGB颜色数组(每个点对应一组RGB值) colors = np.zeros((len(all_points), 3)) colors[:len(cube1)] = [1, 0, 0] # cube1设为红色 colors[len(cube1):] = [0, 0, 1] # cube2设为蓝色 # 创建管线并配置颜色数据 src = mlab.pipeline.scalar_scatter(all_points[:,0], all_points[:,1], all_points[:,2]) src.mlab_source.dataset.lines = np.array([[i, i+1] for i in range(0, len(all_points), 2)]) src.mlab_source.dataset.point_data.scalars = colors src.mlab_source.dataset.point_data.scalars.name = 'colors' # 渲染自定义颜色的线段 lines = mlab.pipeline.stripper(src) mlab.pipeline.surface(lines, line_width=2, color=None) mlab.show()
关键注意事项
- 性能优化:使用
stripper管线可以合并重复的线段数据,大幅提升大量立方体场景下的渲染速度,这也是比mlab.plot3d高效的核心原因。 - 颜色一致性:如果要让单条线段颜色统一,确保线段的两个点使用相同的标量值或RGB值即可。
- 配色方案:内置配色方案可通过
colormap参数指定,比如'viridis'、'hot'等,也可以自定义颜色映射表。
内容的提问来源于stack exchange,提问作者ZhiHeng Feng
相关产品推荐
相关产品推荐

