2012/11/05

TeXユーザーの集い2012 雑感

2012年10月27日、京都大学で開催された「TeXユーザーの集い2012」に参加しました。

TeXユーザーの集い2012開会

勤め先ではpLaTeXをバックエンドに採用した継続的書籍制作をしているので、 前回、前々回の「TeXユーザーの集い」ではポスター発表という形で成果物である書籍の展示をしていたのですが、 今年は会場が京都なので、東京から何冊もの書籍を持っていくのは物理的にいやだ。 そこで代わりに「ショートショート」というコーナーで10分間のプレゼン発表と書籍の宣伝をさせてもらいました。

「出版社の中でpLaTeXとバージョン管理システムを全面的に活用して本を作っています」という話そのものは、 いまやそれほどもの珍しい話ではなくなっていると思います。 ちょっと前に新規企画のキックオフの場で著者(正確にいうと訳者)に制作フローの説明をするとき、 「前にも別の出版社で同じような方法でやったことがあるから分かります」と言われたときは、 本気で涙が出るかと思いました。 田中さんのショートショート発表にあったような業務ドキュメント作成のバックエンドで利用されている事例も案外に多いのかも。

そこで今回のプレゼン発表では、自分たちの書籍制作フローを紹介するだけでなく、実例を交えて方法論の私的な意味づけができればと思って挑みました。 この時点でもともと「ショートショート」コーナーに設定されていた「私のTeX環境」というお題から微妙に逸脱していたことは実行委員の皆様にお詫びいたします。 でも当日、LaTeXの論文原稿からプレゼンを吐き出すという寒川先生の話、 印刷の歴史から現在のXSL-FO対応にいたる中西印刷の中西さんの話、 XMLによる医療系ドキュメントの標準化に携わってらっしゃる時実先生の話などを伺っているうちに、 もしかして自分の発表はカウンターを狙ってたつもりが正面からジャブみたいになってる?という気がしてきました。

思えば去年の「TeXユーザーの集い」も「TeXという視点から構造化ドキュメントのエコシステムを捉えよう」というノリでした。 そうなんだよなー。 かつてTeXを採用する理由とされたのは「数式がきれい」のような特徴でしたが、こういう面ですでにTeXは One of Them になっています。 無料であるのはいまもってTeXくらいに思えますが、Wordなんかは事実上無料なわけで、そのWordの数式エディタも性能としては十分です。Apple製品でもなにかあるんですよね。よく知りませんが。 そういえば黒木さんの発表でも韓国や欧州のTeXユーザーグループの集まりでは「TeXの話が半分、XMLなど周辺の話が半分」といってた気がする。

そういう中でわたしが仕事でTeXを使っているのは、ひとつにはプレゼンで触れてるように「バージョン管理しやすい」というのがあります。 実際、このプレゼン発表の資料も、pLaTeX + beamer で書いて bitbucket でバージョン管理してました(ソースが見られて恥ずかしいけど、おかげで公開後にいっぱいフィードバックもらえた。ありがたいことです)。 でもテキストの原稿をバージョン管理したいなら、べつにTeXをバックエンドに使う必要はなく、中西印刷さんのようにアンテナハウスさんのFOフォーマッターを利用するのでもいい。

結局、編集者としての自分が仕事でTeXを使ってることに、それほど積極的な理由はありません。 経済的な制約だったり自分のスキルの制約だったり、どちらかというと消極的な理由からです。 だから、たとえば人にTeXを使えと勧める気には正直なところあまりなりません。 やっぱり編集の仕事でTeXを使おうとするには、それなりの覚悟と職場的な理解が必要だと思います。 自分は出版社にいるのである程度好きなように環境を選べますが、プロダクションでの編集となるとそうもいかないでしょう。 (もちろん世の中には、そういう覚悟を決めて出版社から制作の仕事を請け負ってしまうすごいプロダクションもあります。)

一方、趣味プログラマーとしての自分にとってTeXマクロは単純に面白いので、その部分については「おもしろいよ!」と主張したい。 ふつうのプログラミング言語だと思って使おうとするとストレスフルですが、モデルが違うんだから違うモデルで考えることを楽しめばいい。 TeXを使って遊ぶ文化は今年に入ってから日本でじわじわ広まっていると感じています(いにしえからあるので新しい文化というわけではないですが)。今年は「TeX芸人」という言葉も生まれました。今回は「TeX芸人」という言葉が誕生してはじめて開催された「TeXユーザーの集い」だったからか、残念ながらストレートにそういう発表はありませんでしたが、今年のクリスマスはTeXアドベントカレンダーが読めるかもしれません。どんな\expandafterが見られるか楽しみですね。

というわけで、自分のTeXに対するスタンスは、そんな「実務で十分に使える自分にとっては楽しい道具」かなと再確認しました。 懇親会で何人かの方と「TeXを普及させるには」的な話になったりもしたけれど、 新興の技術というわけでもないのだし、(1)使ってみようという人にとって負荷が低いこと、(2)楽しく使えてる人が楽しく使い続けられること、(3)新しい仕組みとの親和性を保ち続けること、あたりがTeXユーザーにとって本来の争点なんだと思います。

1は、ディストリビューションやインストーラの開発者のみなさんのおかげで、すでに障壁らしい障壁はない状態にあると思います。 2は、TeX芸人たちをはじめ、わたしの観測範囲にはTeXまわりの技術を楽しんでいる人が何人かいます。 というわけで、あとは3です。 思いつく成功事例としてはMathJaxとかLuaTeXとかありますが、プレゼンでも最後に触れているEPUB対応とか、ほかにもまだ難題は残ってるような気がします。

以上、「気がする」とか「思います」とかが多い記事ですが、それだけTeXの周りにいる人たちが多彩なので一つの見方で断定できないということなのです。そういう方々と交流できる「TeXユーザーの集い」は、今年も自分にとってとても得がたい場でした。

2012/10/20

ロハン・デ・サラム&児玉桃 デュオリサイタル2012に行ってきた

2012年10月19日、ロハン・デ・サラムと児玉桃の共演が津田ホールでありました。 これがロハンおじさん。

このロハンおじさん、アルディッティという人が組織している現代音楽しかやらない弦楽カルテットで長らくチェロをやってきたので、とにかくうまい。 超絶技巧な現代のチェロ曲をさらっと弾く。ヘリコプターの上とかでも平然と弾く。歌うような演奏とは対極にある、クールなうまさです。 十八番はコダーイの無伴奏で、上の写真もロハンおじさんのコダーイが聞ける唯一のCDのジャケットです(ほかにあったら教えてください)。 わりと入手困難で(MP3ならamazonでも買える)、会場の物販にも並んでたやつもロハンおじさんが自ら持ち込んだものだったらしい!

一方の児玉桃も、現代曲、とくにメシアンのCDで名前が知られてるといっても自分的には過言ではないような気がします。 そんなロハン・デ・サラムと児玉桃の共演です。 なんてったってロハン・デ・サラムと児玉桃です! もしかして「イエスの永遠性への賛歌」が生で聴けるのか!って期待するじゃないですか。 百歩譲ってドビュッシーでもいいよ!って思うじゃないですか(2008年のサラムと高橋アキのドビュッシーはよかった)。

