Files
wire_controlsystem/UI/ui_3d.py

227 lines
7.4 KiB
Python
Raw Normal View History

2026-01-07 18:11:27 +08:00
#!/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)
2026-01-07 18:11:27 +08:00
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),
2026-01-07 18:11:27 +08:00
# 中间截面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),
2026-01-07 18:11:27 +08:00
# 顶部界面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),
2026-01-07 18:11:27 +08:00
# z方向的连线
(0, 3, 0.5), (0, 3, 0),
(100, 3, 0.5), (100, 3, 0),
2026-01-07 18:11:27 +08:00
(0, 0.5, 2), (0, 0.5, 0.5),
(100, 0.5, 2), (100, 0.5, 0.5),
(100, 0, 2), (100, 0, 0),
2026-01-07 18:11:27 +08:00
]
# 绘制所有棱边
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')
2026-01-07 18:11:27 +08:00
]
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)
2026-01-07 18:11:27 +08:00
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),
2026-01-07 18:11:27 +08:00
# 中间截面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),
2026-01-07 18:11:27 +08:00
# 中间截面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),
2026-01-07 18:11:27 +08:00
# 顶部界面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),
2026-01-07 18:11:27 +08:00
# z方向的连线
(0, 3, 1), (0, 3, 0),
(100, 3, 1), (100, 3, 0),
2026-01-07 18:11:27 +08:00
(0, 0.5, 2), (0, 0.5, 0.5),
(100, 0.5, 2), (100, 0.5, 0.5),
(100, 0, 2), (100, 0, 0),
2026-01-07 18:11:27 +08:00
(0, 2.5, 1),(0, 2.5, 0.5),
(100, 2.5, 1),(100, 2.5, 0.5)
2026-01-07 18:11:27 +08:00
]
# 绘制所有棱边
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')
2026-01-07 18:11:27 +08:00
]
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()
2026-01-07 18:11:27 +08:00