LoginSignup
0
0

More than 5 years have passed since last update.

「プログラムでシダを描画する」を Chapel でシダ植物

Last updated at Posted at 2014-10-01

Chapel でシダ植物

秋も深まってまいりましたがまだシダ植物をやります。

Cray の HPC 用言語 Chapel でシダ植物を描いてみました。基本的に Fortran 版の移植です。

実行結果

fern.png

プログラム

乱数のモジュールの使い方がイマイチよく分からないのですが、配列に出力させると第一要素が全然乱数になっていなくて、0.9 以上の数ばかり出力されるので、二要素出力させています。

module m_bmp {
  record t_bmp_file_header {
    var bfType      : int(16) = 19778; //"BM"
    var bfSize      : int(32);
    var bfReserved1 : int(16) = 0;
    var bfReserved2 : int(16) = 0;
    var bfOffBits   : int(32);
  }

  record t_bmp_info_header {
    var biSize          : int(32) = 40; // Z'28'
    var biWidth         : int(32);
    var biHeight        : int(32);
    var biPlanes        : int(16) = 1;  // always 1
    var biBitCount      : int(16);
    var biCompression   : int(32) = 0;  // 0:nocompression 
    var biSizeImage     : int(32);
    var biXPelsPerMeter : int(32) = 3780; // 96 dpi
    var biYPelsPerMeter : int(32) = 3780; // 96 dpi
    var biClrUsed       : int(32) = 0;
    var biClrImportant  : int(32) = 0; 
  }

  record t_rgb {
    var b, g, r : uint(8);
  }

  class t_bmp {
    var D: domain(2);
    var file_header: t_bmp_file_header;
    var info_header: t_bmp_info_header;
    var rgb: [D] t_rgb; 

    proc wr(fn:string) {
      var f = open(fn, iomode.cw);
      var w = f.writer(kind=ionative);
      var nx: int(32) = this.D.high(1):int(32);
      var ny: int(32) = this.D.high(2):int(32);

      this.file_header.bfSize      = 14 + 40 + 0 + nx * ny * 3;
      this.file_header.bfOffBits   = 14 + 40;
      this.info_header.biWidth     = nx;
      this.info_header.biHeight    = ny;
      this.info_header.biBitCount  = 24;
      this.info_header.biSizeImage = nx * ny * 3;

      w.write(this.file_header.bfType         );
      w.write(this.file_header.bfSize         );
      w.write(this.file_header.bfReserved1    );
      w.write(this.file_header.bfReserved2    );
      w.write(this.file_header.bfOffBits      );

      w.write(this.info_header.biSize         );
      w.write(this.info_header.biWidth        );
      w.write(this.info_header.biHeight       );
      w.write(this.info_header.biPlanes       );
      w.write(this.info_header.biBitCount     );
      w.write(this.info_header.biCompression  );
      w.write(this.info_header.biSizeImage    );
      w.write(this.info_header.biXPelsPerMeter);
      w.write(this.info_header.biYPelsPerMeter);
      w.write(this.info_header.biClrUsed      );
      w.write(this.info_header.biClrImportant );

      for j in D.dim(2) do
        for i in D.dim(1) do
          w.write(this.rgb(i, j).b, this.rgb(i, j).g, this.rgb(i, j).r);
      w.close();  
    }

    proc point(x, y) {
       var ix: int = x:int, iy: int = y:int;
       this.rgb(x:int, iy + 1).g = 255:uint(8);
    }
  }
}

module fern {
  use Random;
  use m_bmp;

  config const n: int = 20, nx: int = 500, ny: int = 500;
  const D = {1..nx, 1..ny};
  var bmp = new t_bmp(D);

  proc w1x(x, y) return  0.836 * x + 0.044 * y        ;
  proc w1y(x, y) return -0.044 * x + 0.836 * y + 0.169;
  proc w2x(x, y) return -0.141 * x + 0.302 * y        ;
  proc w2y(x, y) return  0.302 * x + 0.141 * y + 0.127;
  proc w3x(x, y) return  0.141 * x - 0.302 * y        ;
  proc w3y(x, y) return  0.302 * x + 0.141 * y + 0.169;
  proc w4x(x, y) return  0.0                          ;
  proc w4y(x, y) return              0.175 * y        ;

  proc f(k:int, x, y) {
    var r: [1..2] real;
    if (k > 0) {
      f(k - 1, w1x(x, y), w1y(x, y));
      fillRandom(r);
      if r(2) < 0.3 then f(k - 1, w2x(x, y), w2y(x, y));
      fillRandom(r);
      if r(2) < 0.3 then f(k - 1, w3x(x, y), w3y(x, y));
      fillRandom(r);
      if r(2) < 0.3 then f(k - 1, w4x(x, y), w4y(x, y));
    }
    else
      bmp.point(x * nx * 0.98 + 0.5 * nx, y * ny * 0.98);
    }

  proc main() {
    f(n, 0.0, 0.0);    
    bmp.wr("fern.bmp"); 
  }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0