LoginSignup
0
1

More than 5 years have passed since last update.

SVG プロット golang 本 丸写しw

Last updated at Posted at 2017-09-24

SVG プロットプログラム移植

『プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES) Alan A.A. Donovan and Brian W. Kernighan』をパラパラと開いて見たら、きれいな三次元プロットの絵があって、ライブラリ無しで SVG ファイルを書き出しているようなので、移植してみることにしました。

Goの本を買う気は全くありませんが、多分ネット上にサンプルは落ちているだろうと、探したらありました。ビバ!ネット時代!郷ひろみ!僕たち男の子!

https://github.com/golang/go/wiki/Books
https://github.com/adonovan/gopl.io/blob/master/ch3/surface/main.go

実行結果

golang.png

SVG ファイルの冒頭部分

<svg xmlns='http://www.w3.org/2000/svg' style='stroke: grey; fill: white; stroke-width: 0.7' width=  600 height=  320>
<polygon points="  302.5981,    6.4081  300.0000,    5.7653  297.4019,    6.4081  300.0000,    7.2564"/>
<polygon points="  300.0000,    7.2564  297.4019,    6.4081  294.8038,    7.2673  297.4019,    8.3568"/>
<polygon points="  297.4019,    8.3568  294.8038,    7.2673  292.2058,    8.3682  294.8038,    9.7242"/>
<polygon points="  294.8038,    9.7242  292.2058,    8.3682  289.6077,    9.7246  292.2058,   11.3613"/>

プログラム

fortran では x,y = func(i, j) 的な左辺の書き方が許されないので、座標の派生型を定義しました。またインデックスは万世一系の我が国にふさわしく1始まりにしました。

go言語は出力のフォーマット指定が C 言語風で分かりにくく、少し戸惑いました。

!   Port from "The Go Programming Language"  chap. 3 
!
!  original : https://github.com/adonovan/gopl.io/blob/master/ch3/surface/main.go
!  // Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
!  // License: https://creativecommons.org/licenses/by-nc-sa/4.0/  
!
    module m_svg
      implicit none
      real, parameter :: pi = 4.0 * atan(1.0) 
      real, parameter :: sin30 = sin(pi / 6.0), cos30 = cos(pi / 6.0)
      integer, parameter :: nwidth = 600, nheight = 320 ! canvas size in pixels
      integer, parameter :: ncells = 100                ! number of grid cells
      real, parameter :: xyrange = 30.0                 ! axis range (-xyrange .. +xyrange) 
      real, parameter :: xyscale = nwidth / 2 / xyrange ! pixels per x or y unit
      real, parameter :: zscale  = nheight * 0.4        ! pixels per z unit
 !
      type :: t_xy
        real :: x, y
      end type  
    contains
      type(t_xy) function corner(i, j) ! Find point (x,y) at corner of cell (i,j).
        integer, intent(in) :: i, j  
        real :: x, y, r, z
        x = xyrange * (real(i) / ncells - 0.5)
        y = xyrange * (real(j) / ncells - 0.5)
        r = hypot(x, y)
        z = sin(r) / r
        corner%x = nwidth  / 2 + (x - y) * cos30 * xyscale
        corner%y = nheight / 2 + (x + y) * sin30 * xyscale - z * zscale
      end function corner
    end module m_svg

    program SVG
      use m_svg
      implicit none
      integer, parameter :: iw = 11
      integer :: i, j
      type(t_xy) :: a, b, c, d
      open(11, file = 'SVG.html')
      write(iw, '(a, i5, a, i5, a)') "<svg xmlns='http://www.w3.org/2000/svg' " // &
                       "style='stroke: grey; fill: white; stroke-width: 0.7' " // &
                       "width=", nwidth, " height=", nheight, ">"
      do i = 1, ncells
        do j = 1, ncells 
          a = corner(i    , j - 1)
          b = corner(i - 1, j - 1)
          c = corner(i - 1, j    )
          d = corner(i    , j    )
          write(iw, '(a, 4(f10.4, ",", f10.4), a)') '<polygon points="', a, b, c, d, '"/>'
        end do
      end do     
      write(iw, '(a)') "</svg>"
    end program SVG
0
1
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
1