前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Blender + Python:用少量有效数据绘制势能面示意图的方法

Blender + Python:用少量有效数据绘制势能面示意图的方法

作者头像
用户7592569
发布2022-03-31 21:14:03
1.6K0
发布2022-03-31 21:14:03
举报
文章被收录于专栏:量子化学

知乎链接:

https://zhuanlan.zhihu.com/p/477136180

前几天有需求要绘制一种势能面的示意图,类似教科书上标出一阶鞍点局域极小点那种示意图。

这种图正规绘制需要大量的单点计算,并用软件描面画成。但是实际上,我无法计算出如此多的单点来绘制一张图,毕竟在一般的计算有机工作中,单是定位过渡态就够普通鼠标侠喝一壶了,更别说选CV扫描并绘图了。时间更不允许,当我需要画图时,往往意味着科研需要的数据已经满足需求了,我再要求提供给我更多数据也不大可能得到。

因此只能利用现用的计算数据合理规划着绘制,也就是说我只能依据目前算出的几个结构的数据,或者IRC上的点进行绘制。

经朋友启发,组织了一个简易的流程,来画这种简易的示意图。

使用Blender绘制草稿

Blender是一款开源的建模软件:

代码语言:javascript
复制
Blender is a free and open-source 3D computer graphics software toolset used for creating animated films, visual effects, art, 3D printed models, motion graphics, interactive 3D applications, virtual reality, and computer games. Blender's features include 3D modelling, UV unwrapping, texturing, raster graphics editing, rigging and skinning, fluid and smoke simulation, particle simulation, soft body simulation, sculpting, animating, match moving, rendering, motion graphics, video editing, and compositing.
  1. 首先下载安装Blender,然后打开软件,可以更改下语言为中文。
  2. 删除初始产生的对象,最多只留下光源和摄像机
  3. 点击 添加 >> 网格 >> 平面

4. 点击上图中的 物体模式改为编辑模式

随后左边多出一竖列按钮,鼠标移到上面会显示名称,点击环切

同时编辑模式字样下方出现切割次数,建议改为10或者8,9

5. 鼠标移到添加的平面上,会出现一根黄线,点击,垂直各切一次

6. 鼠标左键长按该列第一个按钮,选中刷选

7. 平面上切出的格子点上按住鼠标移动,选中

8. 按 G便可以自由移动选中的点,建议再按Z限制其只改变Z坐标,按住鼠标中键可改变视角。

(当然,我们可以使用调整,直接捏出想要的形状,但是我们目的不是在Blender中捏出,只是利用其捏出基本形貌,后利用坐标在常用的科研作图软件中插值制作出符合审美的示意图,所以我建议使用刷选并只改变Z值,你也可以衰减编辑, 但我觉得操作单个点舒服,而且只变Z值的话,xy坐标均匀,后续代码拟合曲面效果会好)

这些点应该严格按照已有的数据绘制出相对高低,峰、谷、鞍面合理处理位置。

9. 使用鼠标拖动,竖直改变对象的形貌,大致捏出基本形貌,该低的地方低,该高的地方高,哪儿是鞍点那儿就捏成鞍部。

比如我可以随手捏出这么一个ts连接两个minimum的示意图,看起来比较丑陋

捏平面

导出为xyz坐标

  1. 此时保存一下自己捏的势能草面,然后进入物体模式,鼠标拖拉选中势能草面
  2. 文件 >> 导出 >> Waveforont(.obj) 勾中仅导出选中的物体 几何数据只选三角面 很幸运,.obj是文本可以进行文本解析,也可以用windows自带的3D查看器打开

3D查看器

3. 提取坐标

打开git bash然后输入grep "v " surface.obj |awk '{print

使用Python或者其他软件处理坐标

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import make_interp_spline
from sklearn.kernel_ridge import KernelRidge
from scipy import interpolate

with open("surface.xyz","r") as f:
    s = f.read()
    
xyz = s.splitlines()

x = []
y = []
z = []
for inf in range(len(xyz)):
    x.append(float(xyz[inf].split()[0]))
    y.append(float(xyz[inf].split()[1]))
    z.append(float(xyz[inf].split()[2]))
print(max(x),min(x),max(y),min(y),max(z),min(z))

dim = int(np.sqrt(len(xyz)))
X = np.asarray(x).reshape([dim, dim])
Y = np.asarray(y).reshape([dim, dim])
Z = np.asarray(z).reshape([dim, dim])

#fig = plt.figure()  
#ax = plt.axes(projection='3d')
#plt.axis('off')
#ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1, cmap = plt.get_cmap('gnuplot'))
#plot.show()


x_0 = np.linspace(min(x),max(x),200)
y_0 = np.linspace(min(y),max(y),200)
X_0, Y_0 = np.meshgrid(x_0, y_0,indexing='ij')
f = interpolate.Rbf(X, Y, Z, function='multiquadric',smooth=0.3)
Z_1 = f(X_0, Y_0)
Z_1.shape


fig = plt.figure()  
ax = plt.axes(projection='3d')
plt.axis('off')

ax.plot_surface(X_0, Y_0, Z_1, rstride = 1, cstride = 1, color="#cccccc")
plt.show()

在被注释的 plt.show()那里会展示最初捏出的草图形貌,不过在Blender里就能看到它就不需要matplotlib渲染了

代码默认生成200x200的图,使用Rbf来拟合曲面。一切都可以改。代码就在上面

也可以保存坐标使用MatLab、Origin等专业软件进一步处理。

结果展示

刚才随意搓的示意图感觉还凑合,还是有些别扭,可能需要再调一调。

刚才的示意图

之前画的几个图:

首先是捏的草图

最后调cmap = plt.get_cmap('gnuplot')着色的示意图

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 量子化学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用Blender绘制草稿
  • 导出为xyz坐标
  • 使用Python或者其他软件处理坐标
  • 结果展示
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档