違いました。なぜか1曲目はシューマン。なんでロマン派。 シューマンももちろん悪くはないんけど、なにもロハン・デ・サラムと児玉桃でやらなくてもいいのになー。 マイスキーとアルゲリッチとかに任せとけばいいじゃないか。 案の上というか何というか、ロハンおじさんは軽く引き流してるし、どうもミスも多い感じ。 児玉桃のほうは安定してました。ときどき振り返って投げかける「しっかり!ロハン」という視線もぐっときます。

しかし、その次の細川俊夫「チェロとピアノのためのリート」で空気が変わりました。 打って変わって精彩な演奏に、という感じではなく、最初こそちょっぴり1曲目を引きずっていましたが、 児玉桃に引っ張られつつ空気が変わっていく。 続くカーターの「フィグメント」はロハンおじさんのソロだったのですが、すっかり安心して聴けました。

細川俊夫とかカーターとか、後の演目にあるクセナキスとかもそうなのだけど、 自宅でCDを聞いてるだけだと悪い意味で耳に障ることもあるくらいなのに、 こうやってライブを目の当たりにして聴くと形ある音楽が見えてくる。 CDでも、聴く回数を重ねていくとそのうち音楽として聞こえてくるようになるんだけど、 ライブだと、一聴で雑音に見えるものから構造が見えてくるという体験がリアルタイムでできる。 そして、そういう体験をさせてくれるロハンおじさんみたいな現代曲の演奏家は本当にすばらしいと思います。

次のフォーレはよく憶えていない、というか、休憩を挟んだその次のクセナキスの印象が強烈すぎて忘れました。 曲目はコトスで、過去にロハンおじさんの生演奏を聞いたこともあるし、 CD(やはりロハンおじさん演奏)を通じて慣れ親しんでいた曲なので、 個人的に今回のプログラムの中でいちばん楽しみだったわけですが、 なんど見てもカッコいい! まずステージの光景からしてかっこいい。 フレーム構造の譜面台に乗せた黄ばんだ大きめの一枚つづりの楽譜が、ステージの照明で透けて、譜面の密度が客席からも垣間見える。 その向こうでロハンおじさんが一人、あのコトスのしょっぱなの地の底みたいな音の塊を、まるで基礎練習でも始めるみたいにしれっと弾き出す。 なんかテンポもCDより速い気が。中盤になると思わず縦に身体が動いてしまう。クセナキスなのに。 その次のR.シュトラウスもまあ楽しかったですが、ほとんどコトスの余韻だけで楽しんだ気分です。 アンコールはカサドが編曲したグラナドスの何かだといってました。初めて聴く曲だったけど、調べてみると「ゴイェスカス」かな。最後までメシアンを期待してたので残念でしたが、まあ、これはこれでよかったです。

演奏会後にはCD購入者向けのサイン会がありました。 売っていたロハンおじさんのCDはほとんど持っていたので、「インドの作曲家による2曲」(ロハンおじさん談)という、見たこともないCDを買ってサインしてもらいました。 軽く舞い上がってしまい、コダーイ持ってるよとか、どうでもいい話をしてしまいました。 冷静になって思い返したら、松村貞三の17絃箏のための祈祷歌のチェロ独奏版を録音してくれとかせがんでくればよかった。

2012/07/16

DP2 Merrillをもって散歩するのが楽しすぎる件

連休も終わってしまうので、昨日に引き続きSigma DP2 Merrillのレビューっぽいことをしておきます。色の不具合とか質感すげーという話は昨日したので、今日は個人的につぼったポイントを紹介します。

まず画角について。35mmカメラ換算で約45mmという、いわゆる標準レンズの画角なのですが、これがやっぱり使いやすいです。最近はD90+カラースコパー20mmという変態構成で散歩することが多くて、これはこれでボーっと眺めてる景色を四角い画面に収めたいときには都合よくて楽しいのですが、意識的に「何か」を眺めてるときの光景を切り出すのにちょうどいいのは、やっぱり標準レンズだったんだなーと思い出してきました。

10数年前、お金ない学生のころはフィルムカメラに標準レンズをつけて歩くしかなかったわけですが、そのころの感覚もこんなでした。そんなおっさんがDP2 Merrillを使うと、当時の自分には切り取れなかったような光景が切れるんだから、楽しくないわけがないです。

SDIM0127

SDIM0143

SDIM0025

SDIM0055

コンデジっぽくない操作性も評価したい点です。いちばんアクセスしやすい位置に取り付けられているジョグダイヤルには、撮影時には露出とシャッタースピードを変更する機能が割り当てられています。これ、すごく使いやすい。さらに、ホワイトバランスの変更、ISOの変更、MFへの切り替え、露出補正、AEロックといった、個人的に「必須」な操作へのアクセスがおそろしく簡便です。スチル写真を撮る人向けに特化した潔い設計で好感度高いし、実際、直感的な操作体系になるようまとめられてるなあと感じます。

コンデジっぽくないといえば、49mm径のフィルターが装着できるのもポイント高いです。ペンタックスSMCタクマーの標準で利用してたフィルターが軒並み使えるので大興奮です。まあでも、PLフィルターの効果を液晶ファインダーで確認するとか、あんまり正気の沙汰ではない感じもしますが、こまけえこたーどうでもいいんだよ。

DP2 Merrill with PL filter

最後にまたノスタルジックな話。DP2 Merrillで撮影後、Sigma Photo Proでの現像が楽しすぎるのですが、これもやっぱりフィルムの現像と暗室作業をしていたころを思い出します。フィルムの場合、現像と焼付けの時点ではじめて撮影時の妄想が形になるわけですが、DP2 Merrillで撮影したデータもPCで現像していると液晶ファインダーのプレビューでは気がつかなかったような絵が出てくることがあって、これって暗室で印画紙に絵が浮き上がってくる感覚に似てます。もっとも、DP2 Merrillの液晶ファインダーは正直なところ「撮ってすぐ細部を確認」のような使い方をするにはストレスフルなので、それで現像時の驚きが増えてるだけかもしれません。とはいえ、DP2 Merrillで撮影した写真の現像作業は楽しすぎて時間泥棒なのは事実です。

SDIM0128

SDIM0136

SDIM0137

SDIM0027

2012/07/15

Sigma DP2 Merrillがきた

Sigma DP2 Merrill を手に入れました。2月の発表と同時に酒を控えるなどしてこつこつ資金を捻出してきたおかげで発売当日にヨドバシカメラで購入することができました。発売日がちょうど夏休中だったのも幸いでした。日ごろの行いがよかったに違いありません。

さっそく、ヨドバシカメラ秋葉原店の前にあるスターバックスで試し撮りです。

DP2 Merrill

なんか暗いのはスタバの店内だからですが、右側のコーナーが緑がかってるのはなぜだろう。このflickr上の写真はカメラ内現像したJPEGデータですが、X3F形式のデータをIrfanViewで閲覧しても、SIGMA Photo Pro 5で処理しても、やはり緑がかってしまいます。ちょっと気になります。

この四隅が緑がかる現象は、こんな白バックの写真で現れるようです。これを見ると、四隅が緑というだけでなく、白バックの中心も赤みがかりますね。

FM-2 WILDCAT 1/144 Sweet

色について気になるポイントが実はもうひとつあって、それは紫のノイズが出ることです。この写真の二階中央部分に、目立たないですが紫の帯が出現してます。

SDIM0038

露出をアンダーにして現像し、等倍で切り出したのがこちら。

SDIM0038-1-close

