fortran绘图、界面功能简介(转载)

对于fortran的绘图、界面功能,我仅仅做一个简单的罗列,这样方便大家的讨论:
                        

1.利用fortran的扩充函数绘图,下面是一个简单的例子,是编程爱好者 -- 中文编程开发类门户网站 -- ProgramFan.com上面有人贴出的;


                        

         Visual Fortran中有提供绘图功能。Visual Fortran的绘图功能不完全是以扩充函数的类型存在,使用它的绘图功能必须在选择Project类型时,选择Standard Graphics或QuickWin模式。


                        

Visual Fortran的QuickWin及Standard Graphics模式在简单的绘图使用上会比较方便,它的绘图函数功能比较多样,不过效率会比较差,而且不支持动画功能。


                        

         Standard
Graphics和QuickWin模式在绘图方面的使用方法完全相同,它们都是调用相同的函数来绘图。差别在于Standard
Graphics只能打开一个窗口来绘图、QuickWin模式则可以打开多个窗口来绘图。QuickWin模式下可以有菜单及对话窗的功
能,Standard Graphics则不行。Standard
Graphics模式的程序代码可以原封不动直接转换到QuickWin模式下使用,但是QuickWin的程序代码并不一定可以直接拿到
Standard Graphics模式下使用。


                        

         
下面这个程序会在屏幕上画出一条斜线、一个方形及一个椭圆。编译程序时,请选择Fortran Standard Graphics or
QuickWin Application这个模式。这个程序可以在Standard
Graphics或QuickWin模式下使用。打开好Project后,再把下面的程序加入Project中来编译。


                        

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值可以用
来设定是要画出一个实心方形或是只有外框而已。在范例中把control的值用$GFILLINTERIOR来代入,表示要画实
心。$GFILLINTERIOR定义在MODULE DFLIB里面。


                        

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分辨率的大小来打开绘图窗口。程序执行后只能够看到窗口的一小部
分,读者可以试着按下Alt+Enter来把窗口放大成全屏幕大小,不然看不到全部的图形。使用QuickWin模式时,并不像使用SGL时一样可以得到
窗口大小改变的信息,所以QuickWin下的虚拟坐标是对固定分辨率来对应,不会随着窗口大小改变而缩放图形。


                        

把这个程序中新使用的绘图函数做一个介绍


                        

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
bytes的空间来做记录。但是FORTRAN中通常一个整数使用4
bytes的空间来做记录,如果分别使用3个变量来记录一个颜色值会很浪费空间,因为这3个变量都只会使用到最低的8个位,其它地方都不会使用。


                        

这个函数可以重新组合R G
B这三个传入的整数,取出这三个整数中最低8个位的数值,把它重新安排到返回值color中。color中的第0~7 bits用存放原本的R,8~15
bits会存放原本的G,16~23 bits会存放原本的B,剩下第24~31 bits的空间则不会使用。


                        

integer(2)  SetColorRGB( color )


                        

用RGB方法来设定颜色,参数color中的第0~7个bits用来设定红光,第8~15
bits用来设定绿光,第16~23
bits用来设定蓝光,其它位不使用。在范例当中曾使用SetColorRGB(#FF0000)来设定颜色,在Visual
Fortran中以#符号开头的数字,代表一个16进制的数字。


                        

16进制数值在0~9时和10进制数字相同,但是接在9下面的数字为A、B、C、D、E、F。其
中A等于10进制的10,B=11,C=12.....,同理可推得1016=16,FF16=255。使用16进制的系统可以比较容易来操作这种需要控
制到位内容的数值。正规的FORTRAN
90写法应该用Z”FF0000”来设定16进制的数值,第5章的最后一节有介绍这个方法。在此顺便范例一下Visual Fortran的扩充语法。


                        

2.利用科学绘图软件包PLPlot、PGPLOT等


                        

PLplot是一个用于多种编程语言(C,
C++, Fortran, Java, Python, Perl etc.)的跨平台(Unix, Linux, Dos, Windows,
Mac OS, OS/2 etc.)的科学绘图程序包,完全免费,源代码开放。如果你用ABSoft Pro
Fortran,该程序包已经包括在内。如果你用别的平台,你可以用这些源代码建立自己的库文件。


                        

PLplot Home Page - Main


                        

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 ;
。该库封装了用于界面编程的windows API函数,包括XFTFile(文件处理), XFTGDI(图形设备接口), XFTWND(窗口),
XFTReg(注册表), XFTMDI(多文档界面), XFTMenu(菜单), XFTCtrl(控制条), XFTApp(应用程序),
XFTDialog(对话框)。所有的程序均为free的,源程序open,有详细的文档。(来自SIMWE)


                        

大概看了一下这一部分,基本上还是API的模式,个人觉得(探讨)。


                        

5.用FORTRAN95的Windows编程接口Winteracter


                        

Winteracter - The Fortran GUI Toolset

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weiyiwen1982

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值