パースのついた円とマウスの当たり判定をする

本サイトの姉妹サイト、「妖精⊸ロケット」では、WebGLを使ってウェブサイトを作るという実験を行っています:

これは「季節の歯車」です:

「季節の歯車」って、いったいぜんたい、何なのかって?

季節が毎年毎年一周してるのは、みなさんもご存知でしょう。ちかごろは、もう桜も散ってしまいましたもんね。

ところで。

なんで季節がきっちり正確に毎年一周しているのか、不思議じゃありません?

実はですね、…ここだけの秘密ですよ。

「季節」を動かす歯車、「季節の歯車」が毎年なんとなく一周しているから、季節は毎年一回だけ巡るのです。

じゃあ、その歯車が回るのはなんでなのかって?

それは、春香、夏美、秋葉、冬音の4人の精霊たちが、いつもは仲良く、時にはケンカしながら、「せかいの裏」でくるくる回しているからです。これも秘密ね。

春の次に夏がやってくるのは、春香と夏美が仲良くやってくれたから。

夏の最中に突然秋みたいな日がやってきたり、季節外れの台風がやってきたりするのは、…きっと、夏美と秋葉がたぶんちょっとした事でケンカしたんでしょうね。

でも大丈夫。ケンカしたら、仲直り。いつもそうやって、季節は巡ってきたのですから。

季節の歯車

…という創作神話(?)を元に、この季節を決める歯車である「季節の歯車」と、その結果生まれる「季節の巡り」をWeb上で表現してみようとしたのが、このWebサイトです。

もう少し常識的に言うと、左上の「歯車」の円周上に、それぞれの季節ごとの写真や絵、文章が並んでいます(これを「モーメント(瞬間)」と呼びます):

春はピンク、夏はみどり、秋はオレンジ、冬は青。…うーん、変えてもいいかな。

ここみたいな、いわゆる「ブログ」と違うのは、時系列で並べているわけではないことです。例えば、同じ「10月1日」の「モーメント」は、10年前のものでも今年の物でも、同じ角度のラインの上に並んで表示されます。

さらに、どの「モーメント」が表示されるかは、毎回ランダム(ガチャ)です。10年前の「モーメント」が表示されて今年の「モーメント」が表示されない事もあるし、逆もある。角度は同じでも、歯車からの距離は更新するたびに変わります。この点でも、2018年のページをクリックすれば必ず2018年のページが表示される「ふつうのブログ」とは異なります。

WebGLでウェブサイト作ろうぜ

えー。「季節の歯車」の紹介はこれぐらいで置いておいて。この季節の歯車を表現するための技術について、がこの記事のテーマです。

このウェブサイトは基本的に全部WebGLと、素のECMA Script 6で書かれています。くるくると回る「歯車」も「モーメント」も、全部WebGLで描いていて、HTMLの<img>タグとかは使ってない、と言うことです。もちろん、WebGLはCanvasの中身をOpenGLで描ける、という技術ですので、他のHTMLの技術と、簡単に組み合わせることもできます。「季節の歯車」では、「モーメント」の上にマウスが乗ると、タイトルが表示されるようになっています。この表示に使われているのは、いつもの<div>要素です:

この「モーメント」はこちら

3Dオブジェクトの当たり判定

さて、これで困るのは、マウスの判定です。つまり、マウスがどの「モーメント」の上にあるのか(あるいは無いのか)のチェック関数、です。

HTMLのmouseoverイベントは使えません。「モーメント」は全て、HTMLの要素ではなく、1つのcanvas要素の上にOpenGLで描かれている「絵」に過ぎないからです。

canvas要素のmousemoveイベントを使えば、canvas上でのマウスの座標を得ることはできますが、この座標もそのままでは使えません。というのも、「モーメント」も左上の歯車と同様、「遠近法」が掛かっている立派な「3Dオブジェクト」だからです。

まぁ、わざわざ「遠近法が掛かっています」と上でわざわざ書いたように、事実上ほとんど掛かっていないので、2Dだと思って当たり判定を書いてもほとんど困ることはない(見ている人が気づくことはない)かもしれません。

でも、せっかくだから「正確」に判定してみたい。趣味のプロジェクトですしね。

さて、こういう「3Dのオブジェクトとマウスの当たり判定」じたいは、ゲームではよくることです。3D空間内のアイテムをマウスでクリックして取得したり。このためのテクニックは「Object picking」と呼ばれているそうで、よくある実装は、「当たり判定」のための専用の画面を作ってしまうというものです:

OpenGL Picking Tutorialから引用

まず、オブジェクトごとに相異なる色で塗った「別の画面」を作ります。この画面は、ユーザーには見せません。ただし、あたり判定をする時は、この隠れた画面からマウスの位置にあるピクセルを読んで、「何色」になっているかを調べます。この色が何色かで当たり判定をする、と。例えば上の例だったら、一番明るい灰色だったら右のチェス、真っ黒だったら背景(何とも当たっていない)、といった感じです。

うーむ。たしかに、チェスの駒とか、人間、動物みたいな、複雑な形のオブジェクトがたくさんある中から当たり判定をしたいならわかります。むしろ、この方法を取らざるを得ないでしょう。

でも、ただの「パースのついた丸」のためにこれをやるのは何だか大げさというか、資源の無駄遣いな気がします。単純に2回絵を描かないといけないですし。「相異なる色」を用意したり、半透明になったりしないように配慮した別の描画プログラムをもう一つ用意しないといけないのも大変です。

もっといえば、この「別の画面を用意して、あたり判定を行いたいオブジェクトごとに色を塗る」という力技で当たり判定ができるのは「当たり前」すぎるように感じられます。ちょっと面白くない。

そこで今回は、それとは別のアプローチを考えてみましょう。

「遠近法」のおさらい

その前に、まずコンピューター3Dにおけるいわゆる「遠近法」をおさらいします。

「いわゆる」とつけたのは、「遠近法」と言えそうなものは、このコンピューターの世界の中だけでもたくさんあるからです。わたしの考えでは、ラスタースクロールも遠近法ですし、ゼビウスのゲームシステムも、「空気遠近法」と同じくらいには、りっぱな遠近法だと思います。

とはいえ、「季節の歯車」では、コンピュータ3Dの世界で「遠近法」という言葉で指すものの中では最もおなじみであろう、「透視法射影」を使っています。

これはどんなものだったのか、と言えば、表示したいモデルの頂点の三次元空間上の座標、x y z、そして最後に1を立てたベクトル(x y z 1)に、モデルごとの変換行列Mを掛けて、出来たベクトルをさらに最後の要素( wと呼ばれる事が多い)で割り、出来た(x’/w’ y’/w’)が画面上での最終的な座標となるのでした。

わかりにくいので、ちょっとベクトルがどのように変形されていって最後のxy座標になるまでを図にしてみました:

それぞれの操作を、数学で写像で移される時元の対応を表す、のマークを流用してその処理の流れを表現してみました。えっ、数学の世界でそんなに繋げるような記法は普通しない?まぁまぁ。うまい表記が思いつかなかったので、おもいついた人は教えてくださいな。

行列Mについて少しだけ話をさせてください。このMをうまく作ることで、モデルの平行移動や、回転、拡大縮小を表現できるだけでなく、最後にw’で割るという、行列のかけ算だけでは表現できない非線形な操作と組み合わせることで、遠いものほど小さくなる「遠近法(パース)」が再現できます。上手く作る、といっても、glMatrixなどのいわゆる3D向け行列ライブラリを使えばそんな難しくないです。とりあえず、この話はまた別の機会にいたしましょう。

さて、元々やりたかった事は何かというと、パースの掛かった「丸」とマウスのあたり判定でした。

ふむ。残念ですねぇ。何がって?パースの掛かった「三角形」とのあたり判定だったらすごく楽だったからです。あたり判定の対象が三角形であれば、上の操作で作ったスクリーン上の3つのXY座標で囲まれた三角形の中にマウスの座標があるかどうかを判定するだけで済みます。とはいえ実はその判定はそこまで簡単でもないんですが、やること自体は直感的です。

一方、パースのかかった丸となると、どうすればいいのやら。斜めになってるとぐにゃぐにゃした形になっていて、何をどうすれば内側になるのか判定できるのか、よくわかりません。

スクリーン空間からモデル空間へ

遠近法をつけた丸はぐにゃぐにゃしてて、なんかよくわかりません。となると、遠近法を付ける「前」の丸とマウスの当たり判定を行う作戦を取らざるを得なさそうです。遠近法を付ける前なら、単に「円の中心とマウスの座標の間の距離が円の半径以下か」判定すれば良いだけですから、三角形の内側にあるかどうか判定するよりも更にラクです。まぁ、点と点の距離を調べるのも、実は言うほど簡単じゃあないんですが…。