この紫ノイズは、SPPで「X3 Fill Light」というパラメータを引き上げて遊んでいるときに初めて気がついたので、そもそもこんなむちゃくちゃな光加減で写真を撮ろうと思わなければいいだけの話ですが、白バックが緑がかるのは撮影時にちょっと警戒しないといけなそう。

難癖は以上でおしまい。実際のところ、このカメラを持って散歩に出かけるのは最高に楽しいです。

まず、とにかくディテールがすごいと噂のFoveonなわけですが、確かにすごいです。意味もなく芝生の写真とか撮りたくなります。

SDIM0044

あと、質感が気持ち悪いくらいすごい。パンケーキの上で溶けかけのバターとか、

SDIM0037

科学博物館の鯨のひれのぬめっとした感じとか、

SDIM0047

オオムラサキの羽の粉っぽさとか。

オオムラサキ

ただしAFでのピント合わせは遅いです。それもあって、オオムラサキはシャッタースピード稼ぐために被写界深度を浅めにしか設定できず、いまいちピントあってないです。とはいえ、フォーカスをいつでもマニュアルへと一瞬で変更できるので、こういうシビアな局面でなくてAFだとおっつかない場合には地味にうれしいです。うどん屋でテーブル上の透明なオブジェ越しに落ち着きのない子どもを撮影とか、AFでどうやって撮るんだという。

SDIM0085

あとノイズについてですが、結論からいうと気にしなくていいと思います。FoveonはノイズがひどいのでISOを上げられないという噂を聞いてたので、けっこう警戒しながら撮影してたのですが、かなり暗い場面で動きのある被写体をディテールは気にしないから雰囲気だけ切り取りたいという気分だったので、思い切ってISO6400に設定し、距離を頼りにMFでシャッターを押してみました。その場で液晶ディスプレイのプレビューを見たときは、盛大なノイズに苦笑いしたのですが、うちに帰ってSPPに読み込ませたら、ほとんどノイズなんて目立たなくなりました。こういう写真を気軽に撮れるのは本当にうれしい。

SDIM0091

あと、カタログに「撮影時には気がつかなかったようなものさえ撮れている」とか何とか書いてあった気がするのですが、本当でした。たまたま撮った風景写真に知り合いが写りこんでるのを自宅に帰ってからPC上で眺めていて発見してしまうくらい。それだけ解像度はすごいです。

2012/07/06

時系列データのグラフをjQueryとFlotで描く

JSONの時系列データがたくさん手に入りました。なにせJSONなんだし、JavaScriptを使ってブラウザにインタラクティブなグラフを簡単に描けそうな気がします。そこでとりあえず折れ線チャートを描くことにしました。むかしjQuery用のFlotというライブラリを使ったことがあったので、今回もこれを使おうと思ったのですが、完全に使い方を忘れていた!そういえば、むかし使ったときも、API.txtという英文がだらだら書かれたテキストファイルしかドキュメントがなくて面倒だったのを忘れていました。そこで今回は備忘録を残しておくことにしたしだい。

なお、Flotはべつに時系列の折れ線チャートを描くためのライブラリではないので、ほかにもいろいろなチャートが描けるはずですが、とくに調べていないので知りません。あくまでも時系列データの折れ線チャートを描くことが目標の備忘録です。

下準備

描画したい時系列データは、こんな1つの配列として用意します。

mydata = [[1309446000000, 6],
          [1312124400000, 9],
          [1314802800000,18],
          [1317394800000,23],
          [1320073200000,27],
          [1322665200000,27],
          [1325343600000,31],
          [1328022000000,35],
          [1330527600000,38],
          [1333206000000,44],
          [1335798000000,49],
          [1338476400000,50]]

要素である長さ2の配列が、それぞれ [日時, データ値] を表しています。

第一要素の日時が 1309446000000 のようなでっかい数値なのは、UNIX時間をミリ秒単位で表したものだからです。これ以外の書式でFlotに日時を指定するすべはありません。もし「2012年7月4日の値は12で、2012年7月5日の値は0で、……」だったら、 [[1341327600000, 12], [1341414000000, 0], ...] という配列を用意するわけです。Gaucheで用意するならこんな感じ。( construct-json-string は、S式からJSON表記の文字列をよろしく作ってくれる関数です。)

(use srfi-19)
(use gauche.sequence)
(use rfc.json)
(define (localtime->jstime str)
  (* 1000
     (time->seconds
      (date->time-utc
       (string->date str "~Y年~m月~d日")))))

