Upgrade to Pro — share decks privately, control downloads, hide ads and more …

golangでマンデンブロ集合の エモい?gif画像作成を高速化する

Avatar for t0w4 t0w4
July 09, 2018
190

golangでマンデンブロ集合の エモい?gif画像作成を高速化する

Avatar for t0w4

t0w4

July 09, 2018

Transcript

  1. ࡞ͬͯݟͨ var powArg float64 func init() { flag.Float64Var(&powArg,"pow", 2.0, "ext)

    ./go-gifmandelbrot -pow=2.0") } func main() { flag.Parse() anim := gif.GIF{LoopCount: nframes} for pow := 1.0; pow < powArg; pow += 0.02 { draw(&anim, pow) } f, _ := os.OpenFile("out.gif", os.O_WRONLY|os.O_CREATE, 0600) defer f.Close() gif.EncodeAll(f, &anim) } func draw(anim *gif.GIF, pow float64) { rect := image.Rect(0, 0, width, height) img := image.NewPaletted(rect, palette) 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) // ը૾ͷ఺(px, py)͸ෳૉ਺஋zΛද͍ͯ͠Δɻ img.Set(px, py, mandelbrot(z, pow)) } } anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } func mandelbrot(z complex128, pow float64) color.Color { const iterations = 200 const contrast = 15 var v complex128 = 0 for n := uint8(0); n < iterations; n++ { v = cmplx.Pow(v, complex(pow, 0)) + z if cmplx.Abs(v) > 2 { return color.Gray{Y: 255 - contrast*n} } } return color.Black }
  2. HPʹஔ͚ΔHJGը૾ͷ࡞Γํ func main() { flag.Parse() anim := gif.GIF{LoopCount: nframes} for

    pow := 1.0; pow < powArg; pow += 0.02 { draw(&anim, pow) } f, _ := os.OpenFile("out.gif", os.O_WRONLY|os.O_CREATE, 0600) defer f.Close() gif.EncodeAll(f, &anim) } func draw(anim *gif.GIF, pow float64) { rect := image.Rect(0, 0, width, height) img := image.NewPaletted(rect, palette) (ུ) anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } (*'*NBHFʹ JNBHF1MBUUFEΛBQQFOE͍͖ͯ͠ &ODPEF"MM͢Δ͜ͱʹΑΓੜ੒Ͱ͖Δɻ
  3. ݪҼ func draw(anim *gif.GIF, pow float64) { rect := image.Rect(0,

    0, width, height) img := image.NewPaletted(rect, palette) 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) // ը૾ͷ఺(px, py)͸ෳૉ਺஋zΛද͍ͯ͠Δɻ img.Set(px, py, mandelbrot(z, pow)) } } anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } GPSͰωετ͞Εͨ௚ྻͳը૾ͷ఺ͷϓϩοτ
  4. func draw(anim *gif.GIF, pow float64) { rect := image.Rect(0, 0,

    width, height) img := image.NewPaletted(rect, palette) 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) // ը૾ͷ఺(px, py)͸ෳૉ਺஋zΛද͍ͯ͠Δɻ img.Set(px, py, mandelbrot(z, pow)) } } anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } HPSPVUJOFΛ࢖͑͹ૣ͘ͳΔͷͰ͸ʁ
  5. վળ func draw(anim *gif.GIF, pow float64) { rect := image.Rect(0,

    0, width, height) img := image.NewPaletted(rect, palette) var wg sync.WaitGroup for py := 0; py < height; py++ { for px := 0; px < width; px++ { x := px y := py wg.Add(1) go func() { plot(img, x, y, pow) wg.Done() }() } } wg.Wait() anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } func plot(img *image.Paletted, px int, py int, pow float64) { y := float64(py)/height*(ymax-ymin) + ymin x := float64(px)/width*(xmax-xmin) + xmin z := complex(x, y) // ը૾ͷ఺(px, py)͸ෳૉ਺஋zΛද͍ͯ͠Δɻ img.Set(px, py, mandelbrot(z, pow)) } HPSPVUJOFʹΑΔฒߦԽ ฒྻͰ͸ͳ͍
  6. վળ func draw(anim *gif.GIF, pow float64) { (ུ) var wg

    sync.WaitGroup for py := 0; py < height; py++ { for px := 0; px < width; px++ { x := px y := py wg.Add(1) go func() { plot(img, x, y, pow) wg.Done() }() } } wg.Wait() (ུ) } func plot(img *image.Paletted, px int, py int, pow float64) { (ུ) // ը૾ͷ఺(px, py)͸ෳૉ਺஋zΛද͍ͯ͠Δɻ img.Set(px, py, mandelbrot(z, pow)) } JNH4FU ʜ ͸GPSͷ֤MPPQͰผͷ࠲ඪͷ఺Λϓϩοτ͍ͯ͠Δ ֤఺ͷϓϩοτॱংʹӨڹ͞Εͳ͍ HPSPVUJOF͕ద༻͠΍͍͢ʂʂʂ
  7. func draw(anim *gif.GIF, pow float64) { (ུ) var wg sync.WaitGroup

    for py := 0; py < height; py++ { for px := 0; px < width; px++ { x := px y := py wg.Add(1) go func() { plot(img, x, y, pow) wg.Done() }() } } wg.Wait() (ུ) } func plot(img *image.Paletted, px int, py int, pow float64) { (ུ) // ը૾ͷ఺(px, py)͸ෳૉ਺஋zΛද͍ͯ͠Δɻ img.Set(px, py, mandelbrot(z, pow)) } શͯͷ֤఺ͷϓϩοτॲཧͷHPSPVUJOF͕શͯऴྃ͢ΔͷΛ ଴ͨͳ͍ͱ͍͚ͳ͍ TZOD8BJU(SPVQΛ࢖ͬͯશHPSPVUJOFͷऴྃΛ଴ͭ վળ
  8. վળ func draw(anim *gif.GIF, pow float64) { (ུ) var wg

    sync.WaitGroup for py := 0; py < height; py++ { for px := 0; px < width; px++ { x := px y := py wg.Add(1) go func() { plot(img, x, y, pow) wg.Done() }() } } wg.Wait() (ུ) } func plot(img *image.Paletted, px int, py int, pow float64) { (ུ) // ը૾ͷ఺(px, py)͸ෳૉ਺஋zΛද͍ͯ͠Δɻ img.Set(px, py, mandelbrot(z, pow)) } XH"EE  ͸HPSPVUJOFͷ֎ʹॻ͘ඞཁ͕͋Δɻ
  9. ༨ஊ func main() { flag.Parse() anim := gif.GIF{LoopCount: nframes} for

    pow := 1.0; pow < powArg; pow += 0.02 { draw(&anim, pow) } f, _ := os.OpenFile("out.gif", os.O_WRONLY|os.O_CREATE, 0600) defer f.Close() gif.EncodeAll(f, &anim) } func draw(anim *gif.GIF, pow float64) { rect := image.Rect(0, 0, width, height) img := image.NewPaletted(rect, palette) (ུ) anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } ESBX΋GPS࢖ͬͯΔ͠ɺͬͪ͜΋HPSPVUJOFͰ ߴ଎Ͱ͖Δ͠ΐʁ