フルカラーのマンデルブロ集合の描画
Go 「プログラミング言語Go」の練習問題3.5である、フルカラーの マンデルブロ集合(Mandelbrot set) を描画するプログラムを作成しました。元のプログラムで使われているcolor.Gray
同様、color.RGBA
型も引数がuint8
なので、uint8
型のインデックスでループをしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ // このプログラムは Alan A. A. Donovan & Brian W. Kernighan による gopl.io/ch3/mandelbrot を // 改変したものです。 // Exercise 3.5 (p.69) // $ go run main.go > a.png // Mandelbrot emits a PNG image of the Mandelbrot fractal. package main import ( "image" "image/color" "image/png" "math/cmplx" "os" ) func main() { const ( xmin, ymin, xmax, ymax = -2, -2, +2, +2 width, height = 1024, 1024 ) img := image.NewRGBA(image.Rect(0, 0, width, height)) for py := 0; py < height; py++ { y := float64(py)/height*(ymax-ymin) + ymin for px := 0; px < width; px++ { x := float64(px)/width*(xmax-xmin) + xmin z := complex(x, y) // Image point (px, py) represents complex value z. img.Set(px, py, mandelbrot(z)) } } png.Encode(os.Stdout, img) // NOTE: ignoring errors } func mandelbrot(z complex128) color.Color { const contrast = 17 const iterations = 255 / contrast var v complex128 var ncolor1, ncolor2 *uint8 for i := 0; i <= 2; i++ { var nred, ngreen, nblue uint8 switch i { case 0: ncolor1 = &nblue ncolor2 = &ngreen case 1: ncolor1 = &ngreen ncolor2 = &nred case 2: ncolor1 = &nred ncolor2 = &nblue } for n := uint8(0); n <= iterations; n++ { nc := n * contrast *ncolor1 = 255 - nc *ncolor2 = nc v = v*v + z if cmplx.Abs(v) > 2 { return color.RGBA{nred, ngreen, nblue, 255} } } } return color.Black } |
ここで、元のプログラムのmandelbrot関数の部分を見てみてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func mandelbrot(z complex128) color.Color { const iterations = 200 const contrast = 15 var v complex128 for n := uint8(0); n < iterations; n++ { v = v*v + z if cmplx.Abs(v) > 2 { return color.Gray{255 - contrast*n} } } return color.Black } |
ループの数値を見るとわかるように、255 - contrast*n
の部分がオーバーフローしています。しかし、uint8
に収まらない上位ビットは自動的に破棄されますので、何の処理をする必要もなく、color.Gray
の色は白から黒に変化した後、また白から黒へと変化します。
今回作成したプログラムでは、フルカラーを使っていますので、オーバーフローは発生していません。
参考文献
- 「プログラミング言語Go」 Alan A.A. Donovan (著), Brian W. Kernighan (著), 柴田 芳樹 (翻訳)