閑話休題。そうなると、問題は「マウスのポインタは、元のモデル空間では一体どこに存在するのか?」になります。さっきの図はモデル空間からスクリーン空間の話でしたが、今度はその逆、スクリーン空間からモデル空間への話を考えねばなりません。二次元から三次元上の位置を推定しないといけないので、ややこしそうです。

一つずつじっくり追い込んでいきましょう。まず、モデル空間上にあるマウスの点を(xm ym zm)、液晶画面上のマウスの座標を(xs ys zs)とします。マウスの座標にZ軸なんか存在しないのですが、あとで計算するときに便宜上必要になりますので「未知だが、存在する、何かしらの数」として導入します。

さて、目からマウスポインタを結ぶ線は液晶モニタの平面を貫通し、最終的に液晶モニタの後ろにある(笑)1モデルへとぶつかります。図にするとこんな感じです:

これらの(xm ym zm)と(xs ys zs)の関係を、書いてみます:

この図自体は最初に描いたものとほぼ同じです。

なかなかややこしいので、wsという(未知の)変数を新たに導入した上で(といってもw’mのエイリアス)、まず波線を引いた部分を変形します。

行列を掛けて出てきた、素性のよくわからんx’m, y’m, z’mを、すでに分かっているxsやysなどにできるだけ置き換えいって整理しようという作戦です:

さらに波線のwで割ってる部分も、xs や ws を使って割ってない所まで戻します。

すると、「モデル空間上の座標に変換行列Mを掛け算して移すと、スクリーン空間上の値を使ったよくわからんベクトルができる」、という図になりました(少なくともわたしはそういう意味でこの図を書いてます)。波線の引いた部分は「矢印の左側でベクトルに行列をかけると矢印の右側のベクトルになる」、という意味で使ってますので、おなじみの等号に書き直します:

未知変数の部分に赤線を引いてみました。xm ym zs wsの4つが未知で、Mは4×4の行列ですから、この行列とベクトルの式は実際には4本の連立方程式です。未知数が4つで、式が4本。原理的には解けます。やったね。zmは未知じゃないのかって?あー、言い忘れてました。今回の丸は、モデル空間上ではXY平面上にあることにしましょう。なので、zmはzm=0の定数です。

さて、この式は前述した通り解けるので、xm ym zs wsを求めたら、zsとwsは単に便宜上入れた要らない変数なので捨ててしまいましょう。モデル空間上のマウスの座標である、xmとymを使えば、無事円との当たり判定ができます。

はいおしまい、QED。

と言いたい所だが、この行列は実際一体どう解いたらいいのか?右にも、左にも未知変数があります。逆行列を一発キメたら終わり、みたいな、そういう生ぬるい式ではなさそうなのは確かです。かといって、プログラムに組み込んで自動で解かなければならない以上、「頑張って手動で連立方程式を変形して解く」みたいな高校生的解法は使えません。捻りが必要です。

頑張って式を変形するぞい

まず確認です。行列とベクトルの掛け算とは、行列の各行ベクトルを、もう片方のクトルのそれぞれの値で重み付けをして足し合わせることだと見なすことができます。

左辺

まず左辺をこれを使って変形します。Mを、M1からM4までの4つの縦ベクトルが横に並んだものだとみなすことにしました:

右辺

次は右辺です。右辺は、まずwとx y zが掛かっていて複雑なので、wをくくりだします。

赤線を引いた未知変数がだいぶ減って気楽な感じになりましたが、まだベクトルの中と外に未知変数が入っていて扱い方がわかりません。さらにこれをこんな感じで2つのベクトルの和に変形します。

するとどうでしょう。右辺も左辺も、「「未知のスカラ量 x 既知のベクトル」の和」に変形できました。

なんとなく、これなら扱えそうな気がしてきません?

最後の一捻り

さっき変形した右辺と左辺の式を使って、再度等式を書いてみます:

するとただの和なので、簡単に未知変数を左辺だけに集約することができます:

で、ここで最後の一捻りです。

さっきの

行列とベクトルの掛け算とは、行列の各行ベクトルを、もう片方のクトルのそれぞれの値で重み付けをして足し合わせることだと見なすことができます。

というのを、今度は逆回しにします。つまり、こんな感じでもう一度「行列とベクトルの積」に書き戻します:

ここまでくれば、もう簡単。赤線が引いてある未知変数が詰まってるベクトルの値は、逆行列を掛ければ一発で求められます。

長かったですけど、纏めてみると結構綺麗な解法のような気がする。…どうかな。

JavaScriptで最小のデモ作った

「季節の歯車」だとここで実装してるんですが、流石に他のコードも多くてわかりにくいだろうという事で、この当たり判定の部分だけ切り出したサンプルを作ってみました:

github.com/ledyba/__sample__3d-picking-without-shaders
パースのついた円とマウスの当たり判定をする

実際に動いてるデモのページはこちら

  1. でも、最初にプレステのゲームを遊んだときは、そんな感じがしませんでした? []

「さきゅばす」の開発をやめて悪魔を祓い、苦楽を共にした彼女を追悼する

かつてわたしと苦楽を共にし歩んできた「さきゅばす」は、いまやゾンビとなり、インターネットの地下倉庫で、苦しそうに彷徨っている。

だから、せめて…生みの親であるわたしがシャベルでその息の根を止めて埋葬し、わたしは新天地へと向かわなければならない1

さきゅばす」とは何だったのか

「さきゅばす」は、「ニコニコ動画レコーダー」である。

一言で伝えられる短いキャッチコピーを考えるのにも10年掛かり、最近やっとここに着地した。やめるけど。

えーっとね。ニコニコ動画の動画ビューワは、投稿された動画の上にコメントの文字列を再生するたびに毎回重ね描き2して表示しているんですが、その代わりに既に最初からコメントが描きこんであるような動画を生成するソフトウェアです。

こんな感じの動画が作れます:

レッツゴー陰陽師

きしめん/Nursery Rhyme

12年半ほど間欠泉のように開発してきたこのソフトウェアですが、もういい加減、開発・メンテという形で関わるのは、もうやめようと思います。

わたしは株式会社ニワンゴ・ドワンゴ・カドカワとは雇用契約以外も含めた一切の金銭的な関係を持ったことはなく、決してこれは退職エントリではありません。そもそも、ただのOSSだし。

とはいえ、ある意味では雇用契約よりもはるかに強い、「悪魔と契約純粋な趣味として」して作ったソフトウェア3ですので、強いていうなら「退魔・追悼エントリ」でしょうか。てなわけで、こんなタイトルになった。でも俺は悪魔と契約しちまった以上、死ぬまで魔女はやめねーかんな。なぜなら、悪魔との契約は生涯有効だからだ。

引き継ぎ資料

さてさて。とはいえ、「さきゅばす」をまだ必要としている人はまだいるでしょうし、開発を引き継いでくれる人がいるなら、それが一番なのは間違いありません。そんなわけで、引き継ぎ資料を作りました。

ただしおそらくこのドキュメントを見てコマンドを打つだけでは、ビルドと実行まではできても、最後まで動画を変換しきることはできず、いくつかの箇所でエラーでコケると思います。(引き継ぎたいあなたへ:悪魔と契約するんだ、デバッグとソースコードの修正をする覚悟ぐらいは持っておくれ)

さて以下では、こんな感じで10年間降り積もった同窓会的なよもやま話を延々といたします。どんな気持ちで作ってたのか知りたかったら、読んでみてね。長いよ。

どうしてやめるのか?

他にやりたいことがあるから

やりたい事・作りたいものが、たくさんあるからです。

死ぬまでに作りたいもの、上手になりたいこと、知りたいこと、研究したいこと、描きたいこと、記したいこと、見たいもの、…そんなものが両手で数え切れないほど、たくさんあります。でも、人間には寿命があり、いつかは死んでしまいます。すべてを行うことも、見聞きすることも出来ません。最近ついにそこに気づきました。

そうして天秤に掛けた時、「さきゅばす」からは、…「彼女」からは、もう、知りたいことは全部教わったし、作りたいものは全部作ったし、描きたいものは全部描いたし、研究したいことは研究しつくしたし、見たいものはもう全部見せてもらいました。

…つまるところ、さきゅばすでやりたいことは、わたしには、もう残っていないのかなぁって。

ニコニコ動画を見ていない

ニコニコ動画を(古いお気に入りの動画をふとたまに見たくなった時以外)全く見ていない事に気がつきました。すこし昔は「アニメを見る時ぐらいはニコニコ動画」だったような気がするのですが、最近はそれもやめ、アニメを見る時は1人でじっくり鑑賞し、噛みしめるように見ています。

そんなわけで、ニコニコ動画を使っていないわたしには、ニコニコ動画の作りやすいツールは、流石にもうこれ以上作れないと思いました。…せいぜい動き続けるように、メンテできるだけ。

でもそれって、「ゾンビ」そのものじゃないですか。わたしは、そんな彼女の姿を見たくはありません。

必要性が薄まった

