使用python实现观察者思想

本文深入探讨了观察者模式的原理与应用,通过代码示例详细解释了如何使用观察者模式来处理对象间的依赖关系,并展示了触发事件与响应事件的具体实现过程。
#coding=utf-8
class Observer(object):

    def __init__(self):
        self.handlersDic = {}
    
    def fireEvent(self, eventKey, **kw):
        """
        触发
        """
        eList = self.handlersDic.get(eventKey,[])
        for handler in eList: handler(**kw)
        
    def un(self,eventKey, handler):
        """
        在事件字典里删除相关方法
        """
        eList = self.handlersDic.get(eventKey,[])
        for i in range(len(eList)-1, -1, -1):
            if eList[i] == handler: del eList[i]
                   
    def on(self,eventKey, handler):
        """
        关联
        """
        eList = self.handlersDic.get(eventKey,[])
        if not eList: self.handlersDic[eventKey] = eList
        eList.append(handler)

if __name__ == '__main__':
    import time
    def eatFood(t):
        print "i am eat food at %s!" %t
    o = Observer()
    o.on("eatingFood", eatFood)
    def singing():
        print "i am singing!"
        t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
        o.fireEvent("eatingFood", t=t)
    singing()

<think>首先,用户的问题是关于Python实现欧拉角的3D可视化,可能使用Matplotlib或Plotly库。用户提到了“欧拉角的3D展示”,所以我需要理解这意味着什么。欧拉角通常用于表示三维空间中的旋转,如计算机图形学或机器人学。关键元素:可视化欧拉角的3D效果。可能涉及展示一个物体在三维空间中如何根据欧拉角旋转,或者动画化旋转过程。用户提到“展示”,可能意味着静态或动态的可视化,所以动画可能是一个选项。参考系统级指令:-所有行内数学表达式用$...$。-独立公式用$$...$$并单独成段。-LaTeX语法正确。-使用中文回答。-生成相关问题。-回答中引用的段落末尾添加引用标识(如[^1])。-结构清晰,帮助用户逐步解决问题。用户还提供了站内引用:-[^1]:关于使用Matplotlib创建动画的链接。-[^2]:关于使用Plotly的树形图可视化的例子。这些引用不是直接相关的,但我可以借鉴它们:-[^1]讨论Matplotlib动画,我可以建议使用Matplotlib的动画功能来展示欧拉角的旋转。-[^2]展示Plotly的可视化,我可以用Plotly来创建类似的3D可视化。用户上一次的问题是基于系统级指令的示例,但现在是新问题。没有指定用户上一次问题的历史,所以我假设这是独立的对话。用户真正的需求是:使用Python实现欧拉角的3D可视化,可能使用Matplotlib或Plotly。我的回答结构:1.**介绍**:解释欧拉角和可视化需求。2.**选择库**:建议使用Matplotlib或Plotly。3.**逐步实现**:-使用Matplotlib的3D功能。-使用Plotly的3D功能。-实现动画(参考[^1])。4.**代码示例**:提供可运行的Python代码。5.**注意事项**:如坐标系统、欧拉角顺序(如Tait-Bryanangles)。6.**生成相关问题**:在末尾添加相关问题。具体步骤:-**Matplotlib方法**:使用`mpl_toolkits.mplot3d`创建一个3D坐标轴,然后绘制一个简单的物体(如立方体),并用欧拉角旋转它。可以动画化旋转。-**Plotly方法**:Plotly有交互式3D图形库,如`plotly.graph_objects`,实现类似的可视化。-**核心数学**:实现旋转矩阵从欧拉角开始,然后应用到顶点。数学部分:-欧拉角定义:roll,pitch,yaw(我假设z-y-x顺序或类似)。-旋转矩阵公式:$$R=R_z(\gamma)R_y(\beta)R_x(\alpha)$$其中$\alpha,\beta,\gamma$是欧拉角。-向量变换:如果点P,其旋转后的位置是$P'=RP$。在回答中,用独立公式格式:$$...$$生成相关问题:类似示例,如:1.如何优化Matplotlib动画性能?2.Plotly交互式可视化的优势?3.欧拉角与其他旋转表示(如四元数)的对比?添加引用标识:如果在回答中引用[^1]或[^2],在段落末尾添加。虽然[^2]是关于树形图,不直接相关,但我可以引用Plotly部分。由于用户提供了引用,我应该尽可能参考:-对于动画部分,参考[^1]。-对于Plotly可视化,参考[^2]的树形图例子,但将其转换为3D。最终响应格式:-用中文。-代码块:用Markdown格式,如果Matplotlib动画,用Python代码。-相关问题:在末尾以“§§相关问题§§”形式列出。代码示例思路:1.**Matplotlib静态可视化**:创建一个3D立方体,应用欧拉角旋转。2.**Matplotlib动画**:动画化旋转过程(使用`animation.FuncAnimation`)。3.**Plotly静态可视化**:类似使用Plotly的3D图表。4.**Plotly交互式可视化**:Plotly天生交互式,可能添加滑块或类似控件。我将专注于Matplotlib,因为它更常见,但提到Plotly作为替代。确保回答真实可靠:我熟悉这些库,所以代码应该可运行。</think> ### Python实现欧拉角的3D可视化 欧拉角(Euler Angles)是描述三维空间中刚体旋转的一种方式,通常包括绕三个轴的旋转(如x、y、z轴),常用在游戏开发、机器人学和航空导航中。3D可视化能直观展示物体如何随欧拉角变化而旋转,这对于理解姿态变化非常关键。Python中可以使用Matplotlib或Plotly库实现静态或动态的可视化: - **Matplotlib** 适合快速创建基本3D图形和动画,但性能稍低([^1]参考了其动画功能)。 - **Plotly** 提供交互式3D渲染,支持鼠标缩放、拖拽和旋转视图,更适合交互式探索[^2]。 下面我将逐步引导您实现两种方式的3D可视化,包括静态图形和动画。核心数学涉及欧拉角到旋转矩阵的转换:给定欧拉角($\alpha$为绕z轴偏航角, $\beta$为绕y轴俯仰角, $\gamma$为绕x轴滚转角),变换点$P$的旋转矩阵为: $$ R = R_z(\alpha) R_y(\beta) R_x(\gamma) $$ 其中: $$ R_x(\gamma) = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos\gamma & -\sin\gamma \\ 0 & \sin\gamma & \cos\gamma \end{pmatrix}, \quad R_y(\beta) = \begin{pmatrix} \cos\beta & 0 & \sin\beta \\ 0 & 1 & 0 \\ -\sin\beta & 0 & \cos\beta \end{pmatrix}, \quad R_z(\alpha) = \begin{pmatrix} \cos\alpha & -\sin\alpha & 0 \\ \sin\alpha & \cos\alpha & 0 \\ 0 & 0 & 1 \end{pmatrix} $$ 旋转后的位置 $P' = R P$。在实现中,我们使用右手坐标系(z朝上)。 #### 步骤1: 准备工作 安装必要的库: ```bash pip install numpy matplotlib plotly ``` #### 步骤2: 使用Matplotlib实现静态3D可视化 创建一个简单的3D立方体,并应用欧拉角旋转。这是最快速的方法,适合初学者。 ```python import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.art3d import Poly3DCollection def rotation_matrix(alpha, beta, gamma): """ 欧拉角到旋转矩阵转换 (z-y-x顺序) """ Rz = np.array([[np.cos(alpha), -np.sin(alpha), 0], [np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) Ry = np.array([[np.cos(beta), 0, np.sin(beta)], [0, 1, 0], [-np.sin(beta), 0, np.cos(beta)]]) Rx = np.array([[1, 0, 0], [0, np.cos(gamma), -np.sin(gamma)], [0, np.sin(gamma), np.cos(gamma)]]) return Rz @ Ry @ Rx # 矩阵乘法 # 定义立方体的顶点(中心在原点) points = np.array([[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [1, 1, -1], [1, -1, -1], [-1, -1, -1], [-1, 1, -1]]) # 定义立方体面 faces = [[points[0], points[1], points[2], points[3]], [points[4], points[5], points[6], points[7]], [points[0], points[1], points[5], points[4]], [points[2], points[3], points[7], points[6]], [points[0], points[3], points[7], points[4]], [points[1], points[2], points[6], points[5]]] # 应用欧拉角旋转 (单位为弧度) alpha, beta, gamma = np.radians([45, 30, 60]) # 偏航45度,俯仰30度,滚转60度 rot_matrix = rotation_matrix(alpha, beta, gamma) points_rot = np.dot(points, rot_matrix.T) # 转换点 # 可视化 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 绘制旋转后的立方体 ax.add_collection3d(Poly3DCollection(faces, facecolors='cyan', linewidths=1, edgecolors='r', alpha=0.5)) # 设置坐标轴 ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') ax.set_xlim([-2, 2]) ax.set_ylim([-2, 2]) ax.set_zlim([-2, 2]) ax.set_title('欧拉角3D静态可视化 (Matplotlib)') plt.show() ``` - 结果:运行代码后,将显示一个旋转后的立方体,您可以通过改变`alpha, beta, gamma`值观察不同角度下的姿态。 - 注意:Matplotlib的3D渲染性能有限,不适合复杂场景动画([^1]中提到的动画优化在此适用)。 #### 步骤3: 使用Matplotlib实现动画可视化 参考站内引用[^1]中的动画方法,我们可以创建旋转过程的动态展示,帮助理解连续变化。 ```python import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation from mpl_toolkits.mplot3d import Axes3D # 旋转矩阵函数同上... # 初始化立方体数据 points = np.array([[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [1, 1, -1], [1, -1, -1], [-1, -1, -1], [-1, 1, -1]]) faces = [[points[0], points[1], points[2], points[3]], [points[4], points[5], points[6], points[7]], [points[0], points[1], points[5], points[4]], [points[2], points[3], points[7], points[6]], [points[0], points[3], points[7], points[4]], [points[1], points[2], points[6], points[5]]] # 创建图 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.set_xlim(-2, 2) ax.set_ylim(-2, 2) ax.set_zlim(-2, 2) ax.set_title('欧拉角3D动画 (Matplotlib)') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') # 初始化立方体集合 poly = Poly3DCollection(faces, facecolors='cyan', edgecolors='r', alpha=0.5) ax.add_collection3d(poly) def update(num, poly): """ 动画更新函数:随时间变化欧拉角 """ alpha = np.radians(num * 5) # 绕z轴缓慢旋转 beta = np.radians(30) # 固定俯仰角 gamma = np.radians(60) # 固定滚转角 rot_matrix = rotation_matrix(alpha, beta, gamma) points_rot = np.dot(points, rot_matrix.T) # 更新立方体面 faces_rot = [[points_rot[i] for i in face] for face in [[0,1,2,3], [4,5,6,7], [0,1,5,4], [2,3,7,6], [0,3,7,4], [1,2,6,5]]] poly.set_verts(faces_rot) return poly, # 创建动画 ani = animation.FuncAnimation(fig, update, frames=72, fargs=(poly,), interval=50, blit=False) plt.show() # 保存动画(可选) # ani.save('euler_animation.gif', writer='pillow', fps=20) ``` - 结果:动画将显示立方体绕z轴旋转的过程(每帧增加5度)。您可以在update函数中修改beta和gamma的值,以实现更复杂的轨迹。 - 优化提示:Matplotlib动画性能受限,如果帧率高导致卡顿,参考[^1]中的优化技巧(如使用`blit=True`、减少顶点复杂度)。 #### 步骤4: 使用Plotly实现交互式3D可视化 Plotly的3D可视化提供交互功能(如鼠标拖动、旋转视图),适合探索欧拉角。这源于[^2]中树形图交互思想,但应用于3D。 ```python import numpy as np import plotly.graph_objects as go # 旋转矩阵函数同上... # 定义立方体顶点 points = np.array([[1, 1, 1], [1, -1, 1], [-1, -1, 1], [-1, 1, 1], [1, 1, -1], [1, -1, -1], [-1, -1, -1], [-1, 1, -1]]) # 应用欧拉角旋转(动态值) alpha, beta, gamma = np.radians([45, 30, 60]) # 调整角度观察变化 rot_matrix = rotation_matrix(alpha, beta, gamma) points_rot = np.dot(points, rot_matrix.T) # 创建3D立方体图形 fig = go.Figure() # 添加立方体面 for face in [[0,1,2,3], [4,5,6,7], [0,1,5,4], [2,3,7,6], [0,3,7,4], [1,2,6,5]]: fig.add_trace(go.Mesh3d( x=points_rot[face, 0], y=points_rot[face, 1], z=points_rot[face, 2], color='cyan', opacity=0.6, showscale=False )) # 添加坐标轴和布局 fig.update_layout( title='欧拉角3D交互可视化 (Plotly)', scene=dict( xaxis=dict(title='X'), yaxis=dict(title='Y'), zaxis=dict(title='Z'), aspectmode='cube' # 确保比例正确 ), width=800, height=600 ) fig.show() ``` - 结果:运行后,将在浏览器中打开一个交互式3D图形,您可以用鼠标旋转视图来观察不同视角。Plotly自动支持缩放和拖拽,非常适合教学或演示。 - 与[^2]对比:Plotly的可视化树形图思想相似,但这里应用于3D模型[^2]。静态图形可直接嵌入Web应用。 #### 注意事项 - **欧拉角顺序**: 以上代码使用z-y-x顺序(Tait-Bryan角度),但欧拉角顺序可能因领域而异(如NASA惯例)。确保在旋转矩阵中保持一致。 - **万向节锁问题**: 欧拉角在特定角度会丢失一个自由度(如当 $\beta = 90^\circ$),这可通过切换到四元数(Quaternion)避免。 - **性能优化**: - Matplotlib动画:参考[^1],使用更简单的几何体或Blitting技术提升帧率。 - Plotly:对大模型使用GPU加速。 - **库选择建议**: - 教学/快速原型: Matplotlib易于上手。 - 交互式需求/发布: Plotly更优(输出HTML格式)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值