如何固定pyqtgraph中GLTextItem的方位角与仰角?
解决GLTextItem随相机旋转的问题:固定文本角度与尺寸
GLTextItem默认会自动朝向相机(即所谓的“横幅效应”),要让文本保持固定的世界空间角度,同时维持尺寸不随视角变化,可通过重写其paint方法,手动控制绘制时的模型矩阵来实现。
修改后的完整代码
import numpy as np from PySide6 import QtWidgets, QtGui import pyqtgraph as pg from pyqtgraph.opengl import GLViewWidget, GLTextItem from pyqtgraph.opengl.GLGraphicsItem import GLGraphicsItem def euler_matrix(azimuth_deg, elevation_deg): a, e = np.radians([azimuth_deg, elevation_deg]) ca, sa = np.cos(a), np.sin(a) ce, se = np.cos(e), np.sin(e) Rz = np.array([[ ca, -sa, 0], [ sa, ca, 0], [ 0, 0, 1]]) Rx = np.array([[1, 0, 0], [0, ce, -se], [0, se, ce]]) return Rx @ Rz class CustomText(GLTextItem): def __init__(self, *args, worldTextHeight=0.1, fixed_azimuth=0, fixed_elevation=0, **kwargs): super().__init__(*args, **kwargs) self.worldTextHeight = worldTextHeight # 设置固定的旋转矩阵(可自定义角度) self.fixed_rot = euler_matrix(fixed_azimuth, fixed_elevation) self.setGLOptions('translucent') def update_text_size(self): # 计算当前位置的像素尺寸,保持文本世界高度固定 unit_per_pixel = self.view().pixelSize(np.array(self.pos)) pixel_height = max(1, int(self.worldTextHeight / unit_per_pixel)) f = QtGui.QFont(self.font) f.setPixelSize(pixel_height) self.font = f self.update() def paint(self): self.update_text_size() gl = self.view().gl # 保存当前模型视图矩阵 gl.glPushMatrix() # 获取相机的视图矩阵,提取平移和缩放,替换旋转为固定旋转 cam = self.view().cameraParams() # 构建固定旋转的模型矩阵:平移到位置 -> 固定旋转 -> 相机缩放 model_matrix = np.eye(4) # 平移到文本位置 model_matrix[:3, 3] = self.pos # 应用固定旋转 model_matrix[:3, :3] = self.fixed_rot # 应用相机的缩放(保持尺寸适配) model_matrix[:3, :3] *= cam['distance'] / 5 # 基准距离为5,可根据初始相机位置调整 # 将矩阵转换为OpenGL可用的格式 gl.glMultMatrixf(model_matrix.T.flatten()) # 禁止父类自动应用相机旋转,直接绘制文本 GLGraphicsItem.paint(self) # 恢复之前的矩阵 gl.glPopMatrix() class CustomGLView(GLViewWidget): def __init__(self): super().__init__() # 创建固定角度的文本(可自定义azimuth和elevation) self.text_item = CustomText(pos=(0,0,0), text="固定角度文本", worldTextHeight=1, fixed_azimuth=0, fixed_elevation=0) self.addItem(self.text_item) self.addItem(pg.opengl.GLAxisItem()) self.setCameraPosition(distance=5) if __name__ == '__main__': app = QtWidgets.QApplication([]) view = CustomGLView() view.show() app.exec()
关键说明
- 固定旋转矩阵:通过
euler_matrix自定义文本的初始旋转角度,确保无论相机如何旋转,文本始终保持该角度。 - 手动控制模型矩阵:在
paint方法中,跳过GLTextItem默认的相机旋转逻辑,手动构建包含固定旋转的模型矩阵,同时保留相机的缩放和平移,确保文本位置和尺寸正确。 - 尺寸固定逻辑:通过
pixelSize计算当前视角下的单位像素比例,动态调整文本的像素高度,保证文本在世界空间中的高度固定。
内容的提问来源于stack exchange,提问作者THATS MY QUANT MY QUANTITATIVE
相关产品推荐
相关产品推荐