さきゅばすは元々は100万回もダウンロードされるために作ったソフトウェアではなく、2007年6月当時の個人的な欲望と興味と関心を具現化するため、高校にもロクに行かずに引きこもりながら実験的に作ったソフトウェアです:

  • PSPでニコニコ動画が見たかった
    (PSPにはニコニコ動画アプリのようなものが無かった)
  • 2007年当時の環境では、弾幕4が重く、PCの性能不足でプレイヤーがコマ落ちしてしまった

でも、2019年現在では、スマホアプリも、各種ゲーム機向けのプレイヤーもあります(端末別ヘルプ、PSP向けはついぞ出なかったようですが)。お気入りの端末でニコニコ動画が見られない、なんて事は、もう無いと思います。変換した動画ではなく、各アプリなら、コメントを見る見るだけでなく投稿することだってできますし、他の動画の検索だってできます5

性能面に関しても、2019年のスマートフォンでも十二分すぎるほどの性能があります。実はスマホをもう持ってないので分かりかねるのですが、「コメントがたくさん出たら画面がカタカタになった」なんて事態は、おそらく流石にもう無いんじゃないでしょうか。少なくとも聞いたことない。

投稿されたコメントアートを残したい、という需要があるということが、orzさんやそれを通じて知り合ったコミュニティを通してわかったのですが、2019年現在では、2019年に投稿されたコメントアートを保存する最善の方法は、おそらく単に録画する事のような気がします。もっと言うと、2019年のパソコンには、それをやるだけの十分な計算資源があります(逆に言うと、2007年当時は、再生された動画をリアルタイムに録画するのはとーっても大変でした)。もちろん、過去に投稿されたコメントアートを今ここで再生・保存したいなら、当時の挙動を再現するコードを書くしかなく、そこに「彼女」の居場所が生まれうる、とは思います。

デフォルトでは動画全体を通して最大1000コメントしか表示されないところを、無理やり数万コメントを突っ込んでコメントで溢れさせる弾幕動画を作るのは…もういいかな。やりたい人が居たら、わたしの代わりに、彼女を召喚ビルドしてお願いしておくんなし。

うーん。

こうして箇条書きにして当時の「モチベーション」とやらを書き出してみたのですが、いくら書いても、ここからこぼれてしまう部分があるような気がします。人はそれを、「情熱」とか「熱意」と呼ぶのでしょうか…。よくわかりません。

…なんだろ、tcpdumpでdumpしたパケット眺めてさ、ActionScriptを逆コンパイルしてさ、ffmpegのソースコード読んで書き換えてコンパイル通してさ、ニコニコ動画の弾幕コメントを表示させるのは、仮に何の意味もなくても、確かにどうしようもなく楽しかったよ。

誰も認めてくれなくても、それがわたしの青春の1ページだ。

さきゅばすの作り方

「資料なんかどこにもないのに、どうやって作ったんですか?」と以前聞かれた事があるので、文章にして残しておきます。

WebAPIの叩き方→tcpdump

ニコニコ動画のサーバから、動画とコメントをダウンロードする方法は、単にブラウザの挙動を追いかけて推理しただけです。ただし、F12を押すと出てくる「開発者ツール」のような便利なものなど存在しない時代だったので6、tcpdumpを使って、ニコニコ動画のサーバと自宅のブラウザが交換するパケットストリームを眺めて観察しました。観察した結果を元にAPIの使い方(リクエストを投げる時のXMLの書き方とか)の仮説をたて、それを確かめるためには、時にはtelnet nicovideo.jp 80ってやって直接手でHTTP/1.1のリクエストを投げて確かめてた気がします。今ではニコニコ動画もHTTPSに対応してしまい、通信はすべて暗号化されてしまったので、今では絶対できない方法ですね…。懐かしや。

コメントの配置方法→逆コンパイル

コメントの配置の仕方は、FlashのプレイヤーのActionScriptを逆コンパイルして、それをそのまま実装しました。今思うと、ちょっとヤバかったかも。でもそのおかげでそこそこ再現性は高かったんですよ。逆コンパイルすると変数名とかが全部「var1」とかになったソースコードが現れてきて、一般に解読はなかなか大変なのですが、当時はゲームのコピープロテクト外しも夢中だったので、「アセンブリじゃなくて、ちゃんとif文やfor文が出てくる!なんてわかりやすいんだ!逆コンパイラってすげー!」みたいな感じでした。…いまやれって言われたら、できるかなぁ。

コメントのレンダリング→適当 or 逆アセンブル

コメントの描画の仕方は、最初はSDL_ttfを使って適当にMSゴシック使って描いていたのですが、後にFlashそのものを逆アセンブル・解析して、ExtTextOutWというWin32APIを特定のパラメータで叩いてることを突き止め、cairoというライブラリでなるべく同じようにWin32APIが叩かれるように実装しました7。これも、今思うとちょっとヤバかったかな。ただ、この解析結果が実装されているのは、ゼロから書き直したSaccubus2だけで、引き継ぎ資料でビルドしてるSaccubus3は初期のバージョンである1がベースなので実装されていません。やりたかったらやってみてね。

ffmpegの改造方法→素直にソース読む

ffmpegの改造の仕方は…普通に変換してるところのソース読んで追いかけて、その結果をもとに、さきゅばす用にちょびっと改造しただけです。話を整理してみると、実はここが一番簡単かつ素直だったことが分かります。ただ、変化の激しいffmpegを改造して維持つづけるのは中々大変でした。この話はまた後でします。

アーキテクチャ図

ちなみに、全体のアーキテクチャはこんな感じです:

この図にして見ると結構複雑なアーキテクチャはどう思いついたのか?…うーん、思い出せません。でも結構素直ではあると思うんですが、みなさんはどう思います?

さきゅばすの思い出

ここからはさらに個人的な思い出話です。ガンガン回顧するぜ。

自宅サーバから配布しすぎてISPからアカウントを永久凍結された回

さきゅばすを開発した当初、このウェブサイトは自宅サーバの上でホスティングされていました。なので、開発したソフトもその自宅サーバから配信してました(当時のブログ記事)。

公開してしばらく経ったある日、とある「個人ニュースサイト(これも懐かしい響きだ)」で取り上げてもらって突発的にすごい人気が出て(今で言うとバズって)一週間で数万回とかダウンロードされるようになりました。

…それはそれでとーっても嬉しい話なのですが、5MBぐらいあるソフトウェアが1万回ダウンロードされると、50GBのアップロード・トラフィックが発生します。当初使っていたプロバイダは(安い代わりに)月々5GBまでしかアップロード・トラフィックを出してはならないという規約になってまして、そのうち見事にアカウントが凍結されてインターネットに繋げなくなり、ウェブサイトも公開できなくなってしまいました。そしてアップロード・トラフィックなんか気に掛けた事無かったので、理由もわからないままある日突然繋げなくなってすごい焦った…(そしてプロバイダからの紙のお手紙が後に届いた)。

当時は「なぜアップロードが…?」と思っていましたが、10年後ぐらいにデータセンターの運営をやるようになって納得しました。インターネットでは、電話と同じで、アップロードする側がお金を払う

つまりISPは、ユーザーがアップロードすればするほど損をするんですね。昔、ISPがP2Pを嫌がって規制したりしてたのも、結局最終的にはそこ(アップロードの増加による経済的損失)だったのか、とかも芋づる式に完全に理解しました。

毎月パソコン雑誌がなぜか家に届く回

人気が出た結果、複数のパソコン雑誌に定期的に収録してもらえるようになりました。収録されるとソフトの開発者は無料で献本してもらえるという習わしがあったので、ほぼ毎月のように様々なパソコン雑誌が届いてた時期がありました。しかし毎月毎月同じソフトが別の雑誌とはいえ収録されるというのも、今思うと不思議な話だ…。

Flash黄金期である2000年代前半に「ぶっこ抜き」という標語と共に生きていた世代だったので、「ネトラン」に収録されたときはちょっとした謎の達成感(?)はありました。

…何もかもが、懐かしい。

ユーザーは説明を読んでくれない

「さきゅばす」は上にも書いた通り「実験」として作ったソフトウェアでしたので、当初のUIは限りなく適当でした。どれぐらい適当かというと、文字を描くためのフォントのパスを自分で打ち込まないと変換できないぐらい、適当なUIのソフトだったのです。

そんなソフトですから、人気が出ると、すぐに「変換できません」という投稿でコメント欄があふれてしまいました。対応策は分かっていて、WindowsのMSゴシックのパスをデフォルトでハードコードしておけば、ぶっちゃけ大半のケースでは困りません。

が、せっかくJavaで書いたのにそれで乗り切るのは負けな気がして8、かといってWindows/Mac OSX/Linuxのすべてで適当なフォントを探すためのJavaコードを書くほどの気力もなく9、「Windowsの人は次にあるMSゴシックのフォントを打つか、フリーのフォントをダウンロードしてそのパスを入力してください」とダウンロードリンクのすぐ上に赤字でデカデカと書くという、今になって冷静に考えると一番ダサい解法で乗り切ろうとしたのですが、デカデカと書いたのにも関わらず、「動きません」というコメントの勢いが衰えることは一切ありませんでした。読んでくれないんだね。町中でダサいテプラを見るたびに、いつもこの事を思い出して、テプラ貼った人に心の中で同情してしまいます。