(define mydata
  #(#("2012年7月4日" 12) #("2012年7月5日" 0)))

;; (construct-json-string mydata) の出力ではだめ

(construct-json-string
 (map-to <vector>
         (lambda (v) (vector (localtime->jstime (ref v 0)) (ref v 1)))
         mydata))

ちなみに、日時に限らず、Flotが受け付けてくれる値データは数値のみです。文字列の値データは与えないこと。

とりあえず描く

おおざっぱなノリとしては、HTMLページ中にグラフの出力場所を作っておいて、 jQuery.plot(出力場所, [データ列], オプション) とすれば、それっぽい折れ線チャートができるという仕組みです。

<html>
<head>
  <script language="javascript" type="text/javascript"
    src="http://code.jquery.com/jquery-latest.js"></script>
  <script language="javascript" type="text/javascript"
    src="flot/jquery.flot.js"></script>
</head>
<body>
  <div id="placeholder" style="width:600px;height:300px;"></div>
</div>
<script>
var options = { xaxis : 
                 { mode : "time"}
              };
var mydata = [
              [1309446000000, 6],
              [1312124400000, 9],
              [1314802800000,18],
              [1317394800000,23],
              [1320073200000,27],
              [1322665200000,27],
              [1325343600000,31],
              [1328022000000,35],
              [1330527600000,38],
              [1333206000000,44],
              [1335798000000,49],
              [1338476400000,50]
             ];
$.plot($("#placeholder"), [mydata], options);
</script>
</body>
</html>

描画する場所は、この例では <div id="placeholder" style="width:600px;height:300px;"></div> です。このように、必ず縦と横の長さを明示してやります。

スクリプトから、この描画場所を参照するときは、この例のようにセレクタを jQuery() に渡してjQueryオブジェクトを作り、それを渡します。グラフを表示するだけなら、 $.plot("div#placeholder",...) のようにセレクタを直接指定するだけでもかまわないようですが、あとでjQueryオブジェクトの bind() メソッドを使ってインタラクティブな機能を付け足したいので、jQueryオブジェクトにしておきます。

$.plot() の3つ目の引数である options は、上記の例では {xaxis : { mode : "time"}} です。「x軸( xaxis )のデータの種類( mode )は日時( "time" )だよ」と意味です。こう指定すれば、元データの第一要素が日時データとして解釈され、x軸にそれっぽいラベルが適当な間隔でふられます。描画の際のオプションはほかにもいろいろ指定できますが、時系列データをプロットするときによく使いそうなものだけメモしておきます。ほかは公式のテキストで「Customizing the axes」とか検索して調べる。

項目オプション値の例意味
xaxismode"time"x軸の値を日時とみなす。
timeformat"%y/<br>%m"日時ラベルの書式。htmlタグ使える。
ticks10x軸に表示するラベルの数。画面に入らないと適当にふり直してくれる。
[]x軸にラベルを表示しない。
tickSize[1, "day"]1日おきにラベルをふる。
gridclickabletrueグラフをクリックしてイベント飛ばせるようになる。
hoverabletrueグラフにマウスオーバーでイベント飛ばせるようになる。

あらかじめ用意するデータ列 mydata はそもそも配列ですが、それをさらに [mydata] のように配列で括ってから $.plot() に渡している点に注意。この配列に複数のデータ列 [mydata1, mydata2] を指定すれば、ひとつのチャートに複数の折れ線を重ねてプロットできます。

var mydata1 = [
               [1309446000000, 6],
               [1312124400000, 9],
                ...                // 長いので省略
              ];
var mydata1 = [
               [1309446000000, 0],
               [1312124400000, 10],
                ...                // 長いので省略
              ];
$.plot($("#placeholder"), [mydata1, mydata2], options);

さて、この例のように $.plot() に引数として描画の際のオプションを渡すのでは、それぞれの線の色を好みに応じて変えたり凡例を指定したりすることはできません。次はその方法です。

凝ったグラフ用にデータを準備する

ここまでの例では、jQuery.plot()の第二引数に、 [[日時,データ], ...] というカタチをしたデータ列そのものを指定してました。実はこれは手抜きなやり方で、本当はデータ列とそのメタ情報をJavaScriptのオブジェクトとしてまとめて指定します。

var myseriese1 = {
                   label : "rapid",                   // データ列の名前
                   data  : mydata1,                   // データ列
                   color : "rgba(255, 0, 0, 0.8)",    // チャートの色
                   ...                   // ほかはドキュメント参照
                 }

var myseriese2 = {
                   label : "human",                    // データ列の名前
                   data  : mydata2,                    // データ列
                   color : "#rgba(255, 0, 0, 0.8)".    // チャートの色
                   ... 
                 }
$.plot($("#placeholder"),
       [myseriese1, myseriese2],
       $.extend(true, {}, options, { legend : { position : "nw" }}));

color は、まあ、線の色です。 label のほうは、指定した文字列が凡例に使われます。凡例は、デフォルトではグラフ領域の右上に表示されますが、これを左上に移動したいときは、この例のようにしてオブジェクト options を拡張( jQuery.extend() )してやります。 "nw" は「北西」ですね。

外部のファイルからJSONデータを読み込む

Flotがデータ列としてとるオブジェクトは、見ての通りまんまJSONです。そこで外部のファイルに保存してあるJSONのデータを読み出してグラフにしたい。これにはjQueryの jQuery.getJSON() メソッドを使います。

JSONがFlotのデータ列として適当な形式になってるとは限らないので、たとえばこんな内容のファイル mydata.json があったとしましょう。

[{
   "entry" : {
               "code"  : "rapid",
               "title" : "うさぎ",
               "data"  : [[1309446000000, 6],
                          ...                    // 省略
                          [1338476400000,50]]
             }
 },
 {
   "entry" : {
               "code"  : "human",
               "title" : "ヒト",
               "data"  : [[1309446000000, 6],
                          ...                    // 省略
                          [1338476400000, 1]]
             }
 },
 ... // 省略
]

"data" をデータ列として使い、 "title" を凡例用のラベルとして使い、チャートを書きたいとします。

var options = { xaxis: { mode: "time" },
                legend : { position : "nw" }
};

$.getJSON("mydata.json", function (json) {
  var target1 = getEntry(json, "rapid");
  var target2 = getEntry(json, "human");

  var plotdata = [{label : target1.title , data : target1.data},
                  {label : target2.title , data : target2.data}];

  $.plot($("#placeholder"), plotdata, options);
});

function getEntry (json, codestr) {
  i=0;
  while (i < json.length) {
    if (json[i].entry.code == codestr) {
      return json[i].entry}
    ++i}
  return false;
};

出力は前の例とほとんど一緒なので省略。

インタラクティブなグラフにしたい

いままでの要領でまず素朴なグラフを描き、その描画領域のjQueryオブジェクト(いまの例では $("#placeholder") )の bind() メソッドを使うことで、グラフにさまざまな機能を付け足すことができます。たとえば、上の例で $.getJSON() に渡している関数の中身に以下のコードを付け足すことで、「グラフ上をマウスでドラッグした範囲にズーム」という芸当ができるようになります( jquery.flot.selection.js が必要なのでHTMLファイルのヘッダ部分に呼び出しを追加しておくこと)。

  $("#placeholder").bind("plotselected", function (event, ranges) {
      $.plot($("#placeholder"), plotdata,
             $.extend(true, {}, options, {
                 xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to }
             }));
  });

bind の第一引数に指定できるイベントには、この例で使った "plotselected" のほか、 "plothover""plotclick" などがあります。名前のとおり、選択した領域に対するアクション、マウスオーバー時のアクション、マウスクリック時のアクションを関数として指定できます。ほかにもありそうだけど調べてません。このへんはドキュメントにはあまり解説がなくて、むしろ公式サンプルで遊びながらソースを参照しましょう。下の画面程度の完成度でよければ、サンプルからのコピペ駆動でそれほど苦もなく実現できます。

<html>
<head>
  <script language="javascript" type="text/javascript"
    src="http://code.jquery.com/jquery-latest.js"></script>
  <script language="javascript" type="text/javascript"
    src="flot/jquery.flot.js"></script>
  <script language="javascript" type="text/javascript"
    src="./flot/jquery.flot.selection.js"></script>
</head>
<body><div>
  <div id="placeholder" style="width:600px;height:300px;"></div>
  <br>
  <div id="overview" style="width:400px;height:150px"></div>
</div>
<script>
var options = { xaxis: { mode: "time", timeformat: "%y年<br>%m月"},
                legend : { position : "nw" },
                selection: { mode: "x" },
                grid: { hoverable: true, clickable: true }
};

$.getJSON("mydata.json", function(json) {
  var target1 = getEntry(json, "rapid");
  var target2 = getEntry(json, "human");

  var plotdata = [{label: target1.title , data: target1.data},
                  {label: target2.title , data: target2.data}];

  var plot = $.plot($("#placeholder"), plotdata, options);

  var overview = $.plot($("#overview"), plotdata, {
      series: {
          shadowSize: 0
      },
      legend: { show: false },
      xaxis: { mode: "time" },
      yaxis: { ticks: 1, min: 0, autoscaleMargin: 0.1 },
      selection: { mode: "x" }
  });
  
  var previousPoint = null;
  $("#placeholder").bind("plothover", function (event, pos, item) {
    if (item != null && previousPoint != item.datapoint) {
      previousPoint = item.datapoint;
      $("#tooltip").remove();
      var d = new Date(item.datapoint[0]),
          Y = d.getFullYear(),
          M = d.getMonth() + 1,
          r = item.datapoint[1].toFixed();
      showTooltip(item.pageX, item.pageY,
          "~" + Y + "年" + M + "月" + ":" + r + "体");
    } else {
      $("#tooltip").remove();
      previousPoint = null;
    }
  })
  
  $("#placeholder").bind("plotselected", function (event, ranges) {
    var plot = $.plot($("#placeholder"), plotdata,
                      $.extend(true, {}, options, {
                        xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to }
                      }));
    overview.setSelection(ranges, true);
  });
  $("#overview").bind("plotselected", function (event, ranges) {
    plot.setSelection(ranges);
  });
});

