返回列表 回复 发帖

UF难题三度征解

整理精简代码,抽出代码如下:
hilbert-curve {

init:
  float x=0.0
  float y=0.0
  float r=0.0
  float rmin=1e20
  float u=0.0
  float v=0.0
  float msb=0.0
  t=(0,0)
  int iter=0
  int nlast=0
  int n=0
  int fac3=0
  int fac4=0
  int power4=0
  zh=(0,0)
  zh0=(0,0)
;
; set up endpoints for the lines
;
  float h=@fourcorners
  float ooh=1/h
  float ooomh=1/(1-h)
  float hoomh=h/(1-h)
  z0a=@enterexit*h
  z0b=flip(@enterexit*h)
  x=real(@centerll)*h
  y=imag(@centerll)*h
  z1=x+flip(y)
  x=real(@centerul)*h
  y=imag(@centerul)*(1-h)+h
  z2=x+flip(y)
  x=real(@centerur)*(1-h)+h
  y=imag(@centerur)*(1-h)+h
  z3=x+flip(y)
  x=real(@centerlr)*(1-h)+h
  y=imag(@centerlr)*h
  z4=x+flip(y)
  z5=1+flip(@enterexit*h)
loop:
final:
  iter=0
  zh0=#z*0.25+(0.5,0.5)
  zh=zh0
  while(iter<@niter)
    iter=iter+1
    x=real(zh)
    y=imag(zh)
;
; lower left sub-square:  shrink, flip horizontally, rotate by -90 degrees
;
    if((x<h)&&(y<h))
      nlast=3
      u=ooh*y
      v=ooh*x
;
; upper left sub-square:  just shrink
;
    elseif((x<h)&&(y>=h))
      nlast=2
      u=ooh*x
      v=ooomh*y-hoomh
;
; upper right sub-square:  shrink & flip horizontally
;
    elseif((x>=h)&&(y>=h))
      nlast=1
      u=ooomh-ooomh*x
      v=ooomh*y-hoomh
;
; lower right sub-square:  shrink, rotate by 90 degrees
;
    elseif((x>=h)&&(y<h))
      nlast=4
      u=ooh*y
      v=ooomh-ooomh*x
    else
      nlast=-1
      u=x
      v=y
    endif
    zh=u+flip(v)
    msb=(msb+nlast-1)/4
    n=n*4+nlast-1
  endwhile
  if(n<0)
    #solid=true
  else
                ; distance to curve
;
; determine how to start line 0-1
;
    z0=z0a
    iter=0
    fac3=2
    fac4=1
    power4=4
    while(iter<@niter)
      iter=iter+1
      if(iter%2==1)
        if(n%power4==fac3)
          z0=z0b
        endif
      else
        if(n%power4==fac3)
          z0=z0a
        endif
      endif
      power4=4*power4
      fac4=4*fac4
      fac3=fac3+2*fac4
    endwhile
;
; line from enter to lower left sub-square
;
    t=(zh-z0)/(z1-z0)
    x=real(t)
    y=imag(t)
    if(x<0.0)
      r=sqr(x)+sqr(y)
    elseif(x>1.0)
      r=sqr(x-1.0)+sqr(y)
    else
      r=sqr(y)
    endif
    r=sqrt(r)*cabs(z1-z0)
    if(r<rmin)
      rmin=r
    endif
;
; line from lower left to upper left sub-squares
;
    t=(zh-z1)/(z2-z1)
    x=real(t)
    y=imag(t)
    if(x<0.0)
      r=sqr(x)+sqr(y)
    elseif(x>1.0)
      r=sqr(x-1.0)+sqr(y)
    else
      r=sqr(y)
    endif
    r=sqrt(r)*cabs(z2-z1)
    if(r<rmin)
      rmin=r
    endif
;
; line from upper left to upper right sub-squares
;
    t=(zh-z2)/(z3-z2)
    x=real(t)
    y=imag(t)
    if(x<0.0)
      r=sqr(x)+sqr(y)
    elseif(x>1.0)
      r=sqr(x-1.0)+sqr(y)
    else
      r=sqr(y)
    endif
    r=sqrt(r)*cabs(z3-z2)
    if(r<rmin)
      rmin=r
    endif
;
; line from upper right to lower right sub-squares
;
    t=(zh-z3)/(z4-z3)
    x=real(t)
    y=imag(t)
    if(x<0.0)
      r=sqr(x)+sqr(y)
    elseif(x>1.0)
      r=sqr(x-1.0)+sqr(y)
    else
      r=sqr(y)
    endif
    r=sqrt(r)*cabs(z4-z3)
    if(r<rmin)
      rmin=r
    endif
;
; line from lower right sub-square to exit
;
    t=(zh-z4)/(z5-z4)
    x=real(t)
    y=imag(t)
    if(x<0.0)
      r=sqr(x)+sqr(y)
    elseif(x>1.0)
      r=sqr(x-1.0)+sqr(y)
    else
      r=sqr(y)
    endif
    r=sqrt(r)*cabs(z5-z4)
    if(r<rmin)
      rmin=r
    endif
;
      #index=rmin
    endif

default:
  title="Hilbert curve"
  param centerll
    caption="lower left center"
    default=(0.5,0.5)
    hint="Center of the lower left sub-square. Make both coordinates \
    between 0 & 1; use (0.5,0.5) for standard Hilbert curve."
  endparam
  param centerul
    caption="upper left center"
    default=(0.5,0.5)
    hint="Center of the upper left sub-square. Make both coordinates \
    between 0 & 1; use (0.5,0.5) for standard Hilbert curve."
  endparam
  param centerur
    caption="upper right center"
    default=(0.5,0.5)
    hint="Center of the upper right sub-square. Make both coordinates \
    between 0 & 1; use (0.5,0.5) for standard Hilbert curve."
  endparam
  param centerlr
    caption="lower right center"
    default=(0.5,0.5)
    hint="Center of the lower right sub-square. Make both coordinates \
    between 0 & 1; use (0.5,0.5) for standard Hilbert curve."
  endparam
  param enterexit
    caption="enter/exit"
    default=0.5
    min=0.0
    max=1.0
    hint="Where the curve enters and exits the block of 4 sub-squares. \
      Between 0 & 1; use 0.5 for standard Hilbert curve."
  endparam
  param fourcorners
    caption="4 corners"
    default=0.5
    hint="Where the 4 corners meet.  Between 0 & 1; use 0.5 for standard \
      Hilbert curve."
  endparam
  param niter
    caption="iterations"
    default=0
    min=0
  endparam

}
这整理后的代码,我在UF验证没问题。代码很长,大家带出后,将文件帖在这。
效果图:
Fractal2.png
按常老师的地毯算法,扫一张谢氏地毯:
未命名.jpg
谢氏地毯.gsp (16.09 KB)
搞了几天,整出的图与UF差别实在是大。今晚重新整,扫出的怪异图片:
未命名.JPG
大家有整出的,告知,实在感激不尽。
又重新做一遍,扫得如下图,有些接近了,仍未找到原因何在。
未命名.JPG
应该说能用画板实现,算式太多,看来我要放弃了。
我把较为接近的歪货希尔拍特粘在此,大家查查问题出在那里?
歪货希尔伯特.gsp (53.77 KB)
数据有点多。
我在UF中玩,将程序中的fac4=4*fac4等三句拖出子循环后,发现与我的歪图有点相似,估计是这二句用画板造,迭代时有问题,实不知如何处理。虽说子循环用画板麻烦,以前遇到这种类似子循环,按常规迭代处理也整出与UF完全一样的图。
UF中的这个希尔伯特曲线,实在太迷人并充满了魅力。
已经决定放弃了,有大师整出后,教会我,万分感激。
8# changxde
感谢常老师。我刚才看了你的文件,作的很成功。原来是我处理代码里那两个循环整复杂了,一直在那里转,跳不出思维的定式,转不出来。这个问题得以解决,心情确实高兴。
学习了常老师的文件,重新作了UF中的此分形,干了两三个钟头。扫一幅图片:
未命名.JPG
机理不明,一头雾水。搞分形,手头,网上能收到的信息太少了,好象外国佬创新头脑厉害,分形成了外国人的最高机密。
精解代码:
aug01-hilbert-spline2 {
init:
  float x=0.0
  float y=0.0
  float r=0.0
  float rmin=1e20
  float u=0.0
  float v=0.0
  int iter=0
  int nlast=0
  int n=0
  int fac3=0
  int fac4=0
  int power4=0
  zh=(0,0)
;
; set up endpoints for the lines
;
  float h=0.5
  float ooh=1/h
  float ooomh=1/(1-h)
  float hoomh=h/(1-h)
  z0a=@enterexit
  z0b=flip(@enterexit)
  z1=@centerll
  z2=@centerul
  z3=@centerur
  z4=@centerlr
  z5=1+flip(@enterexit)
loop:
final:
  iter=0
  zh=#z*0.25+(0.5,0.5)
  while(iter<@niter)
    iter=iter+1
    x=real(zh)
    y=imag(zh)
;
; lower left sub-square:  shrink, flip horizontally, rotate by -90 degrees
;
    if((x<h)&&(y<h))
      nlast=3
      u=ooh*y
      v=ooh*x
;
; upper left sub-square:  just shrink
;
    elseif((x<h)&&(y>=h))
      nlast=2
      u=ooh*x
      v=ooomh*y-hoomh
;
; upper right sub-square:  shrink & flip horizontally
;
    elseif((x>=h)&&(y>=h))
      nlast=1
      u=ooomh-ooomh*x
      v=ooomh*y-hoomh
;
; lower right sub-square:  shrink, rotate by 90 degrees
;
    elseif((x>=h)&&(y<h))
      nlast=4
      u=ooh*y
      v=ooomh-ooomh*x
    else
      nlast=-1
      u=x
      v=y
    endif
    zh=u+flip(v)
    n=n*4+nlast-1
  endwhile
;
; determine how to start line 0-1
;
  z0=z0a

  iter=0
  fac3=2
  fac4=1
  power4=4
  while(iter<@niter)
    iter=iter+1
    if(iter%2==1)
      if(n%power4==fac3)
        z0=z0b

      endif
    else
      if(n%power4==fac3)
        z0=z0a

      endif
    endif
    power4=4*power4
    fac4=4*fac4
    fac3=fac3+2*fac4
  endwhile
;
; spline from enter to lower left sub-square
;
  zz0=z0
  zz2=z1


  zz1=(zz0+zz2)/2

  c=zz0-zh
  b=2*(zz1-zz0)

    root1=-c/b


  x=real(root1)
  y=imag(root1)
  if(x<0.0)
    r=cabs(root1)
  elseif(x>1.0)
    r=cabs(root1-1)
  else
    r=abs(y)
  endif

  if(r<rmin)
    rmin=r
  endif



;
; spline from lower left to upper left sub-square
;
  zz0=z1
  zz2=z2


    zz1=(zz0+zz2)/2

  c=zz0-zh
  b=2*(zz1-zz0)


    root1=-c/b


  x=real(root1)
  y=imag(root1)
  if(x<0.0)
    r=cabs(root1)
  elseif(x>1.0)
    r=cabs(root1-1)
  else
    r=abs(y)
  endif

  if(r<rmin)
    rmin=r
  endif



;
; spline from upper left to upper right sub-square
;
  zz0=z2
  zz2=z3


    zz1=(zz0+zz2)/2

    c=zz0-zh
  b=2*(zz1-zz0)


    root1=-c/b

  x=real(root1)
  y=imag(root1)
  if(x<0.0)
    r=cabs(root1)
  elseif(x>1.0)
    r=cabs(root1-1)
  else
    r=abs(y)
  endif

  if(r<rmin)
    rmin=r
  endif



; spline from upper right to lower right sub-square
;
  zz0=z3
  zz2=z4

    zz1=(zz0+zz2)/2

  c=zz0-zh
  b=2*(zz1-zz0)

    root1=-c/b


  x=real(root1)
  y=imag(root1)
  if(x<0.0)
    r=cabs(root1)
  elseif(x>1.0)
    r=cabs(root1-1)
  else
    r=abs(y)
  endif

  if(r<rmin)
    rmin=r
  endif



; spline from lower right sub-square to exit
;
  zz0=z4
  zz2=z5

    zz1=(zz0+zz2)/2

  c=zz0-zh
  b=2*(zz1-zz0)


    root1=-c/b

  x=real(root1)
  y=imag(root1)
  if(x<0.0)
    r=cabs(root1)
  elseif(x>1.0)
    r=cabs(root1-1)
  else
    r=abs(y)
  endif

  if(r<rmin)
    rmin=r
  endif



;
  #index=rmin
default:
  title="Hilbert spline 2"
  param niter
    caption="iterations"
    default=0
    min=0
  endparam
  param centerll
    caption="lower left center"
    default=(0.25,0.25)
    hint="Center of the lower left sub-square. Make both coordinates \
    between 0 & 1; use (0.25,0.25) for standard Hilbert curve."
  endparam
  param centerul
    caption="upper left center"
    default=(0.25,0.75)
    hint="Center of the upper left sub-square. Make both coordinates \
    between 0 & 1; use (0.25,0.75) for standard Hilbert curve."
  endparam
  param centerur
    caption="upper right center"
    default=(0.75,0.75)
    hint="Center of the upper right sub-square. Make both coordinates \
    between 0 & 1; use (0.75,0.75) for standard Hilbert curve."
  endparam
  param centerlr
    caption="lower right center"
    default=(0.75,0.25)
    hint="Center of the lower right sub-square. Make both coordinates \
    between 0 & 1; use (0.75,0.25) for standard Hilbert curve."
  endparam
  param enterexit
    caption="enter/exit"
    default=0.25
    min=0.0
    max=1.0
    hint="Where the curve enters and exits the block of 4 sub-squares. \
      Between 0 & 1; use 0.25 for standard Hilbert curve."
  endparam


}
返回列表