結局、最終的には腹をくくってWindowsの時はWindowsのシステムフォルダの中にあるMSゴシックのフォントのパスを発見してくるコードを書きました。

とにかく自動でとりあえず大半のケースでは動くようにすることがすごい大事で、人はとにかくログは読まないし、エラーメッセージも読まないし、ドキュメントも読まないし、でもコミュニケーションはする、という、人間へ対するある種の諦観を、このとき手にいれました。この諦観は、この後、他のフリーソフトを書いたり、仕事としてソフトを開発・運用をしたりする中で、何度も何度も強化されていったような気がします。

特定のCPUでクラッシュする

一時期、Crusoeの載ってるVAIO(まだSONYが作ってた頃!)を併用していたのですが10 、さきゅばすはこのPCでだけ、ときたまクラッシュすることに気づきました。トラブルシュートした結果、最終的にSDL_ttfのgccのコンパイルオプションでSSE2かなにかを無効にすると再現しなくなったので、おそらくSIMD命令の互換性がCrusoeでは怪しいのだろう、という結論に。

ただそれだけなんですが、なんというか、パソコンの裏側の、そのまた裏側を覗いてしまったような…見てはいけないものを見てしまったような…何か隠れていたものを掘り起こしてしまったような、そんな気持ちになったエピソードです。

cygwinとmingwの思い出

Windows上でPOSIX互換のプログラムを書くためのソフトウェアツールキットとして、MinGWcygwinがあります。前述したように互換性厨だったので、C言語で書いてあるコメントを描画する部分については、Win32APIを叩くのではなく、こちらを叩いて実装しました。MinGWだとpthreadが無いとかで(詳細は忘れた)、もっと楽なcygwinで当初は開発・配布してました。

cygwinを使ってコンパイルしたバイナリは、cygwin-1.dllに必ず依存するようになります。それ自体は別に問題ではなく、一緒にcygwin-1.dllを配布すればよい…のですが、ただ、他のソフトと同時で起動した時に、そのソフトが別のバージョンのcygwin-1.dllに依存していたりすると、異なるバージョン間で何かがぶつかりあってクラッシュしてしまうらしく、定期的に「動かないのですが」のコメントが来ていたので、頑張ってMinGWで動くように改修した記憶があります。もっというと出来る限り全部をstatic linkするようになっていった記憶が…あります…。

ソフトウェアのバイナリを配布して動かしてもらう場合、相手の環境は前もっては分からないので、かなり想定外な…ともすれば理不尽なエラーに出くわしたりします。…スマホの時代になっても、そのへんはあんまり変わらないかもしれませんねぇ。

ffmpegを改造しながら4〜5年毎日Jenkinsでビルドした

ffmpegの改造自体は結構簡単だったのですが、ffmpegは頻繁にアップデートされ、内部構造も結構大胆に変わります11。それに毎日追従して改造しつづけながら何年間も毎日Jenkinsでビルドし続ける、というのをしてました。ぶっちゃけ、この作業が一番大変だったな。

今思うと、別にそこまでする必要無いよな〜。でもDaily buildとかContinuous Integrationって文字列が、なんか、こう、かっこよくて…やってみたくてさ…。

コメント描画フィルタを実装する3つの方法

最初は、コメントを描画するために「vhook」という、画像から画像に変換するフィルタをDLLで注入できる機能を使っていたのですが、これはすぐになくなりました12

しょうがないので、avfilterでvhook相当の機能を足すvhextというfilterを書いてffmpegのソースに入れました。使うためのドキュメントはあっても作るためのドキュメントがなくてよく分からず、とにかくソースを読みながら手探りで入れたような記憶があります。

が、libavfilterを改造する方法だとかなり頻繁にコミットがコンフリクトしてその度に解決するのが辛かったので、Saccubus2ではまた方法を変え、libavdeviceにsaccubusという名前の仮想入力デバイスを作って、その仮想デバイスが動画のデコードとコメントの描画をした上で、後段のffmpegのエンコーダに渡す、という実装に変えました。

仮想デバイスの追加先であるlibavdeviceはそんなに頻繁に更新されないようで、あんまりconflictに悩まされなくなったような記憶があります。

さらに仮想入力デバイスにしたおかげで、動画のfpsを自在に変えられるようになったり、結構柔軟性は上がりました。ffmpegのAPIたくさん叩かないといけないから、大変だったけどね。

動画の長さをDLLへ渡すための、いくつかの方法

そうそう、コメント描画部分にわたさなければならない情報として、動画の画像とその時間やコメントそのもの以外に、「動画全体の長さ(秒数)」があります。

というのも、ニコニコ動画のコメントは投稿されたタイミングの1秒前から3秒間画面を流れるのですが、その3秒後が動画終了より後だった場合、コメントの描画開始タイミングを前倒しして必ず3秒間表示するようになっています13

この挙動を再現するには、コメントを描画しはじめる前に動画の長さを知っておかなければなりません。

そのために、当初はffmpeg.cの中で動画の長さが取得できるようになったタイミングの箇所を見つけて、そこに動画の長さを後で使うために記録しておくコードを挿入していた記憶があるのですが、ffmpeg.cはあんまりにも書き換えられまくってコミットがコンフリクトしまくるので、結局諦めて変換のためにffmpegを叩く前にffprobeコマンドを使って長さを調査する実装に変えたような…。

「ffmpegのプロセスを実行する回数はできるだけ減らしたい」みたいな、(今思うと無意味かもしれない)妙なこだわりがありました。その後に作ったSaccubus2でも仮想入力デバイスが長さを取得・計算していて、やっぱりffmpegのプロセスは変換ごとに一回しか起動しないようになってます。

追従し続けるにはmergeではなくrebaseするしかなかった

途中からgitを使ってffmpegの改造ソースも管理するようになったのですが(それまでは…どうしてたっけ…)、forkしたさきゅばす用ffmpegのリポジトリを本家に追従させるために、mergeするのではなく、定期的に毎回本家のmasterブランチからrebaseするという方法に落ち着きました。

「rebase絶対許さないマン」がいるのは知ってるし、その理由も頷けるんですが、1年に数千〜万コミットされるソフトにパッチをちょこっとだけ当てるというケースでは、rebaseにしておかないと、自分たちが加えた変更のコミットは大量のコミットログの中に埋もれていき、conflictを解消するだけのmergeコミットが数千コミットに一回ずつ現れるようになり、コミットIDも段々とぐちゃぐちゃになり、最終的に訳がわからなくなったので…。

歴史の管理をする、メタ・歴史管理ソフトがほしいです。

ニワン語の実装

わたしにとっての、初めてのプログラミング言語処理系の実装。それがニワン語の互換処理系(インタプリタ)である「ねこまた」でした。

ニワン語のsyntaxとsemanticsをまとめた不思議なサイトがあったので、だいたいそのとおりにC++でパーサとインタプリタを実装して、細かい部分に関しては、ニワン語で書かれた音ゲーを実際に動かしながら「文法エラーにならないように」syntaxを調整し、「実行した見た目が同じ挙動になるように」semanticsを調整していく、という感じで細部を詰めていきました。音ゲーが最後まで動いた時は嬉しかったな。

ココロの肩書きは一生有効です」と昔CPUの本の人は書きましたが、「初めて書いた本格的なインタプリタが、仕様書もなければ処理系のソースもないプログラミング言語の互換処理系であり、ゲームがちゃんと一本動いて遊べた」という、中々レアな肩書き(?)は、わたしのココロの中で、誰にも理解してもらえないかもしれないけれど、それ故に誰からも曇らせることができない、きれいで澄んだ輝きを、いまでも放っています。ええ、この文章を書いている瞬間もです。

ニワン語は、未踏で作ったシステムの一部であるプログラミング言語「ど〜なっつ」のアイデアの原型にもなっていますし、それは更に、今友達と書いてる小説と、そのゲームにもつながっています。

間違いなく、ニワン語とそのアイデアは、わたしの血肉の一部です。

そういえば元々のニワン語を作った人もなかなかのカワリモノで、結局ドワンゴを辞めてしまったと聞いたのですが、今はなにをしてるんだろう。一回一緒にご飯を食べながらお話したいなぁ。もしもこれ読んでたらTwitterでもMastdonでもメールでもこのコメント欄でもなんでもよいので、連絡してくだされ、頼む。

追悼の一環として、動いた音ゲーのTAS動画(フルコンプ)を再掲します:

このゲームの実装されていた元動画を今見たら、ふつうのPVに戻ってしまっていました。もちろん、もうニワン語は公式にサポートしなくなったのでそれが正しい挙動…なのですが。諸行無常。

