2007年12月10日星期一

MAXScript:利用3DSMAX脚本产生原子运动动画

利用3DSMAX脚本产生原子运动动画

很久,很久以前,曾经做过一些关于分子动力学的工作,最后无疾而终,几乎什么都没有留下。分子动力学(Molecular Dynamic Simulation)计算微观原子间的相互作用,产生其运动轨迹,所有原子的运动形态最终表现为物体宏观的运动和变形等。

如果将这些原子的运动以动画的形式渲染出来,无疑是非常形象的。我曾经用3DSMAX的脚本MAXScript编写了一段程序来完成这个功能,在这里贴出来,供有需要的参考。
以下图中的模型为例,上面是Au探针,压入下面的Ni平板。原子的初始坐标值(x,y,z)分别放在文本文件posau0.txt和posni0.txt;
计算过程中产生一系列的原子坐标文件,这些文件以编号区别,如posau1.txt~posau100.txt;
在脚本文件中,首先读入原子的坐标信息,建立模型,每个原子对应一个球模型;
然后,在时间轴的不同时间坐标上,读入并指定每个原子的新坐标。
脚本的执行我也记不清了。可以在网上搜一下。
完整的程序如下(“--”的注释是把程序粘贴过来后补上去的,不知道有没有什么问题。我是在3DSMAX 5上运行的。):

--指定数组变量;
posarray = #()
postemp = #()
spAu = #()
spNi = #()
lay = #()
--字符串变量
strti = " "
--Au模型中原子个数,坐标数据量
atomau = 768
dataau = atomau*3
--Ni模型中原子个数,坐标数据量
atomni = 616
datani = atomni*3
--位置坐标文件的个数,不含初始坐标文件
framenum = 14
--原子半径
Rau = 1.44
Rni = 1.3
--指定材质,Ni平板每一层具有不同的颜色
--textMatAu = standardMaterial diffuse:[125, 125, 255]
textMatNi = standardMaterial diffuse:[92, 216, 92]
textMat1 = standardMaterial diffuse:[126, 173, 126]
textMat2 = standardMaterial diffuse:[233, 114, 67]
textMat3 = standardMaterial diffuse:[236, 224, 92]
textMat4 = standardMaterial diffuse:[92, 92, 216]
textMat5 = standardMaterial diffuse:[60, 151, 159]
textMat6 = standardMaterial diffuse:[179, 121, 216]
--读入Au的初始坐标
filename = "F:\data\posau0.txt"
in_name = (filename)
in_file = openFile in_name

if in_file != undefined then
(
for v=1 to dataau do
(
vert = readValue in_file
posarray[v]=vert
)
close in_file
--根据原子坐标建立每个原子的球模型
for v=1 to atomau do
(
ti=(v-1)*3+1
px = posarray[ti]
ti=ti+1
py = posarray[ti]
pz = posarray[ti+1]

spAu[v] = sphere radius:Rau position:[px, py, pz] segs:12 smooth:true
--判断原子所在的层,指定不同的材质
lay = (v-1)/288 as integer
lay = lay+1
if lay == 1 then
(spAu[v].mat = textMat1 )
if lay ==2 then
(spAu[v].mat = textMat2 )
if lay ==3 then
(spAu[v].mat = textMat3 )
if lay ==4 then
(spAu[v].mat = textMat4 )
if lay ==5 then
(spAu[v].mat = textMat5 )
if lay ==6 then
(spAu[v].mat = textMat6 )

)

)

--读入Ni的原子位置,并建立模型
filename = "F:data\pos\ni0.txt"
in_name = (filename)
in_file = openFile in_name
if in_file != undefined then
(
for v=1 to datani do
(
vert = readValue in_file
posarray[v]=vert
)
close in_file

for v=1 to atomni do
(
ti=(v-1)*3+1
px = posarray[ti]
ti=ti+1
py = posarray[ti]
pz = posarray[ti+1]

spNi[v] = sphere radius:Rni position:[px, py, pz] segs:12 smooth:true
spNi[v].mat = textmatNi
)

)

--开始设置坐标-时间动画
animate on (
at time 0
for tj in 1 to framenum do
( ti=tj*10
--指定新坐标对应的时间
at time ti (
strti = tj as string
filename = "F:\data\posau"+strti+".txt"
in_name = (filename)
in_file = openFile in_name
if in_file != undefined then
(
for v=1 to dataau do
(
vert = readValue in_file
posarray[v]=vert
)
close in_file

for v=1 to atomau do
(
ti=(v-1)*3+1
px = posarray[ti]
ti=ti+1
py = posarray[ti]
pz = posarray[ti+1]
--设置Au原子模型的新位置
spAu[v].position = [px, py, pz]
)
)

filename = "F:\data\posni"+strti+".txt"
in_name = (filename)
in_file = openFile in_name
if in_file != undefined then
(
for v=1 to datani do
(
vert = readValue in_file
posarray[v]=vert
)
close in_file

for v=1 to atomni do
(
ti=(v-1)*3+1
px = posarray[ti]
ti=ti+1
py = posarray[ti]
pz = posarray[ti+1]

spNi[v].position = [px, py, pz]

)

)
)

)
)

--max time play


再贴一个效果图(模拟计算结果本身可能不正确):

没有评论: