如何在Matplotlib中实现符合要求的斜轴测Cabinet投影?
Matplotlib斜轴测Cabinet投影矩阵适配方案
核心差异说明
Matplotlib的3D投影矩阵与OpenGL存在两点关键差异:
- 采用列主序的齐次变换矩阵,变换时向量以列形式参与运算
- 最终会对变换后的齐次向量执行透视除法(即
(x/w, y/w, z/w)),因此矩阵需适配这一计算逻辑
修正后的Cabinet投影实现
针对x轴水平、y轴垂直的标准Cabinet投影,正确的矩阵代码如下:
import numpy as np from matplotlib import projections as proj3d def _oblique_cabinet_transformation(zfront, zback): # 标准Cabinet投影参数:45度斜角,z轴缩放0.5 angle_rad = np.radians(45) z_scale = 0.5 # 适配Matplotlib的齐次投影矩阵 proj_matrix = np.array([ [2, 0, z_scale * np.cos(angle_rad), 0], [0, 2, -z_scale * np.sin(angle_rad), 0], [0, 0, -2, 0], [0, 0, -(zfront + zback), -(zfront - zback)] ]) return proj_matrix # 替换默认透视变换函数 proj3d.persp_transformation = _oblique_cabinet_transformation
关键调整点
- 保留正交投影的视口适配:矩阵前两行的2倍缩放、第三行的z轴缩放,以及最后一行的深度参数,确保和原生正交投影的视口匹配
- 加入Cabinet斜切逻辑:将z轴分量按比例斜切到x、y轴,同时严格遵循Matplotlib的齐次矩阵格式
- 可自定义参数:修改
angle_rad调整斜切角度,修改z_scale调整z轴方向的缩放比例(标准Cabinet用0.5)
验证示例
替换矩阵后,可通过绘制3D立方体验证效果:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 定义立方体顶点 vertices = np.array([ [0,0,0], [1,0,0], [1,1,0], [0,1,0], [0,0,1], [1,0,1], [1,1,1], [0,1,1] ]) ax.scatter(vertices[:,0], vertices[:,1], vertices[:,2]) # 绘制立方体棱边 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)] for edge in edges: ax.plot3D(*zip(vertices[edge[0]], vertices[edge[1]]), color='black') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show()
内容的提问来源于stack exchange,提问作者gewa
相关产品推荐
相关产品推荐

