对于fortran的绘图、界面功能,我仅仅做一个简单的罗列,这样方便大家的讨论: 1.利用fortran的扩充函数绘图,下面是一个简单的例子,是编程爱好者 -- 中文编程开发类门户网站 -- ProgramFan.com上面有人贴出的; Visual Fortran中有提供绘图功能。Visual Fortran的绘图功能不完全是以扩充函数的类型存在,使用它的绘图功能必须在选择Project类型时,选择Standard Graphics或QuickWin模式。 Visual Fortran的QuickWin及Standard Graphics模式在简单的绘图使用上会比较方便,它的绘图函数功能比较多样,不过效率会比较差,而且不支持动画功能。 Standard 1.! 简单的绘图范例 2.! By Perng 1997/9/19 3.program Plot_Demo 4.! 使用Visual Fortran的绘图功能时需要module dflib 5.use DFLIB 6.implicit none 7. type(xycoord) :: t 8. integer :: result 9. call MoveTo(10,10,t) ! 把目前绘图的位置移动到坐标(10,10) 10. result=LineTo(100,50) ! 从(10,10)到(100,50)间绘一条直线 11. ! 画一个左上角为(110,10), 右下角为(150,50)的实心方形 12. result=Rectangle( $GFILLINTERIOR, 110,10, 150, 50 ) 13. ! 画一个可以放入在(10,60)--(150,100)方形当中的空心椭圆 14. result=Ellipse($GBORDER, 10, 60, 150, 100) 15.end program Plot_Demo 使用Standard Graphics模式时,会出现一个绘图窗口来画图。使用QuickWin模式时,除了绘图窗口外,还有内定的菜单可以使用。File菜单中的Print可以把图形显示出,Save可以把绘图结果储存成*.BMP图文件。 使用Visual Fortran的绘图功能时,打开窗口的工作是自动完成的。程序代码只需要直接调用绘图函数就可以进行绘图,下面对程序中所使用的绘图函数做一些介绍: subroutine MoveTo(x,y,t) 使用这个子程序时,要先把屏幕想像成一张画纸,程序会使用一只画笔在屏幕上画画。MoveTo(x,y,t)可以把这只画笔移动到画纸上的(x,y)坐标处,参数t则会返回移动之前的画笔所在位置(这个参数其实没有什么用,不过既然有规定就一定要把它放入)。 请注意,原点(0,0)是位在窗口的左上角,x坐标轴向右为正,y坐标轴向下为正。 integer(2) LineTo(x,y) 这个函数可以把画笔从目前的位置到(x,y)处画一条直线。返回值如果不为0,代表函数运行不正常。 integer(2) Rectangle( control, x1, y1, x2, y2 ) 这个函数可以在(x1,y1)、(x2,y2)两个端点间画出一个方形。control值可以用 integer(2) Ellipse(control,x1,y1,x2,y2) 这个函数会在(x1,y1)、(x2,y2)两端点间所形成的矩形中画椭圆。control的意义同上,在范例中使用$GBORDER,代表只画出外框。 下面这个范例画出SIN函数的图形: 1.! sin函数的绘图范例 2.program Plot_Sine 3. use DFLIB 4.implicit none 5. integer, parameter :: lines=500 ! 用多少线段来画函数曲线 6. real(kind=8), parameter :: X_Start=-5.0 ! x轴最小范围 7. real(kind=8), parameter :: X_End=5.0 ! x轴最大范围 8. real(kind=8), parameter :: Y_Top=2.0 ! y轴最大范围 9. real(kind=8), parameter :: Y_Bottom=-2.0 ! y轴最小范围 10. integer :: result ! 取回绘图函数运行状态 11. integer(kind=2) :: color ! 设定颜色用 12. real(kind=8) :: step ! 循环的增量 13. real(kind=8) :: x,y ! 绘图时使用,每条小线段都连接 14. real(kind=8) :: NewX,NewY ! (x,y)及(NewX,NewY) 15. real(kind=8), external :: f ! 待绘图的函数 16. type(wxycoord) :: wt ! 返回上一次的虚拟坐标位置 17. type(xycoord) :: t ! 返回上一次的实际坐标位置 18. 19. ! 设定虚拟坐标范围大小 20. result=SetWindow( .true. , X_Start, Y_Top, X_End, Y_Bottom ) 21. ! 用索引值的方法来设定颜色 22. result=SetColor(2) ! 内定的2号是应该是绿色 23. call MoveTo(10,20,t) ! 移动画笔到窗口的(10,20) 24. call OutGText("f(x)=sin(x)") ! 写出内容 25. ! 使用全彩RGB 0-255的256种色阶来设定颜色 26. color=RGBToInteger(255,0,0) ! 把控制RGB的三个值转换到color中 27. result=SetColorRGB(color) ! 利用color来设定颜色 28. 29. call MoveTo_W(X_Start,0.0_8,wt) ! 画X轴 30. result=LineTo_W(X_End,0.0_8) ! 31. call MoveTo_W(0.0_8,Y_Top,wt) ! 画Y轴 32. result=LineTo_W(0.0_8,Y_Bottom) ! 33. 34. step=(X_End-X_Start)/lines ! 计算小线段间的X间距 35. ! 参数#FF0000是使用16进制的方法来表示一个整数 36. result=SetColorRGB(#FF0000) 37. ! 开始绘制小线段们 38. do x=X_Start,X_End-step,step 39. y=f(x) ! 线段的左端点 40. NewX=x+step 41. NewY=f(NewX) ! 线段的右端点 42. call MoveTo_W(x,y,wt) 43. result=LineTo_W(NewX,NewY) 44. end do 45. ! 设定程序结束后,窗口会继续保留 46. result=SetExitQQ(QWIN$EXITPERSIST) 47.end 48.! 所要绘图的函数 49.real(kind=8) f(x) 50.implicit none 51. real(kind=8) :: x 52. f=sin(x) 53. return 54.end f 这个程序会以目前Windows分辨率的大小来打开绘图窗口。程序执行后只能够看到窗口的一小部 把这个程序中新使用的绘图函数做一个介绍 integer(2) SetWindow( invert, x1,y1, x2,y2 ) 用来设定虚拟坐标,invert的值是用来指定Y轴向上为正或为负。invert=.true.时向上为正,invert=.false.时向下为负。(x1,y1)、(x2,y2)则使用双精度浮点数来定义绘图范围两端的虚拟坐标值。 integer(2) SetColor(index) 使用索引值的方法来设定所要使用的颜色。 subroutine OutGText( text ) 调用这个子程序可以在目前画笔的位置上写出text字符串。 integer(4) RGBToInteger(R,G,B) 前面有提过,全彩模式中,RGB三种色光可以各自有256种色阶变化,所以一个颜色需要使用3 这个函数可以重新组合R G integer(2) SetColorRGB( color ) 用RGB方法来设定颜色,参数color中的第0~7个bits用来设定红光,第8~15 16进制数值在0~9时和10进制数字相同,但是接在9下面的数字为A、B、C、D、E、F。其 2.利用科学绘图软件包PLPlot、PGPLOT等 PLplot是一个用于多种编程语言(C, http://keihanna.dl.sourceforge.net/sourceforge/plplot/plplot-5.3.0-printable.pdf http://keihanna.dl.sourceforge.net/sourceforge/plplot/plplot-5.3.0.tar.gz http://www.astro.caltech.edu/%7Etjp/pgplot/ 上面的连接不一定能连接上,你可以到北大天网资源里面搜一下。 3.利用绘图软件包Matfor 大家可以看看http://www.softwarechn.com/ancad/ancad_index.htm是关于他的简单介绍。 具体的直接去网站AnCAD可以下载软件。 4.用OPENGL库绘图 关于这个vf的帮助里面有例子,但是要绘制三维图形的话,首先得知道一些图形学的基础知识。 5.windowsGDI绘图 这个还是API编程那一部分,比较麻烦。
[此贴子已经被作者于2007-1-3 14:57:03编辑过] |
-- 作者:lm_lxt -- 发布时间:2006-12-29 17:16:12 -- 对于fortran的程序界面方面,也简单做一个罗列: 1.混合编程: 用fortran做核心计算,然后利用VB、VC等做界面,这是大家认可的。具体的可以参考彭国伦、唐章宏等人写的书; 2.利用fortran的扩展功能 在上面的帖子里面已经给出例子,在QUICKWIN模式下可以利用原有的菜单,也可以自己订制菜单和对话框,如果程序仅仅需要一些简单的菜单和对话框的话,这个是不错的选择;唯一不足的就是缺少工具条的制作,当然如果调用API函数的话应该能够实现吧(探讨)。 3.利用API函数做界面 下面给出一个简单的例子,形成简单的菜单和模态对话框。从程序看,这个方法需要的代码比较多,相比较QUICKWIN工程中利用fortran的扩展功能而言,这个方法做界面就复杂一些。 module hh integer hInst integer hDlg end module hh integer WinMain( hInstance, hPrevInstance, lpszCmdLine, nCmdShow ) !DEC$ IF DEFINED(_X86_) !DEC$ ATTRIBUTES STDCALL, ALIAS : \'_WinMain@16\' :: WinMain !DEC$ ELSE !DEC$ ATTRIBUTES STDCALL, ALIAS : \'WinMain\' :: WinMain !DEC$ ENDIF !包含有用的模块 use user32 use dfwin use hh USE clipinc integer hInstance !定义句柄 integer hPrevInstance !定义句柄 integer nCmdShow integer lpszCmdLine !***************************************************************** interface integer*4 MainWndProc ( hwnd, mesg, wParam, lParam ) !DEC$ IF DEFINED(_X86_) !DEC$ ATTRIBUTES STDCALL, ALIAS : \'_MainWndProc@16\' :: MainWndProc !DEC$ ELSE !DEC$ ATTRIBUTES STDCALL, ALIAS : \'MainWndProc\' :: MainWndProc !DEC$ ENDIF integer*4 hwnd integer*4 mesg integer*4 wParam integer*4 lParam end end interface !****************************************************************** type (T_WNDCLASS) wc type (T_MSG) mesg integer hWnd,COLOR character*100 lpszClassName,lpszAppName,lpszMenuName COLOR=9 !这个用来改变窗口的背景颜色 lpszCmdLine = lpszCmdLine nCmdShow = nCmdShow lpszClassName ="Generic"C lpszAppName ="窗口程序,非模态对话框"C lpszMenuName="menumenu"C if(hPrevInstance .eq. 0) then wc%lpszClassName = LOC(lpszClassName) wc%lpfnWndProc = LOC(MainWndProc) wc%style = IOR(CS_VREDRAW , CS_HREDRAW) wc%hInstance = hInstance wc%hIcon = LoadIcon( hInstance, "MYICON") wc%hCursor = LoadCursor( hInstance, "MYCURSOR" ) wc%hbrBackground = ( COLOR_WINDOW+COLOR ) wc%lpszMenuName = LOC(lpszMenuName) wc%cbClsExtra = 0 wc%cbWndExtra = 0 i1 = RegisterClass(wc) end if hWnd = CreateWindowEx( 0, lpszClassName, & lpszAppName, & INT(WS_OVERLAPPEDWINDOW), & CW_USEDEFAULT, & 0, & CW_USEDEFAULT, & 0, & NULL, & NULL, & hInstance, & NULL & ) hInst=hInstance i = ShowWindow( hWnd, SW_SHOWNORMAL) do while( GetMessage (mesg, NULL, 0, 0)) if(IsDialogMessage(hDlg,mesg)==0)then i = TranslateMessage( mesg ) i = DispatchMessage( mesg ) endif end do WinMain = mesg%wParam end !*********************************以下是窗口处理函数************* integer MainWndProc (hWnd, mesg, wParam, lParam) !DEC$ IF DEFINED(_X86_) !DEC$ ATTRIBUTES STDCALL, ALIAS : \'_MainWndProc@16\' :: MainWndProc !DEC$ ELSE !DEC$ ATTRIBUTES STDCALL, ALIAS : \'MainWndProc\' :: MainWndProc !DEC$ ENDIF use user32 use dfwin use hh USE clipinc !***************************************************************** interface logical DialogFunc ( hdWnd, mesg, wParam, lParam ) !DEC$ IF DEFINED(_X86_) !DEC$ ATTRIBUTES STDCALL, ALIAS : \'_DialogFunc@16\' :: DialogFunc !DEC$ ELSE !DEC$ ATTRIBUTES STDCALL, ALIAS : \'DialogFunc\' :: DialogFunc !DEC$ ENDIF integer*4 hdWnd integer*4 mesg integer*4 wParam integer*4 lParam end end interface !****************************************************************** integer hWnd, mesg, wParam, lParam select case ( mesg ) case(WM_COMMAND) select case(LOWORD(wParam)) case(IDM_OPEN) hDlg=CreateDialog(hInst, LOC("AboutBox"C),hWnd,LOC(DialogFunc)) case(IDM_DIALOG) call PostQuitMessage( 0 ) end select case (WM_DESTROY) call PostQuitMessage( 0 ) case default MainWndProc = DefWindowProc( hWnd, mesg, wParam, lParam ) return end select end !**********************对话框窗口函数*********************** logical DialogFunc( hdWnd, mesg, wParam, lParam ) !DEC$ IF DEFINED(_X86_) !DEC$ ATTRIBUTES STDCALL, ALIAS : \'_DialogFunc@16\' :: DialogFunc !DEC$ ELSE !DEC$ ATTRIBUTES STDCALL, ALIAS : \'DialogFunc\' :: DialogFunc !DEC$ ENDIF use user32 use dfwin USE clipinc use hh integer hdWnd, mesg, wParam, lParam integer*4 i logical logresult,F,T character*100 string F=10 !T的值为TRUE select case (mesg) case (WM_COMMAND) select case(LOWORD(wParam)) case(IDOK) logresult=DestroyWindow(hdWnd) DialogFunc=T RETURN case(IDCANCEL) logresult=DestroyWindow(hdWnd) DialogFunc=T RETURN case(IDC_LIST1) if(HIWORD(wParam)==LBN_DBLCLK)THEN i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_GETCURSEL,0,0) write(string,"(\'你已经选择了第\',I3,\'项!\')")i i=MessageBox(hdWnd,string,"提示框",MB_OK) ENDIF DialogFunc=T RETURN case(IDC_SELECT) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_GETCURSEL,0,0) if(i==LB_ERR)THEN write(string,"(\'你没有作出选择!\')") else write(string,"(\'你已经选择了第\',I3,\'项!\')")i endif i=MessageBox(hdWnd,string,"提示框",MB_OK) DialogFunc=T RETURN case(IDC_EDITOK) i=GetDlgItemText(hdWnd,IDC_EDIT,string,100) i=MessageBox(hdWnd,string,"你输入的内容为:",MB_OK) DialogFunc=T RETURN end select case(WM_INITDIALOG) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_ADDSTRING,0,LOC("计算机"C)) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_ADDSTRING,0,LOC("物 理"C)) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_ADDSTRING,0,LOC("数 学"C)) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_ADDSTRING,0,LOC("语 文"C)) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_ADDSTRING,0,LOC("英 语"C)) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_ADDSTRING,0,LOC("历 史"C)) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_ADDSTRING,0,LOC("地 理"C)) i=SendDlgItemMessage(hdWnd,IDC_LIST1,LB_ADDSTRING,0,LOC("生 物"C)) DialogFunc=T RETURN end select DialogFunc=F RETURN end 4.用图形界面库XFT 对于习惯只用fortran编程,不会也没有时间学习VC, VB等进行界面变成的朋友,这里有一个十分好的用fortran编写界面的库XFT,其主页在http://www.xeffort.com/xeffort/home.htm ; 大概看了一下这一部分,基本上还是API的模式,个人觉得(探讨)。 5.用FORTRAN95的Windows编程接口Winteracter |