忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


Silverlightで生き物の模様をシミュレート(チューリングパターン)

このサイトを参考に、生き物の模様を描き出すSilverlightを作ってみました。
ちょっと前NHKのサイエンスZero「シリーズ・細胞の世界(1)体をつくる不思議な“波”」でやっていたものです。

チューリングパターンと言って、2種類の化学物質の反応と拡散をシミュレートすると、生き物の模様が再現できるそうです。
(正確には、これはGray-Scottモデルといいます。)
何を言っているのかちょっとよくわかりませんが、百聞は一見にしかずです。



初めは血のりが飛んでるような絵ですが、
Resumeボタンを押すと、このようにゼブラフィッシュのような模様が出来ます。
zebrafish.JPG
模様ができたら、マウスでドラッグしてみてください。
模様が撹乱されますが、すぐに再生しておもしろいです。

「スパイラルウェーブ」を選択すると青い領域が全滅することがあります。
(スパイラルウェーブはチューリング・パターンではありません)
そういう時はコンボボックスで「青塗り」を選択。
適当に塗りたくっていると復活します。


元ネタのサイトのシミュレータにはない機能も付けてみました。
コンボボックスで「壁作り」を選択するとマウスでピンクの壁を作れます。

GrayScottWithWall.JPG

壁は化学物質を通しません。
波が壁を回りこむようになります。


もともとこれはコンピュータサイエンス界では有名なアラン・チューリングが考えだした理論です(だからチューリング・パターンというのですね)。
長らくホコリをかぶっていたようですが、日本の研究者が実証したとかで再び注目されたようです。

おまけ

プロジェクトファイルです。

拍手[3回]

PR

[ユーザーインターフェース] 12時撲滅作戦

突然ですがSilverlightでアナログ時計を作ってみました。





はい、そうですね。
おかしいです。
本来12時のところが0になっています。
でもこれはつまらないバグでこうなったのではありません。
わざとです。
この背景には緻密(?)なロジックがあります。
実は、時計の文字盤はこうであるべきなのです。

 今回はユーザーインターフェースの話です。
なんだか冗談のような話ですが、論理は完璧に通っています。
私が考えたのではなく、某所で聞いてなるほどなと思った話ですが・・・。

どういう事かというと、
時計の文字盤から12時を抹殺せよ!!
12時はユーザーインターフェースとして不条理だ!

という話です。

12時→0時

ということですね。


こういう話ではない

ここまでの話を聞いてこう思われる方もいらっしゃるでしょう。
「なるほど。
これはインデクスを0から始めるか1から始めるかという話だな。
現在主流のプログラミング言語では配列の添字を0からスタートさせる。
物を数えるときは0番目から始めるんだ。
だからそれを時計の文字盤にも当てはめようということか。」

いいえ違います
全然違います。
ものの数え方を0から始めるか1から始めるかなどは慣習で、どうでもいいことなのです。
(さすがにいきなり12番目から数え始めるというのは問題ですが)
その程度の話なら誰も12時を抹殺しようとは言わないでしょう。

ここで大切なのは「1からスタートしない」ということではなく、「スタートは0から」ということなのです。
ここには根本的な誤解があります。
実は、12時を持つ普通の文字盤も、「1からスタートしない」のです。
もちろん「スタートは0から」というわけでもありません。
普通の文字盤は、12からスタートしているのです。


大きな数からスタートする

ややこしいので図にしてみましょう。
普通の文字盤は、次のように時間が進行していきます。

normalClock.jpg


午後や午前は、まず12時からスタートします。
大きな数からスタートするのです。
そこから何故か数が減って、1時となります。
そしてその後は普通に数が増えて2時、3時…となります。

これが12が存在することの理不尽な点です。
普通、物を数えるときには小さな数から大きな数へと推移していきます。
しかし普通の文字盤は違うのです。
はじめに何故か大きな数がやってきて、その後いきなり小さくなり、後はすこしずつ大きくなる。
これを不条理と言わずして何を不条理といえばいいのでしょう!!!?

一方、理想的な文字盤はこうなります。

idealClock.jpg
どうでしょうか。
0から始まりすこしずつ大きくなり11にたどり着く。
これが直感的なものの数え方というものです。


12時があるとプログラムが書きにくい

12時には直感的でないという以上の問題もあります。
時間に関係したプログラムが書きにくいのです。
たとえばある時間と別の時間の時間差を計算するプログラムを書きたいとします。
そのために時間を全て秒に直すとしましょう。

すると直感的にはこのようなプログラムを書きたくなるのではないでしょうか。
(単純化していますが)
        enum DayTimePeriod
        {
            AnteMeridiem = 0,
            PostMeridiem = 1
        }

        int ToSeconds(int day, DayTimePeriod period, int hour, int minute, int second)
        {
            return day * 24 * 60 * 60 
                +(int)period * 12 * 60 * 60
                + hour * 60 * 60 
                + minute * 60 
                + second;
        }


DayTimePeriodは午前か午後かを表します。
AnteMeridiemはAM、PostMeridiemはPMです。
このプログラムは一見正しいように見えるかもしれませんが、hourが12の時正確に動作しません。
12の時は特別扱いをして、0として扱ってやらねばならないのです。

このことは、本質的に12時の存在は間違っていて、0時こそが正しいということを暗示しています!!

…もっとも.netならSystem.TimeSpan構造体を使えという話ではありますが。


でも本当に12時を消さなくちゃいけないのか?

「なるほど現行の文字盤に問題はあるようだ。
しかし今まで長年人々が慣れ親しんできた文字盤から12時を消すことなんて今更出来るだろうか?
それよりは午前午後の境界を一時間ずらして「一時~12時」にした方がいいんじゃないかな?」
と考える方もいらっしゃるでしょう。

