回 帖 发 新 帖 刷新版面

主题:子程序为什么不返回主程序

program main
implicit none
  real,parameter :: width=120.0,heighth=120.0           !模型大小
  double precision  r                    !种子数
  real :: totarea=0.0                       !多边形的总面积
  real :: area=0.0                       !单个多边形的面积
  real,parameter :: e=0.6                                        !块石含量 
  integer :: number=1                   !记录多边形的编号
  real x(9),y(9)
  integer n,i
  real x0,y0
  
  open(unit=10,file='point.txt')
  write(*,*) "Please input the number of seed!"
  read(*,*) r

  do while(totarea<e*heighth*width)
    call point(r,width,heighth,x,y,n,x0,y0)
    call checkin(x,y,n,width,heighth,r)
    totarea=totarea+area+60.0

  write(10,*) "Number=",number
  do i=1,n+1
    write(10,*) i,x(i),y(i)
  end do
  write(10,*)
  number=number+1
  end do

  close(10)

  stop
end program

!产生多边形的顶点
subroutine point(r,width,heighth,x,y,n,x0,y0)
implicit none
  double precision  r
  real width,heighth
  real,external :: NRND1                            !产生随机数的子程序
  real theta,beta                    !定义N边形的角度和随机旋转的角度
  real,parameter :: pi=3.1415926
  integer :: i=0                                      !循环用
  integer n                                  !多边形边的数目
  real,parameter :: Nmax=8.0,Nmin=3.0               !岩石块的最大,最小边数
  real,parameter :: Bmax=20.0,Bmin=2.0                 !岩石块的最大,最小半径
  real x0,y0                   !岩石块的圆心坐标
  real num                       !存放生成的随机数
  real angle           !顶点的角度
  real lenth           !多边形半径的长
  real x(9),y(9)

  num=NRND1(r)
  n=nint(num*(Nmax-Nmin)+Nmin)           !生成多边形的边的数目
  theta=2*pi/n
  num=NRND1(r)
  x0=num*width               !多边形圆心的x坐标值
  num=NRND1(r)
  y0=num*heighth                   !多边形圆心的y坐标值
  beta=NRND1(r)               !多边形第一条边偏转的角度
  
  do i=1,n
    angle=beta+theta*(i-1)
    num=NRND1(r)
    lenth=num*(Bmax-Bmin)+Bmin               !多边形的半径
    x(i)=x0+lenth*cos(angle)
    y(i)=y0+lenth*sin(angle)
  end do
  x(n+1)=x(1)
  y(n+1)=y(1)
  i=0
return
end subroutine

!产生随机数的子程序        
real function NRND1(R)
double precision S,U,V,R
S=65536.0
U=2053.0
V=13849.0
M=R/S
R=R-M*S
R=U*R+V
M=R/S
R=R-M*S
NRND1=R/S
return
end    function

!判断多边形顶点是否在样本内
subroutine checkin(x,y,n,width,heighth,r)
implicit none
  integer n
  real x(9),y(9)
  real width,heighth
  double precision  r
  real x0,y0
  integer :: i=0

  do i=1,n
    if(x(i)<=0 .or. x(i)>=width)then    
      call point(r,width,heighth,x,y,n,x0,y0)
    end if

    if(y(i)<=0 .or. y(i)>=heighth)then    
      call point(r,width,heighth,x,y,n,x0,y0)
    end if
  end do

return
end subroutine

这个程序在运行的时候,point这个子程序执行之后,应该是返回主程序,但是只执行了一次,第二次时,当运行完point之后,就直接跳到了checkin这个子程序,而且还不是跳到checkin子程序的开头。
希望哪位大侠能帮小弟看看,小弟在此谢过了!

回复列表 (共6个回复)

沙发

正常啊,因为你的checkin也调用了point子程序啊:)

板凳


那有什么方法改进么?这只是程序的一部分,这的意思是,如果生成的这些点不在样本之内,那么将重新调用point程序,重新生成点的坐标!

3 楼

您这程序输入的n最大为9,超过就会越界:)

4 楼


我这个n是控制了的,最大正好是9,是不会越界的!

5 楼

如果n最大正好是9,那么:
  x(n+1)=x(1)
  y(n+1)=y(1)
这两句就越了:)

6 楼

我仔细看了楼主程序,感觉无论从程序本身还是算法都值得商榷。
从程序,我觉得您的问题是:
在 0 < x < length,  0 < y < height 的矩形区域,随机生成多边形(边的数目 3 - 8, 离某个随机生成的中心点也有限制),然后求这些多边形的面积。

我学理论物理,完全不懂楼主所具备的专业基础知识,在此只想就是论事谈谈我对程序的疑惑:

1。 Fortran 标准明确规定了 Random_Number 子程序,所以您可以直接调用。
2。 为何您生成的多边形中心与相邻顶点的夹角都一样呢?这个可不是随机多边形哟。
3。 从您只是求面积来看,我觉得阁下子程序 checkin 过于严格,我觉得(正确)生成的随机多边形只要能被前面所说的矩形区域覆盖即可,中心点可以平移、旋转,这样的抽样也有效。

    个人意见!

我来回复

您尚未登录,请登录后再回复。点此登录或注册