SVX日記
2022-03-05(Sat) 人類としての責任
自分が見聞きしているニュースが、間違いなくNATO側に寄りまくっていることを勘案しても、これだけ大々的にドンパチしている原因がロシアのヒトラー二世にあることには違いない。ここに、全自分の代表としてロシアのウクライナ侵攻を非難したい。
しかし、今回の経緯を通じても、様々な学びがあったが、そのひとつに情報の扱いがある。もちろん、ウクライナのゼレンスキー大統領の情報による各種の戦い方は言うまでもないが、それ以前に、ウクライナの国境にロシア軍が集結していることを広く報じて「来るかも……来るかも……来たッ!」という流れに持っていったバイデン大統領の手腕(だよね?)がすごいと思える。
仮定の話ではあるが「××かも……××かも……××ッ!」というのは、人間の納得度を最大にする方法であると思う。自分は、主に技術サポートの問い合わせ業務を行っているが、この方法の威力をよく知っている。悪い状況を、早めに「××かも」と提示することで、相手の心をそこに釘付けにできる。しかも「かも」と言っている時点では反論できないうえに、覚悟だけが固まっていく。そのうえで、最後に「やっぱり××でした」と言えば、思考の向きが固定されている分、諦めもつきやすい。状況は違うが、これにより、強力に耳目を集めつつ、納得度を最大にできるのだ。
この逆のパターンが最悪で「××です」と理由なしにいきなり結論を出してしまう方法。内容によっては、強力に耳目を集めるが、理由がわからない分だけ、議論や想像が発散状態になり、理由が判明するに従って怒りの方向も発散する。アンジャッシュというお笑いコンビは、認識のズレをネタにしたコントでズバ抜けたセンスを発揮していたが、何でこれを自分のスキャンダルにまで適用してしまったのだろう。
話がソレたが、単に「非難する」だけではアレなので、わずかながらでも募金に応じようと思う。ちなみに「ウクライナ 募金」で検索すると「武器の購入などには使われないように寄付するには」などというサイトが引っかかるが、自分的にはウクライナ勢力に使ってもらえるならば、武器の購入に当ててもらってもぜんぜん構わないがな。むしろ、この金で買ったジャベリンでT-80を鉄クズにしてもらえたり、スティンガーでハインドを撃墜してもらえたり、暗殺スナイパーの成功報酬にしてもらえたら本望なくらいである。だって、ナチズムの破壊は、民主主義者の義務でしょ。戦いは経済で。手を出すのは反則。
とはいえ、逆に「武器の購入に当てます」という募金サイトも見当たらないので、代表的な募金サイトで寄付したみた。せっかくなので大台に上げるタイミングを待ってドカンと。スマホ持たない自分なのに、重課金したもんだ。
2022-03-19(Sat) テトランを建造する
なんだか「思考力が余っているような感じがある」こともあるので、プログラミングでもしようかと思い立った。で、なんとなく「テトラン」でも作ってみようかと。ディアゴスティーニみたいに「週刊テトランをつくる」なんて連載記事もいいかな。
さて、どう作ろうか。三角関数をゴリゴリに使う必要があるだろうな……と、考え始めたのだが、エラいことを思いついてしまった。タートルグラフィックスだ。自製のタートルグラフィックスライブラリがあるのだ。それを使う。
require './TrueLegacyGraphicsCairo'
win = LegacyGraphics.new(nil, nil, nil, nil, 720, 960, 16, 8, 0, { :file => 'tetran', :type => 'png' }) # png/pdf/svg/ps
win.tPenUp
win.tSetPenColor([0.6, 0.6, 0.6])
win.tSetPenWidth(16)
4.times {|n|
win.tHome
win.tRight(n * 90)
9.times {|n|
win.tPenDown unless(n < 2)
win.tForward(32)
win.tPenUp
win.tForward(6)
win.tRight(4)
}
}
ox = win.gx / 2; oy = win.gy / 2
win.fill(ox - 96, oy - 96, ox + 95, oy + 95, [0.6, 0.6, 0.6])
win.refresh
win.close
$ diff turtleTetran0.rb turtleTetran1.rb
25c25
< win.fill(ox - 96, oy - 96, ox + 95, oy + 95, [0.6, 0.6, 0.6])
---
> win.put_image_png(ox - 96, oy - 96, 'tetran0.png')
$ diff turtleTetran1.rb turtleTetran2.rb
7c7,10
< win = LegacyGraphics.new(nil, nil, nil, nil, 720, 960, 16, 8, 0, { :file => 'tetran', :type => 'png' }) # png/pdf/svg/ps
---
> # convert -delay 3 -loop 0 tetran.d/tetran*.png tetran.gif
> Dir.mkdir(@path = 'tetran.d') rescue true
> 30.times {|f|
> win = LegacyGraphics.new(nil, nil, nil, nil, 720, 960, 16, 8, 0, { :file => @path + '/tetran%03d' % f, :type => 'png' }) # png/pdf/svg/ps
13a17
> win.tRight(f * 3)
28a33
> }
$ diff turtleTetran0.rb turtleTetran3.rb
5c5
< require './TrueLegacyGraphicsCairo'
---
> require './TrueLegacyGraphicsOpenGL'
8a9
> win.depth3d(0, 16)
23a25
> win.depth3d(-8, 32)
立体環境において「画像を描画する」ということは、つまりテクスチャマッピングを行う、ということだ。以前、やりかけたが勝手がわからず断念したコードが残っていた。で、がんばって試行錯誤しつつ、どうにか実装できた。それなりのコード追加が必要であった。
$ diff turtleTetran3.rb turtleTetran4.rb
25c25
< win.depth3d(-8, 32)
---
> win.depth3d(32)
27c27
< win.fill(ox - 96, oy - 96, ox + 95, oy + 95, [0.6, 0.6, 0.6])
---
> win.put_image_png(ox - 96, oy - 96, 'tetran0.png')
再び、それっぽくなったところで、回してみたいところだが、自製のOpenGLライブラリでアニメーションさせるためには、足をスプライトの扱いにする必要がある。先のタートルグラフィックスのコードは、スプライト機能を実装する前に実装した機能なので、スプライトとして扱えない。そこで、改めてスプライトとして扱えるよう、タートルグラフィックスの処理をModule化して、スプライトクラスからもincludeするように変更した。いや、Rubyってスゴいな。で、本体コードにもちょっとコードを足す。
$ diff turtleTetran4.rb turtleTetran5.rb
6a7,8
> # ffmpeg -y -i tetran.d/3dtetran%06d.png -vcodec libx264 -r 30 -s 480x360 tetran.mp4
> Dir.mkdir(@path = 'tetran.d') rescue true
8a11
> def draw_sprites(win, f)
9a13
> win = win.init_sprites
14a19
> win.tRight(f * 3)
23a29,44
> end
> draw_sprites(win, 0)
>
> def callback(win, info, params)
> case(info[0])
> when(:VSYNC)
> while(it = win.inputs[:EDGE].shift)
> it == 'r' and @ar = win.arotate3d(@ar ? 0 : 1)
> it == 'q' and exit
> end
> win.write_to_file(@path + '/3dtetran%06d.png' % ($jiffies - 1))
> $jiffies > 359 and exit
> end
> draw_sprites(win, $jiffies)
> end
> win.setcallback3d(method(:callback).to_proc, {})
29c50,51
< win.refresh
---
> win.arotate3d(@ar = 1)
> win.refresh(30)
そして、テトランといえば外せないのが、グラディウスIIで見せた「ひっぱたき」である。たぶんそうだろうなぁ、と思いつつ実装してみたら、やっぱりそうだった。長らく「もぞもぞ」しているのも勝手に再現された。実は、実装はものすごく簡単なのだ。たった1行である。
$ diff turtleTetran5.rb turtleTetran6.rb
26c26
< win.tRight(4)
---
> win.tRight($jiffies * 2)
$ diff turtleTetran6.rb turtleTetran7.rb
10a11
> @hands = 4; @swing = 1440
17c18
< 4.times {|n|
---
> @hands.times {|n|
20c21
< win.tRight(n * 90)
---
> win.tRight(n * 360 / @hands)
26c27
< win.tRight($jiffies * 2)
---
> win.tRight(4 + @swing)
35a37,38
> it == 'h' and @hands += 1
> it == 's' and @swing = 0
40c43
< $jiffies > 359 and exit
---
> @swing < 1440 and @swing += 2
当初は「週刊テトランをつくる」なんて連載記事もいいかな、などと思っていたが、意外と時間がかかってしまった。しかし、最小限のコードで、複雑な動作を再現するのは楽しい。動けばいい、というコードを書く人もいるが、自分はコードを煮詰めていくこと自体が楽しいんだよなぁ。コード一式を置いておく。