Files
wire_controlsystem/UI/ui_3d.py

217 lines
6.9 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. 轴范围X轴设为0-60cmY/Z设为0-5cm
self.ax.set_xlim(0, 60)
self.ax.set_ylim(0, 5)
self.ax.set_zlim(0, 5)
# 2. 刻度间隔统一为1cm
self.ax.set_xticks(range(0, 61, 5)) # X轴每5cm标一次刻度避免太密集
self.ax.set_yticks(range(0, 6, 1)) # Y轴每1cm标一次刻度
self.ax.set_zticks(range(0, 6, 1)) # Z轴每1cm标一次刻度
# 调整视角适配X轴1cm刻度
self.ax.view_init(elev=20, azim=60)
def draw_target_shape(self):
"""绘制3D结构"""
vertices = [
# 底部截面Z=0平面
(0, 3, 0), (50, 3, 0),
(50, 3, 0), (50, 0, 0),
# 中间截面Z=0.5平面)
(0, 0.5, 0.5), (0, 3, 0.5),
(0, 3, 0.5), (50, 3, 0.5),
(50, 3, 0.5), (50, 0.5, 0.5),
(50, 0.5, 0.5), (0, 0.5, 0.5),
# 顶部界面Z=2平面
(0, 0, 2), (0, 0.5, 2),
(0, 0.5, 2), (50, 0.5, 2),
(50, 0.5, 2), (50, 0, 2),
(50, 0, 2), (0, 0, 2),
# z方向的连线
(0, 3, 0.5), (0, 3, 0),
(50, 3, 0.5), (50, 3, 0),
(0, 0.5, 2), (0, 0.5, 0.5),
(50, 0.5, 2), (50, 0.5, 0.5),
(50, 0, 2), (50, 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", 50, 0, 1, 'red'),
("b", 50, 1, 0, 'green'),
("c", 50, 3, 0.25, 'blue'),
("d", 25, 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. 轴范围X轴设为0-60cmY/Z设为0-5cm
self.ax.set_xlim(0, 60)
self.ax.set_ylim(0, 5)
self.ax.set_zlim(0, 5)
# 2. 刻度间隔统一为1cm
self.ax.set_xticks(range(0, 61, 5)) # X轴每5cm标一次刻度避免太密集
self.ax.set_yticks(range(0, 6, 1)) # Y轴每1cm标一次刻度
self.ax.set_zticks(range(0, 6, 1)) # Z轴每1cm标一次刻度
# 调整视角适配X轴1cm刻度
self.ax.view_init(elev=20, azim=60)
def draw_target_shape(self):
"""绘制3D结构"""
vertices = [
# 底部截面Z=0平面
(0, 3, 0), (50, 3, 0),
(50, 3, 0), (50, 0, 0),
# 中间截面Z=0.5平面)
(0, 0.5, 0.5), (0, 2.5, 0.5),
(50, 2.5, 0.5), (50, 0.5, 0.5),
(50, 0.5, 0.5), (0, 0.5, 0.5),
# 中间截面Z=1平面
(0, 2.5, 1),(0, 3, 1),
(0, 3, 1), (50, 3, 1),
(50, 3, 1), (50, 2.5, 1),
(50, 2.5, 1), (0, 2.5, 1),
# 顶部界面Z=2平面
(0, 0, 2), (0, 0.5, 2),
(0, 0.5, 2), (50, 0.5, 2),
(50, 0.5, 2), (50, 0, 2),
(50, 0, 2), (0, 0, 2),
# z方向的连线
(0, 3, 1), (0, 3, 0),
(50, 3, 1), (50, 3, 0),
(0, 0.5, 2), (0, 0.5, 0.5),
(50, 0.5, 2), (50, 0.5, 0.5),
(50, 0, 2), (50, 0, 0),
(0, 2.5, 1),(0, 2.5, 0.5),
(50, 2.5, 1),(50, 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", 50, 0, 1, 'red'),
("b", 50, 1, 0, 'green'),
("c", 50, 3, 0.5, 'blue'),
("d", 25, 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()