このゲームだけでなく、他のニワン語を使った動画のプログラムも動いてました:

こっちも今みたら、普通の動画になってしまった…寂しい。

ニコニコ学会βとニコニコ超会議

そんな感じでだらだらソフトを書いていたところ、ニコニコ学会βというところで喋らないか、というお話を頂いて、2回(第二回最終回発表させていただきました。最初はさきゅばすの簡単な紹介とver2.0の自慢(笑)、次は、その後の近況報告みたいな感じかな。

…かわいいお洋服を着て好きなことが喋れたので、余は満足じゃ。

今では在宅勤務して働いてるぐらいには根っからの「ひきこもり」なんですが、大勢の前では意外と喋れるなぁと思って、そこが面白かったかも。

orzさんの貢献とコメントアート

途中から、orzさんという方がコミットしてくれるようになりました。なかなかシャイな人でどんな方かは分からないまま、いつのまにか見なくなってしまったのですが…お元気ですか。

orzさんが貢献してくれたのは主にコメントアートへの対応で、ソースコードを読んでバイナリを解析してるだけでは到底できない、コメントアートコミュニティの知見(例えばこういう知見)を踏まえた改修(や、ニコニコ動画のWeb APIの変更への追従)をしていただけました。ニコニコ学会βやorzさんを通じてコメントアートコミュニティの方とも知り合いになったり…ほんと、フリーソフト開発って何があるかわからないです。

ただ、正直に言うと、最終的にコメントアートはどうしても理解しきれませんでした。色々な意味で。ニコニコ動画への興味が失われかけてた頃に知ったからかなぁ。とはいえ、こういう事に真剣に取り組んで表現・実践・議論している人たちが眼の前にいるんだなぁ、というところを目撃できたのは、いい経験だったと思います。

ところでなんで「さきゅばす」なんですか

これも、

  • 「そもそも「さきゅばす」ってなんですか」

って聞かれるパターンと、

の2パターンがあります。ソシャゲの流行に伴ってえっちなサキュバスの知名度がむちゃくちゃ上がったので、近年は後者のパターンが増えました。10年以上も変わった名前のソフトを作ってると、そういうこともあります。

ではなぜ「さきゅばす」なのか。辞めるわけだし、そろそろ文章として残しておいても良い頃でしょう。

初期のバージョンを作ってた時(2007〜2008年ごろ)に、ニコニコ動画で違法にアップロードされた「ひぐらしのなく頃に」と「涼宮ハルヒの憂鬱」のコスプレAV14を見るのがお友達の間で流行っていて、その時にひらめいた連想ゲームです:

味のある演技15のコスプレAV→「えっち(?)だけど、なんかこわくて、夢の中に出てきそうな、おんなのひと」→サキュバス→「さきゅばす16」。

…そういえば気がつくとニコ動はホモビデオばっかになってノンケは完全に閉め出されてしまったな。あくしろよ。おっそうだな?

ちなみにアプリのアイコンがポケモンのムウマだった17のは、サキュバスは夢魔で、ムウマも夢魔だからです。

こういう連想ゲームは、今でもずっとやってますね。働いてる会社で流石にやりすぎって戒められた事もあるぞい。人間、そうそう変わるものではない。

最後に

これを書いている間、ずっとsm9「レッツゴー陰陽師」を聞いていました。当時は「電波ソング」とゲラゲラ笑いながら聞いていたのですが18、今聞いてみると…結構いい曲だなって思っちゃった。となると、このブログ記事も「電波ゆんゆん」でしょうか?

というわけで、最後に「レッツゴー陰陽師」の気に入ってる一節を引用して終わります。矢部のピコ麻呂に「さきゅばす」も成仏させてもらうか、そこまでは許してもらうか、わたしの中ではまだ結論はついておりません。

辛い時、悲しい時、人はそんな時心の隙間に闇が出来る。
その心の闇に”魔物”達は容赦なく入り込んでくるのだ。
だから、苦しくても、くじけるな。落ち込むな。くよくよするな。
何事にも屈しない強じんな心こそが、最強の武器なのだから。

カドカワ、最近は元気がないようですが頑張って。陰ながら、応援しています。

  1. 元ネタ: https://gakkougurashi.com/ []
  2. 初期はFlash、今はWebはPixi.JS、スマホやゲーム機は、またそれぞれ別の技術 []
  3. あとで書きますが、サキュバスは悪魔の名前です []
  4. たくさんのコメントが一画面上に同時に表示されること []
  5. 「あえて出来ないのがよい」という価値観も、わたしの中に無いではないんですが []
  6. JavaScriptのデバッグのためにalert()使ってた時代といえば伝わるかな []
  7. どうしてWin32APIを直接叩かなかったのかはちょっと思い出せない []
  8. 当時は移植性厨だったので []
  9. そもそもmac持ってなかったし []
  10. バッグに入れてイヤホンつないで音楽聞きながらちゃりんこ乗ってたぜ。スマホで聞きながら走ってる連中より10年早くな! []
  11. libavというフォークもこの間に生まれた…まだ仲直りしてないのかお前ら []
  12. 最初のリリース時点ですでにdeprecatedだったのでしょうがない []
  13. なので最後の3秒だけは特にコメントの密度が高い []
  14. 流石にR18のところはカットされてた気がする []
  15. 穏やかな表現 []
  16. 英語表記のsaccubusも、普通の表記のsuccubusからちょこっと捻ってます []
  17. 今思うと著作権的に完全にアウト []
  18. この言い回し、最近聞かなくなりましたね []

俺もココアだ―「ご注文はうさぎですか?? Wonderful party!」

今日一週クリアしたんですが、エンディングの日はちょうどクリスマスの朝だったので、スケッチするように感想をさっと書き留めておきたいと思います。

ネット上ではこの画像で(一部で)有名なゲームです:

ですが、このゲームは実はココアさん「だけになる」わけではないです。いわゆる「個別ルート」に入って以降は、あなたはチノちゃん、リゼちゃん、千夜ちゃん、シャロちゃんのそれぞれに「なります」。いいか、なるんだよ

原作と同様、物語に大きな起伏があるわけではありません。異世界チートもないし生死を分ける戦いもないです。

前半では、あなたはココアさんとなってチノちゃんの誕生日を最高のものにすべくバイトとチラシ配りを一生懸命がんばって誕生日パーティを開き、
後半では、(チノちゃんルートでは)あなたはチノちゃんとなって、誕生日のお返しとして、たのしいクリスマスパーティを開くべく、人付き合いの苦手な彼女なりに奔走する。

それだけです。あえて悪く言うと、淡々としてます。人によっては退屈だと思うかもしれないくらい。

ですが、それでいい。

「グッドエンド」と呼ばれているものも、いわゆる普通の美少女ゲームと比べたらなんてことないです。「日常のささやかな一コマ」の範疇に収まってしまうかもしれません。でもそれでいいんです。なんでそれでいいのかわかりませんが、それでいい。

物語は、ココアさんがチノちゃんの誕生日(12月4日)が数週間後に近づいていることを知るところから始まります。

そしてココアお姉ちゃんは決心します。今年のチノちゃんの誕生日を、最高のものにしよう、と。

そのために、バイトを頑張って、あとコスプレしてチラシ配りをして、ラビットハウスの知名度をあげて喜んでもらおう、と。

…かなり発想が飛躍しています(たぶんシステムが決まってからシナリオが逆算されたんだと思う)。が、物語の中で「あれ?なんでチラシ配りしてたんだっけ??」ってココアさんも忘れる描写があるのでOKです。これを書いてて、わたしもなんでチノちゃんの誕生日のためにチラシ配りしてたのか忘れました。俺もココアだ

バイトのパートは正直難しいです。たくさんのオーダーにワーキングメモリが押しつぶされそうになります。でも、それもチノちゃんの誕生日を最高のものにするためです。バイトがうまくいってラビットハウスの知名度が上がるとなぜかうれしいのです。

チノちゃんの誕生日までに特定のキャラクターとの親密度をあげるか、ラビットハウスの知名度を最大にあげないと、(チノちゃんは喜んではくれるのですが)そこで物語は終わります。ここで「もっとチノちゃんに喜んでもらえる、最高の誕生日にできたはずなのに」という、悔しさにも似た感情が発生します。チノちゃんにモテなくて悔しいんじゃない、チノちゃんの誕生日を最高のものにしてあげられなかったことが悔しいんだ。これでは俺はお姉ちゃん失格だ。

チノちゃんの誕生日を最高のものにすることができたら、そのお返しとしてのクリスマスパーティを準備する、第二の物語が続きます。
この時は、(チノちゃんルートの時は)わたしはチノちゃんになります。

システム自体はいわゆる普通のギャルゲーで、三択したときに正解だと「友情度」が上がってエンディングが分かれるやつです。

でもそんなのはどうでもいい。チノちゃんになれば、自ずと選ぶべき選択肢はわかります。少なくともそんな気持ちになります。ほんとです。

あんなに素敵な誕生日を用意してくれたココアさんにお返しがしたい。でもわたしは、みんなでわいわいするパーティなんて開いたことないし、そもそもクリスマスといえばもっと慎ましく過ごすものだと思ってた。でも、そんなクリスマスじゃ、きっとみんな退屈しちゃう…どうしよう…。

チノちゃんは人に頼るのが苦手です。ですから、相談するのもいちいち憚ってしまう。ココアさんは相談してねと重ね重ね言ってくれるけれど、ココアさんにお返ししたいのだから、ココアさんには頼れません。最終手段です。

ラビットハウスはクリスマスももちろん営業があります。だから、一日貸し切って、なんてこともできません。仕事の後にパーティを開くしかない。そこがまたリアルなんです。

そんな彼女が出した「クリスマスパーティ」の答えは何か?これはもちろん遊んで確かめてほしいのですが、ココアさんのようなみんなを巻き込んだ盛大なものでは決してない、彼女なりのささやかな、でも一生懸命な素敵な答えです。


パジャマパーティーたのしそう

前半パートでは、毎週末集まってパジャマパーティがあります。これがまた楽しい。

そしてわいわい遊んだ後は、ココアさんとほかの誰かで一緒の布団で寝ます。添い寝しながら楽しく喋って寝る、それだけです。エロゲーは理解できなかったわたしでも、これなら理解できる。「ココアさんになれ」ました。楽しい。

「2人で一緒に寝たら残りの3人はどうしてるんだろう」と思わないではないが、そこは…きっと描かれてない3人の物語があるに違いない。


俯瞰してみると、「モバ美ちゃんPV」と同じく、「美少女 ⇔ 消費するオタク」みたいな構図を極力避けるようなシナリオとシステムになっています。ココアさん「だけ」になるんではなく、後半はほかのキャラクターにもなるので、一切片方向の視点で終わることがありません。ココアさんだけの視点でゲームが最初から最後まで完結していたら、きっとココアさんが実質的に「モテる主人公」になってしまっていたかもしれません。でも、このゲームでは、後半ではココアさんのために奔走することになります。ここがいやな感じが一切しない。

(機械仕掛けの不完全な)誕生日占い

その1

占い師「わたしは本物の霊能力者です。あなたの誕生日をあててさしあげましょう」

「ほんとに?」

占い師「ほんとです。あなたの誕生日の、月の十の位と一の位の差を教えてください」

「6です」

占い師「日の十の位と一の位の差は?」

「5です」

占い師「よろしい。それでは、月の十の位と日の十の位の差は?」

「5です」

占い師「最後に、月と日、十の位と一の位、すべての合計は?」

「13。」

占い師「6月16日ですね?」

「次の行列が正則ってだけじゃん」

その2

占い師「略」

「ほんとに?」

占い師「ほんとです。あなたの誕生日の、月の十の位と一の位の差を教えてください」

「6です」

占い師「次に、あなたの誕生日の、日の十の位と一の位の差に…さらに月の一の位を足したものを教えてくださいな」

「1です」

占い師「最後に、月と日、十の位と一の位、すべての合計は?」

「13。」

占い師「6月16日ですね?」

「次の行列が正則ってだけじゃ…」

「…あれ…正則どころか、そもそも3行しかない…。ほんものの霊能力者は、いるんだ…」

占い師「だから、そう言いましたでしょう?」

その3

占い師「略」

「略」

占い師「あなたの誕生日の、月の十の位と一の位の差を教えてください」

「2です」

占い師「次に、あなたの誕生日の、日の十の位と一の位の差に…さらに月の一の位を足したものを教えてくださいな」

「-5です」

占い師「最後に、月と日、十の位と一の位、すべての合計は?」

「13。」

占い師「Traceback (most recent call last):
File “/src/github.com/ledyba/tanjoubi-uranai/scratch.py”, line 92, in <module>
main()
File /src/github.com/ledyba/tanjoubi-uranai/scratch.py”, line 88, in main
  print(ndict[str(v2.tolist())].transpose())
KeyError: ‘[[13], [-2], [13], [-5]]’

「やっぱな。ちなみにわたしの誕生日は2月29日です。」

ソースコード

https://github.com/ledyba/tanjoubi-uranai

ストップウォッチで計測した月の大きさから、月の直径を計算する

今日の朝、ストップウォッチと電線を使って月の天球上での直径を計測したところ、約0.6度と出ました。

…さて、この値はどこまで正しいのか?

それを確かめる一つの方法は、「正解」を直接ググることです。が、それはあんまりにも面白くない。

そこからは少し離れた情報との整合性を、確かめてみようではありませんか。

それは、月の距離と直径です。それぞれ約38万km、3500km。小学校教育と中学受験のせいかおかげか、脳の中に、刷り込まれ、今でも、亡霊のようにこびりつき、こだまする、この「「「事実」」」と、どれほど一致するのかの概算をします。

三角関数で計算する

月までの距離と、月の天球上での直径(角度)が分かれば、三角関数を使って月の直径を計算することができます:

>>> 38*10000 * math.sin(0.6*math.pi/180.0)
3979.277964173401

実際に数値をいれて計算すると、約4000kmと出ました。文部科学省の提唱する「約3500km」と比べるとちょっと大きいですが、倍か半分ぐらいまでの差は出るだろうな思っていたので、それに比べたらだいぶ近い値が出ています。正直、ちょっと驚いています。

テイラー展開でも計算する

さて、仮に文明がいますぐ何らかの理由で崩壊し、コンピュータの提供する便利なsin関数が使えなくなっても、0度近辺でならsin(x)はxで近似できる(テイラー展開)ことを知っていれば筆算で計算することができます:

>>> 38*10000 * (0.6*3.14159265358979/180.0)
3979.3506945470676 #ほんとに筆算しようと思ったが、めんどくさくなってやめた

上の数値と見比べると、38万kmも先のことを計算したのに、100mも差は出ません。実を言うと大学受験の数学や物理の問題か、大学の数学や物理の試験問題でしかテイラー展開なんか使った事がなかったもので、ここまで差が出ないのかと、またもや驚いています。

しかし、でも、ちょっと大きい。

とはいえ、この結果は、教科書に書いてあった「約3500km」に比べるとちょっと大きいのも事実。この計算につかった「約0.6度」は、地平線近くで測ったものです。地平線の近くにある月は、なんとなく、空の上にある月より大きい気がしませんか。それは人間の錯覚なのか、それとも何らかの理由(大気の屈折とか?)で本当に見かけ上大きくなっているのか。

空の上の方の月でも測定して、もう一度同じように計算してみたいです。

しかし、天気予報によれば、これから先しばらく曇りとのこと。

うーん…次の半月か満月の晴れた夜までに、使えそうな電線を見つけておくことにするか。

ストップウォッチを使って月の大きさを測る

月を眺めていると、その動きはかなり速いことに気が付きます。

昔のアニメのお歌で「ぼくもわざと立ち止まれば 月も立ち止まる」なんてことばがありましたが、実際に立ち止まってみると、そんなことはありません。動いてるのが目視で分かるくらいの速度で、ゆっくりですが、「歩いて」います(もちろん、だからこのお歌はだめ、なんてことはないですよ)。

さて、このことを使って月の大きさを測ってみました。

方法

月の進行方向と、できるだけ直交する電線を選びます。適当な電線に月が触れるのを眺めたら、ストップウォッチで測定を開始します。そして、月が電線から離れた瞬間に測定終了。その時間を記録して「月の大きさ」とします。「時間」ですが、「大きさ」です。

電線と月の移動する向き(進行方向と呼ぶことにします)は一般にはさまざまな角度をなします。電線と月の進行方向が直交することも、ほぼ同じ方向になることも、ナナメになることも、あるでしょう。「月が電線を横切る時間」を、「月のどこかが電線に触れてから月が完全に電柱から離れるまで」と定義すると、この電線と月の進行方向がなす角度によって、時間が変わってしまいます(すんごい極端な例を考えるとはっきりします)。

月と月の進行方向の直線がまじわる2点を基準にして、この2点が電線と触れる時間と定義して測れば、電線と進行方向の角度の影響を無視できそうな気はするのですが…

まぁ、練習が必要そうなので、今日は「電線と進行方向ができるだけ直交する」一番単純な場合を使って測定します。

結果

4月21日 朝

今日は満月から1日ほど経ったころ。測定結果は次の通りです:

  • 2分16秒
  • 2分23秒

今日は水平線近くが白くて区別がつかなくなってきたので、3度目は断念しました。

約2分20秒とすると、月は29.5日で公転し、地球は1日で自転するので(意図的に細かいところをあえてガン無視している)、このことを使って計算します。

% python
Python 2.7.16 (default, Mar  6 2019, 18:14:51) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> moon = 360/29.5
>>> earth = 360.0/1.0
>>> (moon+earth) * 140 / (24*3600.0)
0.6031073446327683
>>> 

天球上の角度はだいたい0.6度?ってことでいいのかな?

今後

理科年表にひょっとすると月の大きさが書いてある気がしてならないのですが、見ないで独自研究をすすめてこうかな。ちょっと悩んでます。

月の満ち欠けみたいに 幸せも 大きくなったり 小さくなったりする」なんて歌詞もあるとおり、月には満ち欠けもあるわけですが、今回の方法を使って月齢を(定量的に)測れたらちょっと面白い気がしています。この場合、月の進行方向と電線の角度にはもっと気をつけないといけないでしょうなぁ。

あとは…そうですねぇ、地平線の近くにあると月は大きく見えるわけですが、これが本当なのかどうか、実測してみたいかも。

太陽

太陽も測ってみたいが、どうすればよいのか…陰を使えばいいのだろうか。

ストップウォッチやめたい

ここでテクノロジーに頼ってるのすこし違和感があるので、ストップウォッチもやめたいんですが、時間を測定するいい道具ないかな。月が電線を横切る時間と、一日の長さ(「日の出から次の日の日の出までの間」としましょう)を同時に測定できる道具…なんだろ。

ホウレンソウの移植と間引き

移植(11月11日)

タネを蒔いたホウレンソウは順調に芽吹いて育っています。これがなかなか嬉しいんだな。あとで殺して食べちゃうと知っていても。芽吹いてうれしい、本葉が出たらまたうれしい。

とはいえ、タネというのは必ず芽吹くというものではありません。研究成果を出すことを義務付けられる大学院生とは違うのです。

結果として、たくさん芽吹いているところと、あんまり芽吹いていないところに分かれます。

このままでもいいのですが、せっかくなので他の混み合っているところから引っ越しに来てもらいました。

小さめのスコップで根っこを傷つけないように移植します。間違っても引っこ抜いてはいけません。双葉の状態で移植して一週間たちましたが、本葉も出てきたのでうまくいったようです。よかったよかった。

そうそう、このブログで「移植」といえばもっぱらソフトウェアの移植でしたけど、植物の移植はtransplant、ソフトウェアの移植はportingで英語だとまったく言葉が違うらしいです。知ってました?

間引き

たくさん芽吹いてくれたホウレンソウですが、悲しいかな。すべてを育てることはできません。そうしないと、場所(日光)を取り合って大きく育ってくれないからです。

というわけで間引いていきます。根っこごと取ろうとすると隣の株の根っこを傷つけてしまうかもしれないので、ハサミでチョキン、でございます。まるで介錯だなぁと思いました(小学生並みの感想)。

before
after

せっかくなので(?)ちょっとずつ間引いていきます。「株の間は3cmあける」との事なので、数日かけてちょっとずつ間引いていこうかと思います。間引くのはundoできないから、慎重にね。

2つずつタネを置いていった結果として、2匹同時に芽生えて隣り合わせで生えているところがところどころあります。わたしはこれに「姉妹」と名付けて遊んでいたのですが、片方は間引かないといけないのかと思うと今から気が重い。

間引いたホウレンソウも食べられます。今日は普通にサラダにして食べました。草って感じの味がした(小学生並みの感想)。

そうそう、混み合っているところのホウレンソウは双葉の下のくき(株元)が長い気がします。…一生懸命、混み合ったところから離れようとしたのかもしれませんね。わたしも混み合ったところから逃げたい。

「ガチャ」でいいじゃん

もう分かんなくなっちゃったよ。

「いいね」の経済学で動くSNSとUGM。感想とキュレーションの循環参照。広告とマーケティングが支配する商業サイト。アイドルの焼き直しみたいなYoutuber。自前でコンテンツを用意してる検索エンジン。テレビの再放送みたいな番組を自前で作ってる元本屋・現なんでも屋。

…そして、無限のリコメンデーション。

わたしが1999年に、Googleの検索ボックスにキーワード入れて遊んでたころに夢みてた「集合知」とか、「インターネット」って、こういうものだったっけ?

うーん。でもちょっと待って。

そもそもGoogle、あるいはPageRankって、そこまで良いものだった?

美化された思い出に、過ぎないんじゃないの?

PageRankは「うまく動いてた気がする」

…ただしGoogleの中身について、誰も知らなかった時は。

つまり、Googleが登場した瞬間は、たしかにうまく動いていたような気がするのです。gooよりもGoogleがいい。なるほど、”gle”の部分が効いているんだね。そんなつまらんジョークを言っていたのは今でも覚えています。

しかし。

今思い返すと、「どう優れていたのか?」という質問に対して、具体的なエピソードで答えられないのも事実です。だから、「Googleが優れていたと思っていたのも、結局、『海外のなんか凄いテック企業、面接でヤバいこと聞くおもしろ会社』という幻影と神話に、化かされていただけでしょ?」といわれたら、言い返せない。

…そもそも「優れた検索結果」って何なんでしょう?

検索エンジンは、なぜ必要か?

そもそも論に立ち返りましょう。

検索エンジンは、なぜ生まれたのか。時計を巻き戻し、1999年へ戻るのです。

時は世紀末。「インターネット」というなんか新しいもんが出てきて。そこは「広大なネットの海」で、情報がたくさんあるけど玉石混交で、その中の有益な情報を見つけ出すぞ!というロマンに溢れておりました。

なるほど、有益な情報。…有益な情報って…何なんでしょう?

思い出して見ると、インターネットと図書館が対比されていたような気がします。「たくさん情報がある」という所からのすごく雑な類推ぐらいの意味でしかなかったのかなぁと今では思いますが。しかし、「図書館の代わり」を人々はなんとなく期待していたのは事実でしょう。

で、この「海」はあまりに膨大で、しかも本棚と違って、入り組んだグラフ構造になっていて、「ネットサーフィン」しているだけでは目的の情報(目的って何?)にたどり着けない。だから、検索エンジンってやつでなんとかするんだ!というのが、元々の「物語」でありました。

なぜ(山に登るのでなく)インターネットをするのか?

まぁ確かに、今日の天気や、今日行かないといけない場所や、ゴミの出し方、MySQLのマニュアルを調べるために数文字タイプすればいいのはすごい楽です。インターネットや検索エンジンは便利だなぁ。

しかし、それらを探すのに、PageRank…つまりページ同士の繋がりの情報はたぶん要らないんじゃないでしょうか。単に、転置インデックスとせいぜいTF-IDFとか使って中身だけを見ればわかるのでは。だって、namazuだって全然イケてるソフトウェアだったじゃないですか?

じゃあなんでTF-IDFとかだけではダメでPageRankみたいなアプローチが必要だと思われているのかといえば、…

それはたぶん、「SEO」があるからですよね。

SEO、体験の共有、共同幻想、目新しさ−
あるいは、テレビはなぜ代わり映えのしない濁流を映すのか?

Googleの結果はイケてたかどうかはともかく、イケてたと少なくとも私が思ってたのは事実です。そして、じゃあそこからどうなったかと思い出していくと、「SEO」が盛んになり、いたちごっこが始まりました。

「SEO」は、検索エンジンの結果の順位を、ページを作っている側が操作して「1位」になってやろうという行為です。

SEOがなんで行われるのかといえば。それは、みんな検索エンジンで読むページを探すから、ですよね。そこで目立って、人気のページになりたい。人気になるとなんで嬉しいのかといえば、サービスを使ってもらったり、読者になってもらって、もっと人気になって有名サイトになりたいから。

有名サイトであれば、その人気を、広告や影響力を通じてお金に変換できる。

そういう、「資本主義」の乾いた仕組みがあるからです。

だから、みんなが検索エンジンではなくSNSで情報を探したりするようになれば、SNSでバスる「フォトジェニック」とかのアプローチに変わる。スマホの「アプリ」をみんなが使い始めたら、スマホのランキングを操作しはじめる。それだけの話。

SEOも検索エンジンも、それ自体は、どうでもいいわけです。

そう。技術なんか、どうだっていいんです。「社会」で目立てりゃ、ウェブサイトでも、SNSでも、テレビでも、なんでもいい。

…というわけで、社会の話をしましょう。

この世はでっかいハンドスピナー

これは長くなるので今日は説明はしませんが、わたしの考えによると、社会1というのは大きな大きなみんなで回すハンドスピナー、あるいは盆踊りです。

みんなで一緒に同じことして、「いいね」と言い合ったり「ダメだ!」と断罪して喧嘩しあったり、そういうので一喜一憂してるとなんだか人生に「意味」がある気がしてきて、その「意味」に依存するのを「すがる」とか「大人になる」とか呼んでいる、と理解しています。(微妙にわたしの考えとは違いますが、「共同幻想」という言葉を当てた人もいます)

最近は「未知語」を検索する人が多くて、検索エンジンも未知語対策に重点を置いてるそうです。それも「社会は盆踊り」という標語の元ではすんなり理解できます。つまり、「社会の流行」です。盆踊りで皆と同じように踊ってないと「疎外感」を感じるように、同じ話題を追いかけたいのが人間、らしい。今あれが流行ってるらしい!って。何が流行っているかも、実はなんでもいい。フォトジェニックスイーツが流行ってるなら、その写真を上げて、いいねがもらいたい。流行ってる「猫の下着」の美少女イラストを描いて、いいねがもらいたい。流行ってるDeep Learningで研究して、いっぱい引用されたい。

ニュースと一緒ですよね。10年前の洪水の映像と、今日の洪水の映像、そんなに差はないけれど、今日というだけでなんとなく価値があって、世間話をするときのいいネタになる。そして、世間話ができると、人間は嬉しいらしい。

「夫 死んで欲しい」でサジェストされるのも似た話かもしれません。「共感」されたいのが人間、らしい。

で、人間ってのは社会性があって、偉いんだってさ。

無いと、病気なんだってさ。

ガチャ、あるいは「いいかげんインターネット」

わたしは、最終的にはインターネットっていうのは「己の心の中の世界を面白くしたりする」ためにあるんだ、となんとなく信じてたんだと思います。でも、どうやら、そうじゃなかったらしい。

でも。政治とか、ニュースとか、社交とか、人気とか承認とか、そういうのはもっともう、飽きてしまったのです。そういうのは、東大卒エリートで社会的地位のスペック競争に夢中な、インスタグラムに夢中な、「みんな」に任すわ…って感じ。心底うんざりしてるんです、もういいよ。

じゃあ、心の中に居場所を見出す「わたしたち」にはどんな物があったら面白いかな、と思って最近意識的にやってるのが「ガチャ」です。

検索エンジンなら、例えばあえてすでにしってるキーワードを入れて、なんか面白い結果が出ないかなと試して見たり。大半は失敗するのですが2、伝えやすい例としては、例えば「いいえ」って入れるとYahoo!が出てきて面白いとかですね。…伝わんないか。

あとは画像検索を使ったDeep Learning占いとか:

間違ってるような当たってるような
これ結果が一定しないんですよ。何で決まってんだろ。

散歩とかと似てるかもしれません。いつも見てる風景なのに、今日はこんな発見があった!こんな見方もできるのかって。

季節の歯車:人間がコントロールできないもの

「見せる側」からの例をあげます。

わたしは友達と「妖精⊸ロケット」というサイトをやっていて、絵や写真、文章などを展示(?)しているのですが、このサイトでは意図的に作品をランダムに並べ替えて表示しています。ただし、完全にランダムではなくて、写真も絵も「時間」が付いていることを利用して、一年のうちの季節に応じて円周上に並べています(これを、「季節の歯車」や「季節のしずく」と呼んでいます)

hexe.net: 妖精⊸ロケット

何が出るかはランダムですし、「キーワード検索」もできません。あえてね。でも、不思議かな、これで十分な気がしてくるのです。行き詰まった時に開いて10年前の紫陽花の写真を眺めると、色々考えが湧いてきたり。それもそれでいいじゃん、となんとなく思うのです。

「ガチャ」、つまり乱数での「ランキング」は絶対に「SEO」できないランキングであることも指摘しておきたいです。じゃんけんでランダムに出すのが絶対に相手が自分より優位に立てない「最強」の戦略なのと似てますかね。

 

みなさんは、どう思いますか。わたしは手探り状態です。

あなたはどうして、インターネットをしていますか。

あーそういえば。このブログのタイトル下に出てくる文章もガチャなんですよ。これはもう始めて12年といったところでしょうか。

  1. 例:政治、経済、サッカーチーム、学校、学会、宗教、町内会、恋愛、家族制度、SNS []
  2. 「ガチャ」ですから []

一年間遊んでみた

おひさしぶりです。明日から4月ですね…(◞‸◟ )。

この1年間、入ったばっかりの大学院を即休学して1年間ひたすら遊んでたので、今日はその話を書きます。

なんで休学したの?

人生に疲れたからです。

もともと高校の時は引きこもって大して学校行ってないような生活だったものですから、浪人のために予備校に入ってから大学を卒業するまでずっと学校に行ってたら、気が休まらなくて疲れてしまったみたいで。未踏もやったし「家族」という物語には失望したし、転学部もしたし。フルタイムのインターンとかもしました。いろいろあったなぁ(遠い目)。

去年の3月ぐらいにはいくつかのストレスが重なって限界に達してかなり精神的に参ってしまったので、休学することにしました。

大学院に深く入り込んでから休学しようとすると、色々休学をためらわせる要素が出てきそうだなぁ1、という読みもありました。正直もう限界だと思ったというのが一番大きいのですが。

休学するには一ヶ月ほど前に連絡して書類を出す必要がありますが、とくに面倒くさい審査とかはなくてほぼ100%受理されるようでした。休学する理由は「経済的理由」にしておくと、診断書みたいな書類が必要ないので一番ラクなようです。

方針

よく休学して「海外に語学留学に…」とか「被災地のボランティアに…」とか「世界一周で人間的成長を…」とか圧倒的成長するのが望ましいみたいな話がありますが、そういう事は一切考えず、とにかくなるがまま、何をしても、何をしなくてもいい、ぐらいの気楽な感じで過ごしました。

休学はいいぞ

休学するメリットを挙げていくぞ!オラオラ!

疲れが取れる

4月〜6月ぐらいはほとんどずっと寝てました。

休学する前はプールに行くと30分もすると疲れ果てて泳げなくなってしまったのですが、3ヶ月ずっと寝てたら(筋肉はいくらか落ちているはずなのに)2時間ぐらいずっと泳げるようになりました。体力は大事ですが、休息もとても大事です。

死にたさが少しは和らぐ

休学する前は毎日死について検討していたのですが、いまはそうでもありません。

いまでも人類は滅びるべきだと思うし今すぐにでも核爆弾で人間の住んでいるところが全部蒸発して欲しいのですが、”衝動的に”死について検討することは減りました。

好きな時に好きな所へ行ける(体力が許せば)

休学すると何も予定はありませんから、「あー明日から伊勢神宮とか行こうかな〜」とか思えば簡単に行けますし、気が変わって「よーしじゃこのまま紀伊半島一周するか~」と思ったら一周できちゃいます。気楽なもんです。

もちろん何もしなくてもいい

一日中寝ていてもいいし、一日中ぼんやりしていてもオッケーです。寝るのは楽しいことなんだって知りませんでした。

好きなことが増える

休学してから半年ぐらいたったころ、友達が「一緒に絵を描かない?」って誘ってくれたのをきっかけに、絵をはじめました。

学校教育で「美術」「芸術」があったころは、絵は大嫌いで、二度と描きたくないと思ってたのですが、実際描いてみるとたーのしー!

描きはじめの頃の記事はこちら:同じキャラクタを50回ぐらい描いてみよう

最近描いたのはこんな感じ:

 

 

写真も取るのが楽しくなってきました。こんな感じ:

 

 

 

絵や写真の他にも友達の書いた小説とかもあるので、もしよろしければ友達とやってるサイト「妖精⊸ロケット」のほうも見てみてください!

休学しててつらいこともあるぞ

概ね楽しかったんですが、つらいこともありました。

大学院の研究室がなくなった

東京大学大学院 情報理工学系研究科 コンピュータ科学専攻 蓮尾研究室という所に居たのですが、4月から東京大学から異動して他の大学院大学に移ることになってしまい、席が無くなってしまいました。

東京大学をやめて異動先の大学院をもう一度受験するか?東京大学大学院内の他の研究室に移るか?という選択肢が提示されたので他の研究室に移ることにしたのですが、教員にアポとってたくさん会ったりしないといけなくて正直結構疲れましたし、心の健康もすこし悪化しました。つらい。

学部の時も「理学部天文学科に内定していたが、履修をミスして内定が取り消しになった」という事があって、内定が決まっていたのに取り消しになってしまったイベントも二度目なので正直ちょっとうんざりしたのが正直な感想かな。

仕事は多少してました

完全にニートやってたわけじゃなくて、仕事も少ししてました。

データセンターの立ち上げをした

Link-Uっていう会社のサービスをホストするためのサーバ群を、それまでの他社VPSからNTTのデータセンターラックを間借りした自社データセンターに移すことになったので、その立ち上げに参加しました。管理もやってます2。「ラックってどっちが前なんだ!?」とかそういうレベルから始めたのですが、なんとかなりました。大変だったけど、楽しくもあったかな。Manga-ONEという漫画アプリの配信とかに使われてるらしい。

アプリもちょっと書いた

HTML5の漫画ビューワー 3とか書きました。どこかの漫画サイトで複数使われてるよ

今後の抱負

今後の抱負ですが、

夜と土日は必ず休む

っていうのを目指したいですね…(休息は本当に大事だ)

  1. 教員に嫌な顔されるとか、人と一緒に研究してるから休学できないとか、就職活動がどうのとか []
  2. さすがに一人ではなくて複数人でやってるよ []
  3. 対外向けにはGPLv3 []