TIM Labs

2013年1月アーカイブ

前回、GHC単独でアニメーションが動くところまでやった。
しかし、おおいなる問題があったのだ。

それは、こんな風に動くのだと言いながら、示したのは静止画だったのだ。
ここは何とか、実際にどのように動くのかを見せねば良くないだろう。

1つの方法はHaskellが直接動くようにして見せることだが、それは大掛かり過ぎる。
もっと、どこからでも、手軽に見える、確認できるようにしたい。
ということで、動いている動画を、アニメーションGIFというファイル形式で録画して見せることにしよう。
アニメーションGIFなら、ほとんどのブラウザで見えるはずだ。

動画をどうやったら録画できるのだろうか、勉強しなくちゃいけない。

ということで、ちょっと調べた。今回は、このあたりの話をする。

使っているパソコンは、Ubuntu/Linuxなのだ。ここには膨大なフリーソフトがつまっている。
何かきっとあるだろう。
実際、いくつかあったのだが、極めて安直にウィンドウの録画ができそうなのを調べたら、

Making a GIF screencast が出てきた。byzanzというソフトがUbuntuにはあり、GIFファイルを吐き出してくれる。ピッタシ!

インストールは、Synapticパッケージマネージャでやったので、説明は省略。ちょっとツンツンしただけだ。

fuji$ byzanz-record --help
Usage:
  byzanz-record [OPTION...] record your current desktop session

Help Options:
  -?, --help               Show help options
  --help-all               Show all help options
  --help-gtk               Show GTK+ Options

Application Options:
  -d, --duration=SECS      Duration of animation (default: 10 seconds)
  --delay=SECS             Delay before start (default: 1 second)
  -l, --loop               Let the animation loop
  -c, --cursor             Record mouse cursor
  -x, --x=PIXEL            X coordinate of rectangle to record
  -y, --y=PIXEL            Y coordinate of rectangle to record
  -w, --width=PIXEL        Width of recording rectangle
  -h, --height=PIXEL       Height of recording rectangle
  -v, --verbose            Be verbose
  --display=DISPLAY        X display to use

ということで早速録画しようとしたのだが、全画面を録画するのは良いのだが、指定したウィンドウだけを録画しようとしたら、録画するウィンドウの位置を指定しないといけないのだった。

ということで、今度は、xwininfo を起動し、Haskell/Glossのアニメーションウィンドウをクリックし、配置を確認した。

fuji$ xwininfo

xwininfo: Please select the window about which you
          would like information by clicking the
          mouse in that window.

xwininfo: Window id: 0x2ebe5b8 (has no name)

  Absolute upper-left X:  10
  Absolute upper-left Y:  10
  Relative upper-left X:  10
  Relative upper-left Y:  10
  Width: 246
  Height: 266
  Depth: 0
  Visual: 0x21
  ..................以下省略

ということで、左上隅が (10,10)で、246x266の部分を録画すればよいことがわかった。

fuji$ byzanz-record -d 60 --delay=0 -x 20 -y 10 -w 246 -h 266  byzanz-record-sample.gif

とやると、リターンキーを押した直後から60秒間録画され、最後に指定したファイルにアニメーションGIFファイルが作られる。

今回試しにつくったのがこれだ。サイズは、300KBと、動きが単純なこともあり、たいして大きくない。



これで、作られたアニメーションがどんなものか見せることができるようになった。

ということで、今日はここまで。



今回、第6週は、今までの復習なので、無視して第7週に進むのだが、ちょっとだけ取り上げることがある。
それは、前回、星条旗の宿題が出たが、これに対して、こんなキーボードをSophiaは描いたのだ。
う?む、まだわずかな知識しかあたえていないのに、こういう絵を作るセンスの良さに感心だ。

keyboard.png
さて、第7週に入る。ここで、やっと絵が動き出すのだ。

ここでも、Haskell+Glossで試せるページ
http://dac4.designacourse.com:8000/sim
が利用されるのだが、ちょっとだけ違う。
今までは、Pictureアイコンをクリックして、ソースを入れるページを出していたのだが、
今度は、Animationアイコンをクリックするのだ。

すると、以下のソースが出てくる。

import Graphics.Gloss

data BallState = BallAt Float Float
initial _           = BallAt 100 0
step t (BallAt x v) = BallAt (x+v*t) (0.99*v-x*t)
draw   (BallAt x v) = translate x x (circle 20)