function getEntry (json, codestr) {
  var i=0;
  while (i < json.length) {
    if (json[i].entry.code == codestr) {
      return json[i].entry}
    ++i}
  return false;
};

function showTooltip(x, y, contents) {
  $('<div id="tooltip">' + contents + '</div>').css( {
    position: 'absolute',
    display: 'none',
    top: y + 5,
    left: x + 5,
    border: '1px solid #fdd', 
    padding: '2px',
    'background-color': '#fee',
    opacity: 0.80
  }).appendTo("body").fadeIn(200);
};

</script>
</body>
</html>

2012/01/13

n進数で文字列探索

4桁の整数のなかで「42」という並びを含むものを探すことを考えます(10進で考えます)。 こんな二階建ての再帰でいけそうです。

『「末尾が42の数を全部集める」』→
『「末尾が420の数を全部集める」→「末尾が421の数を全部集める」→…→「末尾が429の数を全部集める」』→
『「末尾が4200の数を全部集める」→…』

『…』の再帰は、こんな感じ。

(define (migi base hidari)
  (iota (expt 10 base) hidari))

「42」が出現してる場所より右側をなめるので、migi という名前にしました。 引数の hidari には「42なんとか」(なんとかは空か数字の列)が順番に入る、という気持ちです。 base が 0 なら「42」、base が 1 なら「420から429」、base が 2なら「4200から4299」、…という具合。「42なんとか」を始点に、10 の base 乗個とってくればよいので、iota を使っています。

「…」の再帰については、migi を受けて hidari の全パターンを集めるので、こんな unfold で書けます。

(define (hidari-all upper order)
  (lambda (migi)
    (unfold (pa$ < upper) values
            (pa$ + (expt 10 order))
            migi)))

ようするに、 migi が「42」の場合には「xx42」の xx にあらゆる数字の組み合わせをぶちこんだリストです。migi が「420から429」なら「0420, ..., 9420, 0421, ..., 9421, ..., 0429, ..., 9429」で、migi が「4200から4299」ならそのものです。 migi の要素が2桁である「42」のときは10の2乗( = 100)を次々に加えていったもの全部、3桁である「420から429」のときは10の3乗( = 1000)をそれぞれに次々加えていったもの全部、…という具合です。これらを unfold で作り出しています。

以上の2つの再帰を組み合わせれば完成です。(hidari-allorder を決めるときにちょっと苦心しました。)

(define (intseek order num)
  (let1 upper (+ 1 (expt 10 order)) ; 9999 + 1
    (let R ((b 0) (hidari num))
      (if (> b (- order (ord num)))
          '()
          (append
            (append-map (hidari-all upper (+ b (ord num))) (migi b hidari))
            (R (+ b 1) (* hidari 10)))))))

; 最近のGaucheなら(log x 10)で済むのだけど。
(define (ord x)
  (x->integer (/ (log x) (log 10))))
結果はこうなります(途中は省略)。
gosh> (intseek 4 42)
(42 142 242 342 442 542 642 742 842 942 1042 1142 ... 4295 4296 4297 4298 4299)

この遊び、なにも10進に限る必要はありません。2進表記で10桁の整数から「11」の並びを含むものを探すとか、16進表記で4桁の整数から「aa」の並びを含むものを探すとか、簡単に応用できます。

(define (intseek order str radix max-digit)
  (define (hidari-all upper order)
    (lambda (migi)
      (unfold (pa$ < upper) values
              (pa$ + (expt radix order))
              migi)))
  (define (migi b hidari)
    (iota (expt radix b) hidari))
  (let1 upper ; radix進でorder桁の最大数 + 1
      (+ 1 (string->number (make-string order max-digit) radix))
    (let R ((b 0) (hidari (string->number str radix)))
      (if (> b (- order (string-length str)))
          '()
          (append
            (append-map (hidari-all upper (+ b (string-length str)))
                        (migi b hidari))
            (R (+ b 1) (* hidari radix)))))))
