#!/usr/bin/env python # -*- coding: utf-8 -*- ''' # @Time : 2026/1/7 10:41 # @Author : reenrr # @File : 3D.py # @Desc : 界面上的线条3D显示 ''' from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas import matplotlib.pyplot as plt import sys # 线条类型A class Target3DWidgetA(QWidget): def __init__(self, parent=None): super().__init__(parent) self.init_3d_plot() self.setLayout(QVBoxLayout()) self.layout().addWidget(self.canvas) def init_3d_plot(self): # 3D画布 self.fig = plt.figure(figsize=(15, 6)) self.canvas = FigureCanvas(self.fig) self.ax = self.fig.add_subplot(111, projection='3d') # 绘制3D形状 self.draw_target_shape() # 添加标注 self.add_annotations() # ========== 核心修改:X/Y/Z轴统一为1cm单位 ========== self.ax.set_xlabel('X') self.ax.set_ylabel('Y') self.ax.set_zlabel('Z') # 1. 清空刻度数值(隐藏刻度数字) self.ax.set_xticklabels([]) self.ax.set_yticklabels([]) self.ax.set_zticklabels([]) # 2. 隐藏刻度线(针对3D轴的特殊设置) self.ax.tick_params(axis='x', which='both', length=0) # X轴刻度线长度设为0 self.ax.tick_params(axis='y', which='both', length=0) # Y轴刻度线长度设为0 self.ax.tick_params(axis='z', which='both', length=0) # Z轴刻度线长度设为0 # 轴范围保留(保证3D图形显示范围正确) self.ax.set_xlim(0, 120) self.ax.set_ylim(0, 5) self.ax.set_zlim(0, 5) # 调整视角(适配X轴1cm刻度) self.ax.view_init(elev=20, azim=60) def draw_target_shape(self): """绘制3D结构""" vertices = [ # 底部截面(Z=0平面) (0, 3, 0), (100, 3, 0), (100, 3, 0), (100, 0, 0), # 中间截面(Z=0.5平面) (0, 0.5, 0.5), (0, 3, 0.5), (0, 3, 0.5), (100, 3, 0.5), (100, 3, 0.5), (100, 0.5, 0.5), (100, 0.5, 0.5), (0, 0.5, 0.5), # 顶部界面(Z=2平面) (0, 0, 2), (0, 0.5, 2), (0, 0.5, 2), (100, 0.5, 2), (100, 0.5, 2), (100, 0, 2), (100, 0, 2), (0, 0, 2), # z方向的连线 (0, 3, 0.5), (0, 3, 0), (100, 3, 0.5), (100, 3, 0), (0, 0.5, 2), (0, 0.5, 0.5), (100, 0.5, 2), (100, 0.5, 0.5), (100, 0, 2), (100, 0, 0), ] # 绘制所有棱边 for i in range(0, len(vertices), 2): x = [vertices[i][0], vertices[i + 1][0]] y = [vertices[i][1], vertices[i + 1][1]] z = [vertices[i][2], vertices[i + 1][2]] self.ax.plot(x, y, z, color='black', linewidth=2) def add_annotations(self): """标注位置(适配X轴1cm单位)""" annotations = [ ("a", 100, 0, 1, 'red'), ("b", 100, 1, 0, 'green'), ("c", 100, 3, 0.25, 'blue'), ("d", 50, 2, 0, 'magenta') ] for text, x, y, z, color in annotations: self.ax.text(x, y, z, text, fontsize=14, color=color, weight='bold') # 线条类型B class Target3DWidgetB(QWidget): def __init__(self, parent=None): super().__init__(parent) self.init_3d_plot() self.setLayout(QVBoxLayout()) self.layout().addWidget(self.canvas) def init_3d_plot(self): # 3D画布 self.fig = plt.figure(figsize=(15, 6)) self.canvas = FigureCanvas(self.fig) self.ax = self.fig.add_subplot(111, projection='3d') # 绘制3D形状 self.draw_target_shape() # 添加标注 self.add_annotations() # ========== 核心修改:X/Y/Z轴统一为1cm单位 ========== self.ax.set_xlabel('X') self.ax.set_ylabel('Y') self.ax.set_zlabel('Z') # 1. 清空刻度数值(隐藏刻度数字) self.ax.set_xticklabels([]) self.ax.set_yticklabels([]) self.ax.set_zticklabels([]) # 2. 隐藏刻度线(针对3D轴的特殊设置) self.ax.tick_params(axis='x', which='both', length=0) # X轴刻度线长度设为0 self.ax.tick_params(axis='y', which='both', length=0) # Y轴刻度线长度设为0 self.ax.tick_params(axis='z', which='both', length=0) # Z轴刻度线长度设为0 # 轴范围保留(保证3D图形显示范围正确) self.ax.set_xlim(0, 120) self.ax.set_ylim(0, 5) self.ax.set_zlim(0, 5) # 调整视角(适配X轴1cm刻度) self.ax.view_init(elev=20, azim=60) def draw_target_shape(self): """绘制3D结构""" vertices = [ # 底部截面(Z=0平面) (0, 3, 0), (100, 3, 0), (100, 3, 0), (100, 0, 0), # 中间截面(Z=0.5平面) (0, 0.5, 0.5), (0, 2.5, 0.5), (100, 2.5, 0.5), (100, 0.5, 0.5), (100, 0.5, 0.5), (0, 0.5, 0.5), # 中间截面(Z=1平面) (0, 2.5, 1),(0, 3, 1), (0, 3, 1), (100, 3, 1), (100, 3, 1), (100, 2.5, 1), (100, 2.5, 1), (0, 2.5, 1), # 顶部界面(Z=2平面) (0, 0, 2), (0, 0.5, 2), (0, 0.5, 2), (100, 0.5, 2), (100, 0.5, 2), (100, 0, 2), (100, 0, 2), (0, 0, 2), # z方向的连线 (0, 3, 1), (0, 3, 0), (100, 3, 1), (100, 3, 0), (0, 0.5, 2), (0, 0.5, 0.5), (100, 0.5, 2), (100, 0.5, 0.5), (100, 0, 2), (100, 0, 0), (0, 2.5, 1),(0, 2.5, 0.5), (100, 2.5, 1),(100, 2.5, 0.5) ] # 绘制所有棱边 for i in range(0, len(vertices), 2): x = [vertices[i][0], vertices[i + 1][0]] y = [vertices[i][1], vertices[i + 1][1]] z = [vertices[i][2], vertices[i + 1][2]] self.ax.plot(x, y, z, color='black', linewidth=2) def add_annotations(self): """标注位置(适配X轴1cm单位)""" annotations = [ ("a", 100, 0, 1, 'red'), ("b", 100, 1, 0, 'green'), ("c", 100, 3, 0.5, 'blue'), ("d", 50, 2, 0, 'magenta') ] for text, x, y, z, color in annotations: self.ax.text(x, y, z, text, fontsize=14, color=color, weight='bold') class MainWindowA(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("3D视图(X/Y/Z单位:1cm)") self.setGeometry(100, 100, 1200, 700) # 加宽窗口,适配X轴1cm刻度 self.setCentralWidget(Target3DWidgetA()) class MainWindowB(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("3D视图(X/Y/Z单位:1cm)") self.setGeometry(100, 100, 1200, 700) # 加宽窗口,适配X轴1cm刻度 self.setCentralWidget(Target3DWidgetB()) def ui_3d_a(): app = QApplication(sys.argv) window = MainWindowA() window.show() sys.exit(app.exec()) def ui_3d_b(): app = QApplication(sys.argv) window = MainWindowB() window.show() sys.exit(app.exec()) # ----------测试接口---------- if __name__ == '__main__': # ui_3d_a() ui_3d_b()