Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
golangでマンデンブロ集合の エモい?gif画像作成を高速化する
Search
t0w4
July 09, 2018
190
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
golangでマンデンブロ集合の エモい?gif画像作成を高速化する
t0w4
July 09, 2018
More Decks by t0w4
See All by t0w4
RubyをRubyらしく書く!
t0w4
0
59
Featured
See All Featured
The browser strikes back
jonoalderson
0
1.8k
Site-Speed That Sticks
csswizardry
13
1.6k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Prompt Engineering for Job Search
mfonobong
0
520
Navigating Weather and Climate Data
rabernat
0
560
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
780
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
Paper Plane (Part 1)
katiecoart
PRO
2
12k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Transcript
HPMBOHͰϚϯσϯϒϩू߹ͷ ΤϞ͍ HJGը૾࡞ΛߴԽ͢Δ
ࣗݾհ IUUQTHJUIVCDPNUX ࣄීஈSBJMTΛͬͯϚΠΫϩαʔϏεͷҰ෦Λ ͔͔ͤͤ։ൃ͍ͯ͠·͢ ࣌ʑ1ZUIPO (Pྺϲ݄ͪΐ͍ d
എܠ ɾϓϩάϥϛϯάݴޠ(PΛಡΈਐΊΔաఔͰϚϯσϯϒϧू߹ͷ ը૾Λ࡞͢ΔνϡʔτϦΞϧΛߦ͏ ҾʹΑΓܗ͕มΘΔ ɻ ɾHJGը૾ͷ࡞ํ๏ΛֶͿɻ Ϛϯσϯϒϧू߹ͷมԽΛHJGͰݟͨ͘ͳΔ /FX ͜Ε ͜ΜͳΜ
࡞ͬͯݟͨ 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 }
݁Ռ ˢ1%'൛ͷࢿྉͰಈ͖·ͤΜ
݁Ռ ͍͍ײ͡ʹಈ͍͍ͯΔʂʂײಈ
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͢Δ͜ͱʹΑΓੜͰ͖Δɻ
݁Ռ ͡Ό͋HJGը૾Λ࡞͢Δͷʹ ͲΕ͚͔͔ͩΔͷ͔ɾɾɾ
݁Ռ HJGը૾͕ੜ͞ΕΔ·Ͱʹ͔͔ͬͨ࣌ؒ NT UJNFͰͷࢉग़
݁Ռ ͷ͍͘͢͝ ମײ
ݪҼ 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Ͱωετ͞Εͨྻͳը૾ͷͷϓϩοτ
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Λ͑ૣ͘ͳΔͷͰʁ
վળ 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ʹΑΔฒߦԽ ฒྻͰͳ͍
վળ 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͕ద༻͍͢͠ʂʂʂ
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ͷऴྃΛͭ վળ
վળ 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ͷ֎ʹॻ͘ඞཁ͕͋Δɻ
վળ ࠷ऴతͳHPSVUJOFద༻ޙͷ
HJGը૾͕ੜ͞ΕΔ·Ͱʹ͔͔ͬͨ࣌ؒ UJNFͰͷࢉग़ CFGPSF NT BGUFS NT վળͦͷ
Λେ෯ʹվળ CFGPSF NT BGUFS NT վળͦͷ
༨ஊ 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) } ESBXGPSͬͯΔ͠ɺͬͪ͜HPSPVUJOFͰ ߴͰ͖Δ͠ΐʁ
༨ஊ݁Ռ HPSPVUJOFԽͰ͖ͨɺɺɺ݁Ռಉ͡ɺɺɺ Ͱૣ͘ͳΒͣɻɻ ˠͲ͏ʹ͔͜͏ʹ͔ૣ͘͠Α͏ͱͯ͢͠Δ ɹҰʹૣ͘ͳΒͣɺɺɺ ˠఘΊΔ
ɾॱংΛߟྀ͢Δඞཁͷͳ͍ॲཧΛฒߦʹHPSPVUJOFԽ͢Δͱ વ શମͷॲཧ͕࣌ؒૣ͘ͳΔ ɾݸਓతʹࢥ͏HPSPVUJOFΛదԠ͢Δ·ͰͷྲྀΕ ۪ʹॲཧΛॻ͘ɻ HPSPVUJOFΛదԠ͍͢͠Α͏ϦϑΝΫλϦϯά͢Δɻ ͜ͷࡍॲཧ͕ؔɺϝιουͱͯ͠Γग़ͤΔͱHPSPVUJOF ʹ͍͢͠ HPSPVUJOFԽ͢Δ
݁
࠷ॳ͔ΒHPSPVUJOF͋Γ͖ͰίʔσΟϯά͢ΔΑΓɺ ී௨ʹίʔσΟϯάͨ͠ޙʹϦϑΝΫλϦϯά͠ɺ Ͳͷ෦Ͱ͋ΕHPSPVUJOFͱͯ͠Γग़ͤΔ͔ɺɺ Ͳͷ෦Ͱ͋Εฒߦʹ࣮ߦͯ݁͠ՌʹӨڹ͕ग़ͳ͍͔ɺ ͱ͍͏෩ʹߟ͑ͨ΄͏͕HPSPVUJOFΛద༻͍͢͠ɻ ײ
HPSPVUJOFΛ༻͢Εૣ͘ͳΔɺɺ ͨͩ͠ͳΜͰ͔ΜͰద༻͢Ε͍͍ͯΜ͡Όͳ͍ɻ ˞ݸਓͷײͰ͋Γɺ࣮ྗʹΑΓ·͢ɻ ͓·͚
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