[i=s] 本帖最后由 CasperVector 于 2009-2-11 22:38 编辑
[格式乱了点,参见附件= =]
简介
我设想曾经设想用空间中点的颜色来表示空间区域所对应的点集内关于点的坐标的函数的值,从而
描绘出三元函数的图像的模型。在本学期期末时,上高等数学课的老师说下个学期将在学生中开展应用
数学的活动。借此机会,在这个寒假以及随后的一个学期内,我想通过计算机程序实现这个设想已久的
模型,希望召集一些在编程[和/或]计算机图形学上有较多经验的同学来参与本计划。
建模
在高中(化学竞赛中)学习电子云和波函数的概念时,我曾经设想:电子云(概率密度函数)和
(取实数值的)波函数分别可以用灰度图像和彩色图像来表示。而这个模型可以简单地抽象成以下的数
学模型:
定义于集合 Ω={(x,y,z)|x∈[xmin,xmax],y∈[ymin,ymax],z∈[zmin,zmax]}(类比于 Mathematica 中作图函数
Plot 和 Plot3D 的选项)中的函数 u=f(x,y,z) (x,y,z,u∈R),可以用空间中对应区域 Ω 中有色点的集合
来表示,其颜色函数为 Color(x,y,z)=g[f(x,y,z)]。
颜色函数 g (u)实际上是由三个变量组成的向量函数 g (u)={R,G,B}={Red(u),Green(u),Blue(u)}(类比
于 Mathematica 中的 RGBColor 选项)。一般三个函数均可取为线性函数(包括常数函数);若原
函数 f(x,y,z)在 Ω 内无界,则截取一个合适的界 m[例如,从采样点得到的函数值中的最值之绝对值中的
最大值 m=max(|umin|,|umax|)]。
下面给出颜色函数 g (u)的两个示例:
1.g (u)=
{255,255(m-u)/m,255(m-u)/m} (u≥0),
{255(m+u)/m,255(m+u)/m,255} (u<0),
这就是我设想的绘制波函数图像时所使用的颜色函数,越正越红,越负越蓝,为零则白色。
2.g (u)={255(m-u)/m,255(m-u)/m,255(m-u)/m} (u≥0),
这就是我设想的绘制电子云图像时所使用的颜色函数,函数值越大则灰度越大。
目前,我还没有在任何的数学软件中发现能够实现这个模型的模块;在化学软件中,绘制电子云图
像的模块虽然有,但好像都还只是绘出一个半透明(有色)的、包围了一定概率区域的等概率密度曲面,
没有完全实现这个模型,因此希望能通过与同学们的合作实现这个模型。
关于解模的一些想法
一 对程序的预期(主要类比于 Mathematica 中的 Plot3D 函数):
Plot4D[f(x,y,z),{x,xmin,xmax},{y,ymin,ymax},{z,zmin,zmax},[OPTIONS]]
或
Plot4D[{f1,f2,f3,...},{x,xmin,xmax},{y,ymin,ymax},{z,zmin,zmax},[OPTIONS]]
参数和选项 (请注意“[OPTIONS]”中灰色的“[]”只是表示 OPTIONS 是可选的,下文中类似):
PlotRange -> m
指定函数的界,若超过此界则以界值所对应的颜色代替。默认为从采样点得到的函数值中的最值
之绝对值中的最大值。
ColorFunction -> {{Red1(u),Green1(u),Blue1(u)}[,{Red2(u),Green2(u),Blue2(u)}]}
指定颜色函数 g (u)。若输入了两个函数,则在 u0 非负时采用{Red1(u),Green1(u),Blue1(u)},否则采
用{Red2(u),Green2(u),Blue2(u)}。默认情况:若 f(x,y,z)为非负函数(未采到取负函数值的点)则采用
前面的电子云绘图函数,否则采用前面的波函数绘图函数。
PlotPoints -> {nx,ny,nz}
指定各个方向上的采样点个数。默认为绘图区间长度值(max-min)最大的那个变量取 20 个点,
其余变量根据绘图区间按比例计算。
ViewPoint -> {θ,φ}
指定观察方向。默认为{π/2,9π/10}。
另外的两点说明:
因为我只学了 C 语言,所以希望用 C 或者 C++来编写这个程序;由于受张涤凡的影响,我希望这个
程序能够成为一个开放源代码的程序。
二 程序设计的大概思路及一些可能需要提出的问题:
思路:输入识别 → 取点采样 → 透视绘图 → 后期处理
输入识别:化学吧论坛网友——来自青岛大学的张涤凡指出:这一部分实质上就是编写一个简单的
解释器,可能需要了解编译原理的同学来做。如果不能找到合适的人来作这件事的话,可能需要我自
己参阅科学自由软件 SCILAB 的源代码来编写此部分程序。
取点采样:这一部分应该并不算很困难,但需要和前面已经封装好了的函数以及绘图参数、选项密
切配合。采样可以主要分为两个阶段:1.根据 PlotPoints 选项计算各采样点的函数值 u0;2.根据函
数值以及 PlotRange 和 ColorFunction 两个参数计算各采样点的颜色值。计算中使用 float 类型
应该就可以了,因为 g(u)能够取到的值的精度本来就和 float 变量的精度接近,何况人眼对颜色的识别
能力本来就很有限。
透视绘图(包括绘制包围空间区域 Ω 的“盒子”):这一部分可能是最为棘手的,因为它涉及透视算
法的设计。目前我自己想到的算法是将每个采样点看成小长方体,再根据 ViewPoint 参数按指定方
向投影到指定的平面上。每个小长方体的投影将是一个多边形,如果采用平行透视法分别计算其形状
将十分耗费时间,故采用投影透视法;而在计算投影位置时,采用平行透视法以保证真实感。当然,
在初步的设计中,采用纯粹的投影透视法也是个不错的主意。
后期处理:主要是对 ViewPoint 参数的微调,通过键盘上的方向键控制。因为重新渲染图形本来
就是很耗费时间的工作,故设想通过以下方式实现:在绘图完成之后,按一下某个键(例如
“Rerender”的首字母“r”),可以在原图形的旁边显示一个小坐标系,通过方向键对其方向进行微调,
然后再按一下另一个键(例如回车键)即可进行重新渲染;如果想反悔,按其它的任意键即可返回。
返回后,再按一次另外的某个键(例如 Esc 键或者“Quit”的“q”)即可回到输入函数的状态;再按一
次,则退出整个程序。
三 对程序编写进程的大致规划:
其实我自己对这个程序的预期并不是十分地高。我们毕竟只是写一个独立于一般的数学软件的程序;
换言之,就是写一个示例型的程序。而将这个功能整合到一个系统的数学软件中可能就是真正的数学
软件编写者所做的事情了。从另一个角度考虑,我自己其实也是刚刚(相对系统地)接受编程训练不
久(大一上学期的计算概论课程),对软件工程中可能遇到的问题也不太了解,加上平时还有其他学
科的学习以及转系计划等等,可能进度会十分缓慢。
我大概设想的编写计划是:先编写只有一个目标函数的 Plot4D 程序中的基本部分,再将各种参数
和选项加进去,再编写多目标函数的程序以及添加重新渲染等功能;如果还有机会的话,还可以尝试
编写下面即将讲到的 ParametricPlot4D 程序。
扩展
在实际应用中,波函数或概率密度函数通常是用极坐标函数 f(r,θ,φ)来表示的。Mathematica 中的
PolarPlot 和 SphericalPlot3D 两个模块可以实现这个目的,而且其中也提供了下面的参数方程作
图模块:
ParametricPlot3D[{x(s,t),y(s,t),z(s,t)},{s,smin,smax},{t,tmin,tmax}]
类似地,我们也可以设计一个以下形式的程序来实现这个目的:
ParametricPlot4D[{x(r,s,t),y(r,s,t),z(r,s,t)},{r,rmin,rmax},{s,smin,smax},{t,tmin,tmax}]
对这个程序的预期以及设计的大概思路应该是与 Plot4D 类似的,但可能有两个不同的问题要提出:
1.采样策略——如何取采样点数?然而,这个问题可以由用户自己根据函数的特点来人工指定。默
认值或许应该保留,不妨取{20,20,20}。
2.如何取每个点对应的采样区域?在这个问题上,我们还没有找到合适的策略。
结语
要成功地将这个数学模型转化为实际的程序,需要有此方面数学基础的同学和程序员们的通力合作。
如果你有此方面的基础,欢迎加入我们,谢谢!