右下の [Run]ボタンを押すと、円が 右上⇔左下 を往復運動する。動きは徐々に悪くなり、そのうち画面中央に停止する。

ということで、とりあえず、以上のような書き方で、アニメーションができるようなのだ。

さて、授業で教える最初のアニメーションのソースはこれなのだ。
importの行だけを残し、残りを

animation t = rotate (60 * t) (rectangleSolid 100 100)

に置き換えるだけで、一辺100の黒い正方形が、反時計回りにぐるぐる回りつづけるのだ。

今は、ブラウザ上で動いているだけなのだが、これを、Pictureでやったときと同様にGHC単独で動くようにしたいのだ。

そうなると、日本語での説明を無駄に探すより、Graphics.Gloss のちゃんとしたドキュメントを読むべきだ。
このところHaskell関係はバージョンがよく変わっているので要注意である。
探し当てたのが、つぎのドキュメントだ。

gloss-1.7.4.1: Painless 2D vector graphics, animations and simulations

これにより、今までの 関数displayの代わりに、animateを使わないといけないことが分かる。
まず、関数animateの型定義を見てみよう。

Prelude Graphics.Gloss> :t animate
animate :: Display -> Color -> (Float -> Picture) -> IO ()

さらに、Display を調べようとすると、

Prelude Graphics.Gloss> :t Display

