Python绘制两向量张成的3D平面时出现零除错误如何解决
问题描述
定义两个向量 v1 = np.array([-1, 1, 0]) 和 v2 = np.array([0, 0, 1]),需要绘制这两个向量张成的平面。
两个向量v1和v2的示意如下:
初始实现代码尝试通过叉乘计算平面法向量推导z坐标公式,但因为叉乘结果z分量为0触发零除报错:
import numpy as np from plotly import graph_objs as go v1 = np.array([-1, 1, 0]) v2 = np.array([0, 0, 1]) trace_v1 = go.Scatter3d(x=[0, v1[0]], y=[0, v1[1]], z=[0, v1[2]],mode='lines') trace_v2 = go.Scatter3d(x=[0, v2[0]], y=[0, v2[1]], z=[0, v2[2]],mode='lines') xx, yy = np.meshgrid(np.linspace(-1, 1, 10), np.linspace(-1, 1, 10)) cp = np.cross(v1, v2) # result is [1, 1, 0] zz = (-cp[0]*xx - cp[1]*yy) / cp[2] # cp[2] is zero and raise an error because of zero division surf = go.Surface(x=xx, y=yy, z=zz) fig = go.Figure(data=[trace_v1, trace_v2, surf]) fig.show()
报错信息:divide by zero encountered in true_divide
问题原因
初始代码默认平面可以表示为z = f(x,y)的显式函数形式,但这两个向量张成的平面法向量为[1,1,0],对应平面方程是x + y = 0,平面完全垂直于xy平面,不存在z关于x、y的单值映射,强行解z必然触发除零错误。
解决方案
两个向量张成的平面本质是所有满足P = a*v1 + b*v2(a、b为任意实数)的点集合,直接用参数化方式生成网格点即可,这种方法对任意两个不共线的向量通用,不需要额外判断法向量分量是否为0。
修正后的可运行代码:
import numpy as np from plotly import graph_objs as go v1 = np.array([-1, 1, 0]) v2 = np.array([0, 0, 1]) # 绘制两个基准向量 trace_v1 = go.Scatter3d( x=[0, v1[0]], y=[0, v1[1]], z=[0, v1[2]], mode='lines', name='v1', line=dict(width=5) ) trace_v2 = go.Scatter3d( x=[0, v2[0]], y=[0, v2[1]], z=[0, v2[2]], mode='lines', name='v2', line=dict(width=5) ) # 参数化生成平面网格点,a、b取值范围可根据需要展示的平面大小调整 a, b = np.meshgrid(np.linspace(-1, 1, 10), np.linspace(-1, 1, 10)) xx = a * v1[0] + b * v2[0] yy = a * v1[1] + b * v2[1] zz = a * v1[2] + b * v2[2] surf = go.Surface(x=xx, y=yy, z=zz, opacity=0.5, showscale=False) fig = go.Figure(data=[trace_v1, trace_v2, surf]) # 调整视角方便观察平面 fig.update_layout(scene=dict(camera=dict(eye=dict(x=1.5, y=1.5, z=0.5)))) fig.show()
如果一定要用法向量推导平面坐标,需要先判断法向量三个分量中哪个不为0,选择对应坐标轴作为因变量求解(比如法向量z分量为0时,就解x关于y、z的表达式,或y关于x、z的表达式),但参数化方法不需要做分支判断,实现更简洁鲁棒。
内容的提问来源于stack exchange,提问作者rodd
相关产品推荐
相关产品推荐