しかし午前午後の境界をずらすというのはあまり美しい方法ではありません。
0時(旧12時)はその定義が南中時刻に結び付けられています。
地球の自転と太陽の位置とに密接に結びついているのです。
一時間ずらすのはあまりきれいではないのです。
もっともサマータイムはそのずらしを期間限定で行っていますが。

「今更12時を消せない」という点についてはどうでしょうか。
これも疑問が残ります。

過去にこんな例がありました。
摂氏という単位はみなさんご存知ですね。
温度の単位です。
実はこれは昔、逆だったのです。
水が凍っている時が100℃で沸騰している時が0℃でした。
さすがにそれは分かりにくいということで逆転されたのです。
何を言いたいのかというと、逆転ができたのなら一部変更くらいできてもおかしく有りません!!!!

まあそれはともかく最近は0時と言う人も珍しくありませんので文字盤から12時を消すのも心理的抵抗は以前より少なくなっているのではないかと思います。
大切なのは心理的抵抗をどんどん薄めていくことです。
たとえば同僚の前で「12時」と言う機会があったら代わりに0時というのです。
家の中のアナログ時計にシールで0を貼ります(うーん想像してみたら異様な光景です)。
子供たちにシンデレラを読み聞かせることがあったら、魔法が解けるのは0時です。

こうして人々の心理的抵抗が少なくなっていってそれがある閾値に到達したとき、ばっと情勢がひっくり返ると思うのです。
世の中からは12時文字盤が消え、0時型文字盤が普及するでしょう!
・・・・・・どうでしょうか。
0時型文字盤を普及させる気になってきませんか!?


おまけ

Silverlightアナログ時計のプロジェクトファイルです。
MVVMを使うとデザイン画面で針が動くとは思いませんでした。
SilverlightClock.zip
















拍手[0回]


リッチテキストなソースコードをHTMLに変換

 ツールを作ってみました。
ブログにソースコードを貼るためのツールです。
Visual Studioからコピー貼付けするとそれがpreで囲まれたhtmlになって出てきます。
つまりリッチテキストからHTMLへの簡単な変換プログラムですね。
クラスやキーワードに色がついて見やすくなるというあれです。


RitchTextToHtmlConverter.jpg

といっても既に似たようなプログラムはたくさん作られています。
まあツール世界の多様性に貢献するという意味で(????)アップしておきます。



ダウンロード


拍手[2回]


XNAで音を合成 DynamicSoundEffectInstanceクラス

突然ですが、 XNA4.0では自在に音を合成できるクラスが用意されているようです。
自在に合成とは一体何を言っているのかというと、こういうことです。

これまでXNAではたしか予め録音された音しか再生できなかったと思います。
ものが爆発した音なら爆発音を最初からファイルに保存しておいてそれを必要なときに再生するという形でした。
しかし新しいMicrosoft.Xna.Framework.Audio.DynamicSoundEffectInstanceクラスはちがいます。
波形データをリアルタイムで作って、それを再生できるのです。

もしかすると物理世界をシミュレートして、その結果として音を鳴らすというようなことが出来るかもしれませんね。
先程の例で言うと爆発時の空気の振動を計算してそれを使えるかもしれませんん。
あるいは音声の合成とかゲームとは別のベクトルで面白そうです。

ではやってみましょう。

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;

namespace XnaDynamicAudio
{
    static class Program
    {
        static void Main(string[] args)
        {
            const int samplePerSecond = 8000;
            const int secondsToPlay = 3;

            using (DynamicSoundEffectInstance dynamicSound = new DynamicSoundEffectInstance(samplePerSecond, AudioChannels.Mono))
            {
                byte[] buffer = createAWave(samplePerSecond, secondsToPlay, 440);
                dynamicSound.SubmitBuffer(buffer);
                FrameworkDispatcher.Update();
                dynamicSound.Play();
                System.Threading.Thread.Sleep(secondsToPlay * 1000);
            }
        }

        private static byte[] createAWave(int samplePerSecond, int secondsToPlay, int heltz)
        {
            byte[] buffer = new byte[samplePerSecond * secondsToPlay];

            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = (byte)(
                    byte.MaxValue / 4 * (1 + Math.Sin((Math.PI * heltz) * i / samplePerSecond))
                    );
            }

            return buffer;
        }
    }
}



このサンプルプログラムを実行すると、ピーという音が鳴ります。
440Hzのサイン波。
つまり、ラの音です。


クラス

このサンプルプログラムに登場した重要なクラスは2つ有ります。
DynamicSoundEffectInstanceクラスとFrameworkDispatcherクラスです。

DynamicSoundEffectInstanceはダイナミックな再生を司るクラスだからいいとして、FrameworkDispatcherとはなんでしょう?
これはXNAで使うコンポーネントを管理するらしく、普段は内部で呼ばれているようです。

が、今回のプログラムのように、「XNAは使うけれどGameは使わないよ」というような場合にはFrameworkDispatcher.Updateメソッドを自分で呼ばなければならないのです。
これは1フレームに一回の呼び出しが推奨されています

拍手[2回]


ブログにSilverlight埋め込みテスト

クリックでSilverlightデモ起動

クリックするとボタンが出ます。
ボタンをクリックするとダイヤログボックスが出ます。

さてSilverlightをブログに埋め込むにはどうすればいいんでしょうね?


どうやらこんなふうにタグを使えばいいようです。

<iframe src="https://blog.cnobi.jp/v1/blog/user/118c300f2ee0ad311e5962b0167205f5/1309324795" frameborder="0" width="400" height="400" scrolling="no"></iframe>

まあ当たり前な気もします。

SilverlightApplicationDemoTestPage.htmlというのは、VisualStudioがbin\DebugやReleaseフォルダ内に作り出すhtmlファイルです。

拍手[0回]