<interactive>:1:1: Not in scope: data constructor `Display'
Prelude Graphics.Gloss>

となって、叱られてしまった。
ドキュメントを見ると、Displayは静止画用の関数displayのときと同じということが分かって、一件落着。

以上をまとめて、1つのhsファイルにしてみた。

import Graphics.Gloss

animation t = rotate (60 * t) (rectangleSolid 100 100)

main = animate (InWindow "Animation" (200, 200) (10,10)) white animation

最初はライブラリのインポート、最後はmainの行で、関数animateを使って、アニメーションを実現している。
この最後の関数型の引数の名前を animation にすることで、授業のプログラムとの整合性をとっている。

animation t の定義は、授業と一緒なので、この部分を次々と変更していけば、良いはずだ。

これを動かすと、こんな絵が得られる。

sample13.png
やはり、一辺100の黒い正方形が、時計回りにぐるぐる回りつづけるのだ。

ん、でもおかしい。
Web上のでやったときは、反時計回りだったのに、今度は時計回り、つまり回転方向が逆になってしまった。
なぜだろう。理由が分からないので、今日はここまでとしよう。




今日は、第5週の授業に従って進める。
今回から、アニメーションを目指した勉強になっているのだ。

といっても、いきなり、「こうすればアニメーションできますよ」というような教え方はしていないのだ。

まず、Sophiaという生徒が作った絵と、プログラムが紹介されるのだ。

つぎが、Sophiaのプログラムに、ちょっとだけ手を加えたものだ。

-- elephant written by Sophia
import Graphics.Gloss

elephant angle = pictures [
      rotate (20) (scale 3 2 (translate 30 40 (circleSolid 25))),
      translate 150 (-20) (rectangleSolid 40 80),
      translate (-10) 40 (scale 1.5 1 (circleSolid 80)),
      translate 50 (-50)(rectangleSolid 40 70),
      translate (-60) (-50) (rectangleSolid 40 70),
      translate (-125) 50 (rotate (-angle) (translate 0 20 (rectangleSolid 10 40)))
      ]

picture = elephant 120

main = display (InWindow "Nice Window" (400, 300) (10, 10)) white picture

あちこちに数字が散らばっていて、ちと汚いと思うかもしれないが、とりあえず今はそういうことは考えるのをよそう。
それより、ちょっとだけ教わって、こんな絵を描いてくるところが良いではないか。

picture は、elephant に角度を与えるようになっていて、この例では120が与えられている。

これを動かすと、こんな絵が表示される。

sample10.png
elephant angle となっていて、このangleの数値を変更すると、この像のシッポの角度が変わるのだ。
確かに、シッポを振るとカワイイに違いない。

今は、まだ、1つの静的な絵、つまり指定した角度のシッポの象さんが描かれるだけだ。

では、つぎに、このシッポの動かし方、という風には説明しないのだ。
[Picture] 、つまり絵のリストを作ろうと言うわけだ。
リストは、何も [1,2,3] とか [1,3..100] とかのように数字を並べるだけしか使い道がない訳ではない。
リストの要素は何だって良いのだ。だから、

絵が並んだリストを作ってみよう!

import Graphics.Gloss

picture = pictures circles
circles = [ translate x 0 (circle x) | x <- [ 10, 20 .. 100 ] ]

main = display (InWindow "Nice Window" (500, 300) (10, 10)) white picture

このプログラムの circles は、半径が 10,20..100 の10個のPicture型の円からなるリストである。
そのままでは描けないので、picturesで1つのPictureにまとめ上げた上で描かれている。

sample11.pngそして、もっと複雑で綺麗な形もある。

import Graphics.Gloss

picture = pictures circles
circles = [ rotate angle (translate (5*x) 0 (circle x))
            | x <- [5, 10 .. 30 ], angle <- [ 0, 30 .. 360 ]
    ]

main = display (InWindow "Nice Window" (400, 400) (10, 10)) white picture

sample12.png...というような例がいくつか紹介され、最後に次の課題が示される。

flag.png星が50個も並んでいるのだが、さてどうしますか?




今まで習ったことを使って、簡単な絵を描いてみた。

import Graphics.Gloss

eye     = scale 0.5 1 circles

circles = pictures [
          circleSolid 100,
          translate 50 (-10) (color white (circleSolid 50)),
          translate 65 (-25) (circleSolid 25)
      ]

picture = pictures [
          translate   50  0 (scale (-1) 1 eye),
          translate (-50) 0 eye
      ]

main = display (InWindow "Nice Window" (400, 300) (10, 10)) white picture

sample5.png

さて、今回は3週目の話をしよう。線、多角形などをつくる話だ。

多角形を描くために、polygonが用意されている。

polygon :: Path -> Picture

そして、

type Point = (Float, Float)
type Path = [Point]

となっているので、点を並べるだけで、多角形を描いてくれる。
外周だけを描きたいときは

line :: Path -> Picture

を使うようだ。
授業で出てきたプログラムがこれだ。
ただし、画面サイズ、星の移動量は変更してある。

import Graphics.Gloss

picture = stars

stars = pictures [
    translate ( 100) ( 100) (color blue   star),
    translate (-100) (-100) (color yellow star),
    translate (   0) (   0) (color red    star)
    ]

star = polygon [
    (  0,  50),
    ( 10,  20),
    ( 40,  20),
    ( 20,   0),
    ( 30, -30),
    (  0, -10),
    (-30, -30),
    (-20,   0),
    (-40,  20),
    (-10,  20),
    (  0,  50)
    ]

main = display  (InWindow "Nice Window" (300, 300) (100, 100)) white picture

sample6.png

さて、このプログラムだが、少々変更を加えてみよう。
まず、★を描くとき考えるのは、外周の5頂点をひとつおきに結んで行くことではないだろうか。
それを、lineで描いてみた。

import Graphics.Gloss

picture = line [
    (  0,  50),
    ( 30, -30),
    (-40,  20),
    ( 40,  20),
    (-30, -30),
    (  0,  50)
    ]

main = display  (InWindow "Nice Window" (200, 200) (100, 100)) white picture

sample7.png

ここでは、lineを使っているので線画になっているが、このようにヒネクレた多角形の場合、どのように塗りつぶすであろうか。
そして、polygonの場合、かならず多角形、つまり閉じた形にしてしまうので、最後に最初と同じ位置を並べる必要は無いはず。

ということを考慮に入れて、★を一つだけ描くプログラムを作り直してみた。

import Graphics.Gloss

picture = polygon [
    (  0,  50),
    ( 30, -30),
    (-40,  20),
    ( 40,  20),
    (-30, -30)
    ]

main = display  (InWindow "Nice Window" (200, 200) (100, 100)) white picture

sample8.png
ちゃんと星の形に塗りつぶすようだ。
2次元描画ソフトによっては、複数のモードが用意されていたり、必ずしもこうはならないこともある。

さて、実験で得られた情報から、授業で出てきたプログラムを勝手に変更したのが次のプログラムだ。

import Graphics.Gloss

picture = stars

stars = pictures [
    translate ( 80) ( 80) (color blue   star),
    translate (-80) (-80) (color yellow star),
                          (color red    star)
    ]

star = polygon [
    (  0,  50),
    ( 30, -30),
    (-40,  20),
    ( 40,  20),
    (-30, -30)
    ]

main = display  (InWindow "Nice Window" (300, 300) (100, 100)) white picture

もちろん、今日の最初の図と同じになってしまったので、絵は省略する。

どんなプログラムでも、変更してみよう。そうすることで、何かが得られる。

今まで、線しか描いていなかったが、図形の内部を塗ってみよう。

circleSolid  で円の内部がつまった円板になる。
rectangleSolid で内部がつまった長方形になる。

このままだと、塗る色が黒なのだが、color で色を指定することができる。

import Graphics.Gloss

picture = pictures [
    circleSolid 80,
    color green (rectangleSolid 200 100) ]

main = display (InWindow "Nice Window" (300, 200) (10, 10)) white picture

関数colorについて、ちょっと注意しておこう。
普通の感覚だと、 color 色 で、塗る色が切り替わる、と考えるかも知れないが、それは誤りだ。
関数colorの型を見てみよう。

Prelude Graphics.Gloss> :t color
color :: Color -> Picture -> Picture

第1パラメータが色だが、第2パラメータにPictureを与え、結果として指定色になったPictureが出てくるのだ。

ということで、このプログラムを実行すると、こんな表示になる。

sample-circleboxsolid.png

次に、図形の移動をしてみよう。
関数translateで、平行移動ができる。
x方向移動量 y方向移動量 図形 を与えると、移動された図形が得られる。

Prelude Graphics.Gloss> :t translate
translate :: Float -> Float -> Picture -> Picture

関数rotateで図形を回転できる。
回転量は、度で与える。
さて、回転の方向はどちらであろうか、結果を見て考えてみよう。

ということで、こんなプログラムを実行してみた。

import Graphics.Gloss

rec     = rectangleSolid 100 50
picture = pictures [
    translate 100 50 (color orange rec),
    rotate 60        (color blue   rec) ]

main = display (InWindow "Nice Window" (400, 200) (10, 10)) white picture

sample-circleboxmove.png

この図から、yの方向は、画面の上方向がプラス、下方向がマイナスである。
回転方向は、時計と同じ方向に回転するのがプラスである。

回転と移動が組み合わさると、最初はなかなか理解しにくいかも知れない。
どうして、その位置に表示されるのか、しっかり考えてみよう。
Haskellよりも、グラフィックの問題になってしまったかな。

では、また(つづく)

正月特別ビデオ講義の最後ということで、世界の大学がいかに講義(コース)を公開しているかについて書いておこうと思う。
中でも、一番有名なのは、MITのMIT OpenCourseWare | Free Online Course Materialsであろう。ForTheLoveOfPhysics.jpgMITでは、全コースをインターネット公開しようとしているのだ。
授業料などだけで年間4万ドルほどかかる大学の講義が無料で聴講できるのだ。理解できなくても覗いて見る価値はある。
その中でも特別に有名なのは、物理学の力学の講義だ。
日本の物理の本でも、鉄砲とかが出てくるが、この講義では実際にライフルをぶっ放してから、物理学に従って弾の速度を計算してみるのだ。
講義があまりにも有名になって本にもなったのだが、その表紙には等時性の実験をやっているところが載っている。教授自身が振り子の重りになって、広い教壇の上をゆらりゆらりと10回揺られるのだ。


1大学だけでなく、複数の著名大学が協力して公開している
Free Online Classes | Online Learning | Academic Earth というのがある。
現在、世界の41大学が参加していて、実に様々なコースが用意されている。
最初はアメリカが中心であったが、徐々に世界の大学が参加するようになってきている。
最近の目立った動きはIIT(インド工科大学)であろう。ちょっと試しに聞いてみたが、インド英語で延々と講義されてしまい、耐えられなかったので止めてしまった。本来はイギリス英語のはずなので、あのインド英語をイギリス英語に変換するフィルタはないものかと思う。

これら以外にも、世界の多くの大学で、様々な形で授業内容が公開されている。それに比較すると、日本の大学の授業公開レベルは、かなりお寒い状況である。公開しているといっても、最終講義だったり、特別講義だったり、資料だけとかが多い。たとえビデオが用意されていても、コースの一部がビデオ公開されているだけで、これではコースウェアでも何でもないと思うのだが。

Khan Academyも紹介しておきたい。今まで紹介したのは大学学部レベルの内容だったのだが、これは、それ以前、初等中等教育の理系科目が中心になっている動画サイトである。見ている人の数はこちらの方が多いようだ。
内容は他愛もないことだけれど、それを英語でどう説明するのかは、なかなか分からないものだ。
この動画サイトは、The Bill and Melinda Gates Foundation, Googleなどをはじめ多くのdonationで成り立っている。Bill Gates は引退後、慈善活動を行っており、2011年は36億ドルを寄付したようだ。
分かってる内容を英語で聞いてみるのも良い勉強になるだろう。英語が苦手でも、よく分かっている内容だと大丈夫かもしれない。

さて、次からは、またHaskellに戻るぞ!
msdn上に、Channel9というマイクロソフト関連の情報提供チャネルがあって、コンピュータ、ソフトウェア関連の多数のビデオコンテンツが存在する。もちろん、大部分はマイクロソフト関連のソフトに関するものだが。

この中に、haskellの講義が入っていた。単にhaskellを教えるというより、他の言語と比較してhaskell、そして関数プログラミングの素晴らしさを訴えるという内容である。比較対象として、ときどきVBやF#も出てくる。


C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals, Chapter 1 of 13

講師は、マイクロソフトのエンジニアの Erik Meijer (Computer scientist) である。

ビデオの内容は、関数プログラミングの基本的なもので、かなりというか、丁寧過ぎるくらい丁寧にやってくれる。ちょっと関数プログラミングを齧っただけの人にもやさしい、あるいはやさし過ぎるくらいの内容である。

しかし、講師は、なかなかエネルギッシュに、関数プログラミングについて語りかけるというより、まくしたてる。そのため、英語は、やや早口である。関数プログラミングがある程度分かっていれば、英語の練習として見てみるのは、とても良い勉強になると思う。

日本語の関数プログラミング/haskellのビデオがYouTubeなどに転がっているかと思ったが、残念ながら現時点ではほとんど存在しないようだ。YouTubeの検索に、"functional programming"とか、"Haskell"と入れるとすごくたくさんのビデオ講義などが出てきて、どれを見ようか迷ってしまう。とにかく、世界ではとても流行っているのだ。
さて、今日は、いつもとは違ったことを紹介しよう。
Haskellのプログラムをちょこちょこ紹介していたが、今日は、世界に飛び出してみよう。
つまり、日本以外、世界ではHaskellでどんなことをしているのだろうか。とくに、大学などで、Haskellをどのように教えているのか見てみよう。

まず、Haskellをやる以上、かならず見るべきサイトがある。
The Haskell Programming Language (www.haskell.org)
うまく表示されないときは、新しいタブ・新しいウィンドウに表示させるようにしてみてください。

そして、いままで使ってきたのがGHCなのだが、このGはグラスゴー大学のGなのだ。
ということで、グラスゴー大学で探すと、Functional Programming Research at Glasgowがすぐに見つかったが、文字情報はいっぱいあるものの、講義のビデオなどが見当たらないのだ。

haskell.org中に、Haskell in educationというのがあり、世界のいろいろな大学(主にイギリス)で行われているHaskellの授業の紹介がある。
その中の最初の方で取り上げられているのが、グラスゴーから近いエディンバラ大学の授業が紹介されていた。

informatics 1 - Functional Programming


ここには、テキストばかglasgow university haskell lectureりだが、YouTubeで調べると、なんと21本のビデオ(1回1時間)が存在するのだ。
うまく表示されないときは、新しいタブ・新しいウィンドウに表示させるようにしてみてください。

うまくビデオが出てこないときには、YouTubeで、 

haskell course 2011

で検索すると、ずらっと出てくる。ビデオのタイトルの最初にビデオの通し番号が降られているので、それを参考に見ていくとよい。

2011年の講義のビデオで、講義のページに資料が置かれているので、それを見ながら聞くこともできる。

最初の3回くらいは、Haskell以前のことを話していて、いつになったらHaskellの話になるのかな、という感じだ。

私も、まだ途中まで聴講しただけだが、結構ゆっくり説明してくれているようだ。
でも、講師は、とても興奮気味だ。Haskellを教えるって、そんなに興奮することかな。日本には、こんなに興奮しながら講義をする先生って、ほとんどいないなか。

正月なので、とりあえず、ゆっくりHaskellのビデオでも見て過ごしましょう♪

このアーカイブについて

このページには、2013年1月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2012年12月です。

次のアーカイブは2013年2月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。