Files
wire_controlsystem/UI/ui_3d.py

227 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()