gosh> (map (cut format "~x" <>) (intseek 4 "aa" 16 #\F))
("aa" "1aa" "2aa" "3aa" "4aa" "5aa" "6aa" "7aa" ... "aafd" "aafe" "aaff")

さらに、26進の数字で特定の並びを含むものを探すこともできるはずです。ということは、26進の数字とアルファベット26文字を対応させてやれば、n文字のアルファベット文字列から特定の文字の並びを含むものを見つける、といった問題にも応用できることになります。さすがに26進だと表記につかう26個の文字を扱うのつらいのでやる気になりませんが、次の問題くらいなら4進で済むので、この方法を使って解けそうです。

4種類のアルファベット "A,C,G,T" から成るn文字の文字列のうち、"AAG"という並びが含まれる文字列を全て列挙するプログラムを書きなさい。ただし、nは3以上の整数とし、文字列内に同じアルファベットが出現しても構わないものとし、出力順序は問わないものとします。 ... 適性検査に合格された方はその生産性を実現可能な方です。生産性に見合う初任給として年俸1000万円をご用意しております。
(via: 名古屋Scala掲示板 年俸1000万の会社の試験問題

アルファベットと4進数との変換だけ定義してやれば、1000万ゲット。

(define mapping
  '((#\A #\3) (#\C #\2) (#\G #\1) (#\T #\0)))

(define (acgts n ls)
  (map (lambda (int)
         (ints->acgt (string-pad (number->string int 4) n #\0)))
       ls))

(define (acgt->ints str)
  (string-map (lambda (c) (cadr (assoc c mapping))) str))

(define (ints->acgt str)
  (string-map (lambda (c) (cadr (assoc c (map reverse mapping)))) str))
gosh> (acgts 5 (intseek 5 (acgt->ints "AAG") 4 #\3))
("TTAAG" "TGAAG" "TCAAG" "TAAAG" "GTAAG" "GGAAG" "GCAAG" "GAAAG" "CTAAG"
 "CGAAG" "CCAAG" "CAAAG" "ATAAG" "AGAAG" "ACAAG" "AAAAG" "TAAGT" "GAAGT"
 "CAAGT" "AAAGT" "TAAGG" "GAAGG" "CAAGG" "AAAGG" "TAAGC" "GAAGC" "CAAGC"
 "AAAGC" "TAAGA" "GAAGA" "CAAGA" "AAAGA" "AAGTT" "AAGTG" "AAGTC" "AAGTA"
 "AAGGT" "AAGGG" "AAGGC" "AAGGA" "AAGCT" "AAGCG" "AAGCC" "AAGCA" "AAGAT"
 "AAGAG" "AAGAC" "AAGAA")

2012/01/06

一筆書きドラゴン曲線

TeX でドラゴン曲線を描こうと思ったのですが、クヌース先生がとっくにやってしまっていて、あろうことか『TeXブック』にまで載せていました。出力結果は『TeXブック』に載っていないので、とりあえず写経して pdftex にかけてみたら、確かにきれいな龍が現れました

そのクヌース先生のコードですが、実際にドラゴン曲線を描くコードはたったの 2行です。

\def\dragon{\ifnum\n>0{\advance\n-1 \dragon\L\nogard}\fi}
\def\nogard{\ifnum\n>0{\advance\n-1 \dragon\R\nogard}\fi}

どうやら相互再帰みたいですね。 Scheme で書くならこんな感じでしょうか。

(define (dragon-curve dim)
  (define (dragon i)
    (if (> i 0)
        (append (dragon (- i 1)) 
                turn-left
                (nogard (- i 1)))
        '()))
  (define (nogard i)
    (if (> i 0)
        (append (dragon (- i 1))
                turn-right
                (nogard (- i 1)))
        '()))
  (dragon dim))

ドラゴン曲線は、「線分を真ん中で直角に折る」という操作を、折り曲げてできた 2つの線分に繰り返し適用して得られる自己相似なフラクタル図形です。ただし、折り曲げてできた 2つの線分を再び折り曲げる際には、それぞれ違う向きに操作を適用します。最初の線分の向きが「→→」だとしたら、「→←」という具合に、折り曲げてできた 2つの線分の双方に対して逆向きに繰り返し操作を適用するわけです。

で、クヌース先生はこれをうまく利用することで、\dragon\nogard (dragon を逆から読んだ)を相互再帰させているわけですね。それぞれの真ん中にある \L\R は曲げる方向で、結果として \dragon\L\R からなる列に展開されます。この \L\R にしたがって頭から進んでいけば、一筆書きの要領でドラゴン曲線が得られるという寸法です。

TeXもいいですが、一筆書きといったら『関数プログラミング』(R. バード,P.ワドラー著/武市 正人訳)の亀の子図形でしょう。むかし書いた Scheme 版でドラゴン曲線をやってみます。切り貼りして説明書くの面倒くさくなったのでファイルまるごと掲載。

;;;; dragon.scm
(use srfi-1)
(use srfi-42)
(use util.match)

;; state -> state
(define (move state)
  (match state
    (`((,x ,y) 0) (make-state (- x 1) y 0))    ;; N
    (`((,x ,y) 1) (make-state x (- y 1) 1))    ;; W
    (`((,x ,y) 2) (make-state (+ x 1) y 2))    ;; S
    (`((,x ,y) 3) (make-state x (+ y 1) 3))    ;; E
    ))

(define-syntax let-state
  (syntax-rules ()
    ((_ e1 (e2 e3 e4) e5 ...)
     (let ((e2 (caar e1))
           (e3 (cadar e1))
           (e4 (cadr e1)))
       e5 ...))))

;; state -> state
(define (turn-left state)
  (let-state state
      (x y d)
    (make-state x y (remainder (+ d 1) 4))))

;; state -> state
(define (turn-right state)
  (let-state state
      (x y d)
    (make-state x y (remainder (+ d 3) 4))))

;; state
(define (make-state x y d)
  (list (list x y) d))

;; state -> [state -> state] -> [state]
(define (scanf init procs)
  (if (null? procs)
      '()
      (let ((value ((car procs) init)))
        (cons value
              (scanf value (cdr procs))))))

;; draw as ASCII art

;; [state] -> [[boole]]
(define (to-bitmap ps)
  (define (range xs)
    (list-ec (: i (apply min xs) (+ (apply max xs) 1)) i))
  (define (orlist ls)
    (cond ((null? ls) #f)
          ((car ls) #t)
          (else
           (orlist (cdr ls)))))
  (define (in? x xs)
    (orlist (map (cut equal? <> x) xs)))
  (let ((codes (map car ps)))
    (list-ec (: x (range (map car codes)))
             (list-ec (: y (range (map cadr codes)))
                      (in? (list x y) codes)))))

;; [[boole]] -> string
(define (draw bitmap)
  (string-join
   (map (lambda (y)
          (string-join (map (lambda (x) (if x "#" " ")) y)
                       "" 'strict-infix))
        bitmap)
   "\n" 'strict-infix))

(define (dragon-curve dim)
  (define (dragon i)
    (if (> i 0)
        (append (nogard (- i 1))
                (list move turn-left)
                (dragon (- i 1)))
        '()))
  (define (nogard i)
    (if (> i 0)
        (append (nogard (- i 1))
                (list move turn-right)
                (dragon (- i 1)))
        '()))
  (scanf (make-state 0 0 0) (dragon dim)))

(define (main args)
  (print
   (draw
    (to-bitmap
     (dragon-curve (x->integer (cadr args))))))
  0)
$ gosh dragon.scm 8
     ####    ####       
    #####   #####       
    ####### #######     
      #####   #####     
 #################      
#################       
###### ### ########     
  ####  ## ########     
 ###       #######      
####       ######    ## 
####  #    ### ####   ##
  #####     ## ####   ##
  ####         #########
               #########
               ### ###  
                ##  ##  

なんかひっくり返ってますが、無事にドラゴン出ました。

2011/12/31

OLYMPUS SH-21 がきた

年末感あふれる進行でへろへろになりながら会社の納会に遅れてったら、余興の景品で豪華賞品を獲得してしまいました。オリンパスのSH-21。なんか今年はずいぶんカメラづいてるなあ。レビューを書く約束をしたのでファーストインプレッションを。

景品

帰宅してすぐに箱から出し、インテリジェントオートで何枚か撮ってみましたが、背面の液晶でプレビューすると、やたらに明るく写ってるけど何となくしゃきっとしない絵。設定いじれば変わるかなと思って、プログラムオートでいじってみるものの、さっぱり勝手がわからない。オールインワンカメラなんて、自分ではまず買わないタイプなので、かなり戸惑います。まあでもふだん使っているパナソニックのコンデジよりモノとしては楽しいので、翌日子どもと散歩に出かけるときに持って行こうと決めました。

翌朝、つまり今朝、散歩に出る前にフォーカスを合わせるコツをさぐりながら撮ったのがこれ。なんというひどいボケだw。こういう写真を見ると、ソフトウェアでは得られずハードの質で左右される部分がまだまだあるんだと自分に言い聞かせてD90用にレンズを買う口実になります。まあ、これくらい寄れるとそれだけで単純に楽しくなってしまうので、気楽に撮り流していくことにしましょう。

PC300002

このカメラ、背面液晶がタッチパネルになってて、タッチした場所でAFロックするようにできます。でも、それなりに明るい場所なら、従来のコンデジの要領でシャッターボタン半押しから構図を決めて撮るほうが楽でした。タッチパネルでAF操作するのに慣れてないわけではなくて、HTC Desireでは便利に使っているんですが、このカメラはタッチパネルの感度がいまいちよろしくない気がします。それにつけてもAFは楽ちんだ。

昨晩はしゃっきりしないと感じた肝心の絵ですが、晴天下ではずいぶん印象が変わりました。相変わらずインテリジェントオートはいまいちですが、プログラムオートにしてホワイトバランスのみオートにしてやると、完全にシャッター押すだけでソフトウェア支援をバリバリに受けたぱきっとした絵を快適に撮れるようになりました。

山手線

PC300035

キリンキャンディー

PC300036

無駄に広角側があるのもスナップにはうれしい。

PC300021

ライドオンストライダー

でも、こういう写真はむずい。

PC300060

暗いシーンでも何も考えずにシャッター押すだけ。

仲町商店街

日暮里

おもしろ機能として、パノラマが撮れちゃう。これはかなり興奮しました。このためだけに、これを登山に持っていこうと思った。高さが720ピクセルなのでPCで見るとそれほど迫力ないけど、背面液晶ではアニメーションでプレビューしてくれるので、かなり「おおっ」となります。

谷中コミュニティセンター

あと連写が楽しいです。これも背面液晶ではアニメーションとしてプレビューでき、やはり異様に楽しい。flickrが中心の自分にとっては、しょせん静止画なのでハンドリングが楽なのもうれしいです。ハイビジョン動画とか、正直もてあます。あれってみんな、撮影したやつをどうやって保管してるんだろう。もちろんこのカメラも当たり前のようにハイビジョン動画撮れるのですが。

もうひとつ、3Dが取れる機能があって気になってるのですが、背面液晶は3D対応じゃないので、3Dモニターがないと楽しめないらしい。残念。



別の日に撮影したものを追加しときます。



科学未来館

unsignaled signal

EXIF 情報が見られないのばかりで申し訳ないです。Eye-Fi → iPad 経由で Flickr にアップしたら EXIF がなくなってしまった。

2011/12/11

2012年賀状

年賀状書いた。

%!
<< /PageSize [285 420] >> setpagedevice

/fun { % y=x^2/81 for x<9, y=(x-18)^2/81 for x>=9
  dup 9 le {dup mul 81 div} {18 sub dup mul 81 div} ifelse
} def

/colwidth 62 def % set column width
/xoffset 15 def
/linehfactor 1.3 def
/fontsize 170 def
/numfont {
    /Sixties % /Bookman-Demi or /Times-Bold are also good
} def

/setrandcolor { % def
  /m exch def
  /r1 {rand 10 mod 7 div 1 m fun sub mul m 9 eq {1 add} if} def
  /r2 {rand 10 mod 7 div 1 m fun sub mul 0 add} def
  /r3 {rand 10 mod 7 div 1 m fun sub mul 0 add} def
  r1 r2 r3 setrgbcolor
} def

/centeringchar { % def
  dup stringwidth pop
  colwidth exch sub 2 div 0 rmoveto
} def % remaining a character string on top of the opstack

xoffset 0 moveto

0 1 3 { % for
  /i exch def
  i colwidth mul 0 rmoveto
  [3 1 2 3] i get % map (+1) (2 0 1 2)
  /base exch def
  0 1 10 { % for
    /t exch def
    /num t base add 10 mod def
    /f {i 3 eq {12} {9} ifelse} def
    /h {t 9 mul fun 2 mul f add} def
    numfont findfont
      [fontsize 1 0 linehfactor h mul 1 0]
      makefont setfont
    t setrandcolor
    num 10 1 string cvrs
    currentpoint
      /y exch def
      /x exch def
    centeringchar
    true charpath gsave fill grestore
    0.5 setgray stroke
    x h y add moveto
  } for
  xoffset 0 moveto
} for

showpage

去年まではちゃんと印刷して写真をとっていたのだけど、今年は ps2pdf の出力を Scribd にアップするだけというていたらくです。

2012

2010年2011年と、ぐるぐる回す系のデザインが続いたので、今年は縦スクロールにしてみました。回す系より地味だけど、縦のセンターを合わせなければいけないので、カラム幅と文字幅をもとに座標を調整したり、座標のリセットをしたり、見た目から想像されるよりも手間がかかります。

ナンバリング風の演出は、最初は円周の割合でフォントの高さの変化率を決めてみたのだけど、どうにも格好がつかず、適当な二次曲線(上記の /fun )を使ったらなんかいい具合になりました。あと「2012」だけが目に飛び込むような配色に苦労した。

今回の作例で使ったフォントは Sixties というフリーフォントです。他の一般的なフォントを使う場合は、Bookman-Demi とか Times-Bold のようなひげのあるフォントがおすすめ。


ここから Ghostscript で TrueType フォントを使うときのメモを書くけれど、自分ではよくわかってない話なので、個人マシンで遊ぶときとか意外には参考にしないでください。

Web から入手したフリーの TrueType フォントを PostScript 遊びで使いたいとき、インタプリタが Acrobat なら Windows や Mac にフォントをインストールすれば勝手に使ってくれるけれど、Ghostscript ではそうはいかない。基本的な手順は、

  1. TrueType フォントの名前を調べる
  2. GS から見える場所に置く
  3. GS の Fontmap に登録(/usr/share/ghostscript/8.71/Resource/Init/ とかにあるやつ)
だけど、1つめの手順でつまずく。Font HOWTOとか読むと、こんな手が紹介されていた。
$ ttf2pt1 -GA -l latin1 Sixties.ttf - 2> /dev/null | grep FontName
FontName Sixties
フォントの置き場所もなかなか一筋縄ではいかなくて、Fontmap に絶対パスを書きさえすればどこに置いてもいいのかと思いきや、GS が見に行ってくれる場所(/usr/share/ghostscript/fonts/ とか)にないとだめっぽい。

Fontmap への登録も、システムワイドな Fontmap ファイルに直接書かないと有効にならないようで、今回は Sixties.ttf を /usr/share/ghostscript/8.71/Resource/Init/Fontmap にこんなふうに登録した。

%!
% See Fontmap.GS for the syntax of real Fontmap files.
%% Replace 1 (Fontmap.GS)
(Fontmap.GS) .runlibfile

(Sixties) (Sixties.ttf) ;

2011/11/03

TeX ユーザーの集い 2011 雑感

10月22日に催された「 TeX ユーザーの集い 2011」に参加しました。「ユーザーの集い」というゆるい名前にもかかわらず、主要パッケージメンテナが一同に会する円卓会議で標準的な日本語 TeX 環境に向けた議論がなされたり、 LuaTeX 日本語化の開発状況の報告があったり、単なるエンドユーザーの集まりとは思えない雰囲気で楽しかったです。

そんな雰囲気の中、自分は一人のエンドユーザーとして、パッケージメンテナの方々や開発者を含む「 TeX ユーザー」たちがどこを目指してるのかを考えてました。ざっくり言うと、こんな 2つのベクトルがあるような気がします。

  1. TeX は、数式や図を含む組版に使える便利なツールである
  2. TeX は、ドキュメントのための形式のひとつである

当日の発表も、どちらかに大別できそう。たとえば、インプレスさんや達人出版会、奥村先生の招待講演のうち美文書の話、それにオーム社の事例は、主に 1 の立場でしょう。 KeTpic も 1 ですよね。一方、村上真雄さんの招待講演や解析概論プロジェクト、 OpenOffice は、 2 という見方だと思います。 LuaTeX の開発や TeXLive の報告は、ひとによってどんな立場の話としても聞ける類の内容で、その意味では、発表者ではない参加者の立場もまた上記 2 つのどちらかに当てはめることができそうです。

自分が今年の「 TeX ユーザーの集い 2011」であらためて感じたのが、2 の立場の重要性でした。ドキュメントのあり方というか、そういうレイヤで TeX 環境をとらえるべきなのではなかろうかと思い直しました。

TeX 環境には、きれいな組版ができるという出力側の優れた機能と、テキスト形式であるという入力側の利便性、それにプログラミング可能という特徴があります。それらをうまく使うことで、ドキュメント構造とスタイルという 2 つの抽象を分離できます。「うまく使う」というのがポイントです。うまく使わないと、まるで分離できない。でもうまく使えば、 XML/CSS のような固定的な分離だけでなく、ユーザにとって都合のよい分離を設計することさえできるはず。プログラミング可能というのはそういうことです。

(だから、なにも原稿が XML である必要はないのです。とはいえ、現実には補助線もなく適切な分離を毎回設計してそれを守り抜くのは誰にでもできることではありません。漏れのない抽象化は至難。だから、原稿そのものは XML 風だったり Wiki 風だったりするテンプレートを使って書くというのも次善策でしょう。閑話休題)

こういう話、実は予稿集の「ごあいさつ」にもきちんと書いてありました。実行委員の方々が2の立場を意識しているからこそ、村上さんの招待講演に結びついたのだろうし、実行委員の皆様には本当にどうもありがとうございました。勝手なことを言うと、さらに武藤さんによる「 InDesign 自動組版の可能性と限界」とかあってもよかったかも。テキスト原稿から InDesign への変換ツールを使った商業出版は、自分もほかに知ってるし、けっこう事例がありそうですが、 TeX との比較とかできるのは武藤さんくらいではないかと。そういう、構造/スタイルをはじめとする抽象分離を意識したドキュメント全般の事例をもっと聞いてみたかったです。 LaTeX から EPUB への展開とか、 TeX ユーザーにとって直接役立つヒントも多いはず。(昨今の電子書籍ブームみると、これらが来年のネタの提案としてふさわしいかはちょっと疑問ですが。)

gdgdな内容ですが、だから雑感だといったでしょ。あと、山本さんと八登さんの発表はおもしろかったです。そういえば、上記 1, 2 のような立場だけでなく、おもちゃとしての TeX という路線もありますよね。

2011/10/24

コダクロームの自家現像(ただし白黒)

コダクローム(Kodachrome)というリバーサルフィルムがあります。というか、ありました。Kodak社ではコダクロームの製造を2009年6月22日に終了しています。だからいまはもう手に入らない。

製造中止そのものは、一部のファンには悲しいことだったのだろうけど、まあオールドメディアの終焉の一幕に過ぎません。コダクロームの本当の終了は、世界で最後の現像所が取り扱いを停止した2010年12月30日でした。これが「本当の終了」だったのは、コダクロームが自家現像のできないフィルムだからです。

現代のふつうのカラーフィルムは、フィルムそのものが発色の機能を備えています。だから、所定の薬品を使って一定の手順を踏めば、撮影した画像をカラーで取り出せます。そのへんの現像所はもちろん、おうちの台所でも現像ができるということです。ところがコダクロームは、フィルムそのものには発色の機能がなく、現像の過程で何段階か露光させることにより発色させるという特殊な方式でした(耳知識)。そのため、家庭はもちろん、そのへんの現像所でもコダクロームの現像はできません。だから2010年12月30日を最後に、それまで世界中で販売された未現像のコダクロームはただのゴミになってしまいました。ある種のDRMのようなものですね。人類はちっとも学習しない。

そんなゴミが、我が家からも一本発掘されました。とはいえ、古いカメラの中に入っていた撮影済みのフィルムを取り出したらコダクロームだった!という事情なので、個人的には安易にゴミ認定しかねます(どうせスナップではあるのですが)。必死になって調べてみたところ、どうやら英語圏では白黒ネガフィルムとしての自家現像にチャレンジしている人たちがいるようです。

というわけで、さっそく試してみます。

Kodachrome

プロセスは "Kodachrome in 2011 – Process as Black and White" というサイトのものを参考にしました。参考というより、まるまる利用。現像マニアというわけではないので、その程度が限界です。以下はあくまでも素人による結果報告なので、もし参考にされる場合は、撮影画像が抜けてしまう覚悟でお願いします。

水洗い
水道水(30°C だった)で攪拌しながら 3分。排水はかなり黄色くなります。
T-Max現像液で現像
標準希釈(1:4)、20°C で計 6分30秒。最初の 3分間を連続攪拌、50秒停止→10秒攪拌を 3セット。排水に 30秒
コダフィックスソリューションで定着
標準希釈(1:7)、28°C で計 8分。最初の1分を連続攪拌、50秒停止→10秒攪拌を6セット、30秒停止→排水30秒
水洗い
20°C の水で2分程度の攪拌後、水道水(30°C だった)からの流水で 15分
こそぐ
ちょっと何を言ってるのか分からないかもしれないが、アクリルたわしで感光剤のない面(つるつるのほう)をこすり、黒ずみのようなものをこそいだ。フィルムワイパーかければ取れるのかなと思ったら、けっこうしっかり付いてるので、感光剤を傷つけないように注意しながら、けっこうしっかり黒ずみをおとしてやる。勇気がいる。
ナニワカラーキットNの漂白定着液で処理
上記サイトによるとC-41の漂白をしたほうがヌケがよくなる、ということなので、いちおうやっておく。標準希釈で 1分攪拌し、すぐ排水。
ドライウェル
上記サイトではフォトフローを使っているけど、そんなものヨドバシカメラに売ってない
乾燥
子供が留守のあいだに

結果です。EPSON GT-X800 でスキャンしただけの状態。ソフトウェアでは手を加えていません。長いことカメラに入りっぱなしなのを考慮して、もっと現像時の水温を下げるべきだったと後悔してますが、何が映ってるかは判明したのですっきりしました。

11

8

4

出来上がりについては、わたしの現像が未熟なのをおいておいても、残念な感じだと思いました(ところどころある白点は、こそぎ切れかなった黒ずみと思われ)。今回のような事情でもない限り、わざわざ余っているコダクロームを使ってモノクロ撮影をするようなものでもなさそう。

最後にいいわけっぽく、このコダクロームが眠っていたオリンパスのペンFというカメラと、同じカメラによるT-MAX100による自家現像作例も張り付けておきます。10年以上前の香港のようすです。

14

15

16

Olympus Pen F with pancake

なんてすてきなレンズ!

2011/10/12

D90がきた

デジカメを買いました。それも、3年まえに発売され、すでにカタログ落ちしている Nikon D90 をいまさら購入です。まったくそんなつもりはなかったのですが、まる7年にわたって使い倒した D70 がいよいよデータ保存時に深刻なエラーを引き起こすようになって、サービスセンターに持ち込むつもりで Nikon のサイトをのぞいたところ、アウトレットで D90 のボディが 59,800 円で売り出していたのに引っかかってしまったのでした。でもまあ、D70 を修理するにしても2万円は出費を覚悟しなければならないし、買い換えるにしても D7000 はなんかちがうし、D90 なら当分は腐らないし、ニコンダイレクトで3年保証だというし。。

なにはともあれ、さっそく試し撮りです。被写体はいつもの FM-2 WILDCAT。下が以前とった D70。レンズはどちらも東独ツァイスのフレクトゴン35mm。

FM-2 WILDCAT 1/144 Sweet

DSC_0235

やっぱり画素数が D70 の二倍というだけで単純にバージョンアップ感ある(でも D70 のほうはなぜか画質が FINE じゃなかったっぽいなあ)。被写体は実はこんなに小さい。

FM-2 WILDCAT 1/144 Sweet

関係ないけど、久しぶりにSWEETのページをみたら二式水戦が新商品とな! パーツは2機分入っているのだろうし、これは二枚反転ペラに改造してオレンジに塗るしか。。

そして、おつかれさまの D70。問題の原因はわかっているので、そのうち自分で修理してから息子に与える予定。

D70 with Tamron 18mm-200mm

この D70 が最後に活躍したのが先週末の息子の運動会でした(閉会式で脈略なく担任でもない先生に抱擁されている図)。この運動会の写真をあやうく全部ロストしそうになったことで買い替えを決意したみたいなものなのだけど。chkdsk でも fsck でもどうにもならなくなってしまうと、さすがにねえ。

DSC_0088