忍者ブログ

Memeplexes

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

[PR]

×

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


かんがんL-system その2 描画

前回かんたんなL-systemのプログラムを書きました。
しかしその実行結果はわけがわからないものでした。

ABAABABAABAABABAABABA
というふうに、文字だけで、おもしろくありません。
L-systemはやはり描画してこそでしょう。

ソースコード

Algae.cs

using System;
using System.Collections.Generic;

namespace LSystem.Algae
{
    public class Algae
    {
        public AlgaeCell Root = new AlgaeCell { IsBig = false };
        public List<AlgaeCell> Cells = new List<AlgaeCell>();

        public Algae()
        {
            Cells.Add(Root);
        }

        public void Develop()
        {
            foreach (var cell in Cells)
            {
                cell.Update();
            }

            var newCells = new List<AlgaeCell>();

            foreach (var cell in Cells)
            {
                newCells.Add(cell);

                if (cell.CreatedChildren)
                {
                    newCells.Add(cell.Child1);
                    newCells.Add(cell.Child2);
                }
            }

            this.Cells = newCells;
        }

        public void ForEachTerminal(Action<AlgaeCell> executedInTerminal)
        {
            ForEachTerminal(executedInTerminal, Root);
        }

        public void ForEachTerminal(Action<AlgaeCell> executedInTerminal, AlgaeCell cell)
        {
            if (cell.HasChildren)
            {
                ForEachTerminal(executedInTerminal, cell.Child1);
                ForEachTerminal(executedInTerminal, cell.Child2);
            }
            else
            {
                executedInTerminal(cell);
            }
        }
    }

    public class AlgaeCell
    {
        public bool IsBig;
        public AlgaeCell Child1;
        public AlgaeCell Child2;

        public bool HasChildren
        {
            get { return Child1 != null; }
        }

        public bool CreatedChildren { get; private set; }

        public void Update()
        {
            CreatedChildren = false;

            if (HasChildren)
            {
                return;
            }

            if (IsBig)
            {
                this.Child1 = new AlgaeCell
                {
                    IsBig = true
                };
                this.Child2 = new AlgaeCell
                {
                    IsBig = false
                };
                CreatedChildren = true;
            }
            else
            {
                IsBig = true;
            }
        }
    }
}


MainWindow.xaml.cs

using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace LSystem.Algae
{
    public partial class MainWindow : Window
    {
        Algae algae = new Algae();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            algae.Develop();

            Title = getText(algae.Root);
            canvas.Children.Clear();
            draw(algae.Root, new Vector(300, 100), 0);
        }

        private string getText(AlgaeCell cell)
        {
            var text = "";
            algae.ForEachTerminal((c) => text += c.IsBig ? "A" : "B");
            return text;
        }

        private void draw(AlgaeCell cell, Vector position, double angle)
        {
            var transform = new TransformGroup();
            transform.Children.Add(
                new ScaleTransform(cell.IsBig ? 1 : 0.5, cell.IsBig ? 1 : 0.5)
                );
            transform.Children.Add(new RotateTransform(angle));
            var endPosition = position 
                + transform.Value.Transform(new Vector(0, 100));

            var line = new Line
            {
                X1 = position.X,
                Y1 = position.Y,
                X2 = endPosition.X,
                Y2 = endPosition.Y,
                Stroke = cell.IsBig ? Brushes.Green : Brushes.LightGreen,
                StrokeThickness = 5
            };
            canvas.Children.Add(line);

            if (cell.HasChildren)
            {
                draw(
                    cell.Child1,
                    endPosition,
                    angle + 8
                    );
                draw(
                    cell.Child2,
                    endPosition,
                    angle - 8
                    );
            }
        }
    }
}

MainWindow.xaml

<Window x:Class="LSystem.Algae.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

        <Canvas x:Name="canvas">

        </Canvas>
        <Button Height="24" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="58" Margin="0,0,10,10" Click="Button_Click">Next</Button>
    </Grid>
</Window>

実行結果

このプログラムを実行するとこうなります:

おお!!

なんとなく、藻類のように見えなくもないような気がしますね。
ただ、再帰で適当に描いたのとたいして変わりないじゃないかと言われると困りますが。

本来L-systemは文字とその変換だけでプログラムはすむはずなのですが、
ここではイメージというかフレイバーというかそういったものにこだわったソースコードにしてみました。
それにしては成長しきった細胞がいきなり現れたりという変な感じはしますが……

拍手[1回]

PR

かんたんL-system その1 文字だけ

L-systemというアルゴリズムがあります。
これを使うと植物の形が描けます。
やってみましょう。

Program.cs

class Program
{
    static void Main()
    {
        var text = "A";
        System.Console.WriteLine(text);

        for (int i = 0; i < 10; i++)
        {
            var newText = "";

            for (int textIndex = 0; textIndex < text.Length; textIndex++)
            {
                switch(text[textIndex])
                {
                    case 'A':
                        newText += "AB";
                        break;
                    case 'B':
                        newText += "A";
                        break;
                }

            }

            text = newText;
            System.Console.WriteLine(text);
        }
    }
}
結構簡単なプログラムですね。
ディスプレイが小さくても一画面に収まりそうです。

結果

A
AB
ABA
ABAAB
ABAABABA
ABAABABAABAAB
ABAABABAABAABABAABABA
ABAABABAABAABABAABABAABAABABAABAAB
ABAABABAABAABABAABABAABAABABAABAABABAABABAABAABABAABABA
ABAABABAABAABABAABABAABAABABAABAABABAABABAABAABABAABABAABAABABAABAABABAABABAABAABABAABAAB
ABAABABAABAABABAABABAABAABABAABAABABAABABAABAABABAABABAABAABABAABAABABAABABAABAABABAABAABABAABABAABAABABAABABAABAABABAABAABABAABABAABAABABAABABA

さて……文字列が表示されました。
何でしょう?この結果は。
私たちは植物を描こうとしていたはずでしたが…?

実はこのプログラムはL-systemのエッセンスを実装しただけであって、見た目はダメです。
植物の形にするにはきちんと体裁を整えなければなりません。
では続きは次回。

拍手[0回]


人間は宇宙の本当の物理法則に辿り着けるのか

物理学の進歩

これまで物理学は何回か革命を起こしてきました。
人間の宇宙観はそのたびに変わってきたのです。
あるときはニュートン力学が相対論や量子論によって覆されました。
「物理学はもうこれで完璧だろう」というようなことを物理学者が言ったすぐ後に、物理学上の革命が起こったりです。

進歩は好ましいことですが、逆にこう考える人もいるかも知れません。
「このまま本当に正解にたどり着けるのだろうか?
いつまでたっても不完全な理論しかわからず、単に精度の良い理論が導き出されるだけにすぎないのではないだろうか?
人間は永遠に本当の物理法則にはたどり着けないのではないだろうか?」

この宇宙がコンピュータ中のシミュレーションだった場合

この不安はある程度までは正しいです。
もし私たちの宇宙が別の上位宇宙のコンピュータだったと考えてみて下さい。
(その可能性は完全には否定できません。
そうだと考えなければならない理由もありませんが)

もし宇宙がプログラムなら、ハードウェアは一体どうなっているのでしょう?
メーカーによってコンピュータのアーキテクチャは違うでしょう。
にも関わらず本質的には同じなので、内部(私たちの宇宙)からは、プロセッサのアーキテクチャは全くわからないのです。

私達がコンピュータでシミュレートした生命体に知性が芽生えたとしても、彼らは自分たちの宇宙がどのCPUメーカーによってシミュレートしているかなんてわかりません。
もちろん、私たちの宇宙の物理法則なんてさっぱりわからないでしょう。
そういう意味で、私達の宇宙がシミュレーションなら、「本当の物理法則」にはたどり着きようが無いように思えるかもしれません。

「本当の物理法則」とは何か

しかしそれは杞憂です。
実は、私達の宇宙のプログラムを当てることができたら(さらに言えば、そこまで正確でなくても同等のプログラムを言い当てることが出来れば)、それを実行しているCPUのアーキテクチャがわからなくても「本当の物理法則」を見つけられたことになるのです。
どういうことか詳しく見て行きましょう。

※ここから先は議論を簡単にするために宇宙が決定論であると仮定して話します。
これは量子論でのベルの不等式の破れと矛盾するように思えるかもしれません。
しかし1999ノーベル物理学賞受賞のヘラールト・トホーフトらも決定論的な量子力学を諦めていないので早まってはいけません!
それに実のところ、決定論だろうとそうでなかろうと、この議論の真偽にはあまり関係ありません。

私達の宇宙が決定論的プログラムで動いているとします。
するとアーキテクチャが違う複数のコンピュータで走らせた場合、それでもそれらの宇宙は全く同じ様子になります。
さて、あるコンピュータの中で誰かが「この宇宙を走らせているハードウェアはこんな構造に違いない!」と言ったとしましょう。
どうなるでしょうか?

もしその科学者の言っていることが正解だったとしましょう。
だからなんだというのでしょうか?
全然偉くありません。
どうせ他のコンピュータでもその科学者は全く同じ事を言っているのです。
そしてほかのコンピュータのアーキテクチャは違っているので、その科学者は不正解となります。

お分かりいただけたでしょうか。
宇宙がプログラムだった場合、ハードウェアのアーキテクチャにまで言及することは意味がありません。
コンピュータのアーキテクチャの種類が多ければ、どうせ「真の物理法則の予想」は正しく、かつ間違っているのです。
宇宙の内部から真実を知ることが出来ないのではなく、一つの確実な真実というものが存在しないのです。

本当にハードウェアの予測に意味が無いのか

本当に予測に意味が無いのかと考える人もいるでしょう。
もしこの宇宙のプログラマが私達を外の世界に出して働かせようとしたら?
それなら私達を実行しているプロセッサのアーキテクチャについて知ることは有意義だと考えることも出来ると思われるかもしれません。

しかしそれはやはり違います。
そのケースでは外の世界の情報を入れているからです。
外の世界の情報を入れた場合、その宇宙の物理法則は壊れてしまいます。
きっと月かどこかにモノリスをいきなり具現化して、そこに「君たちはシミュレーションだ」と表面に刻むのです。
そんなことは本来の物理法則では起こるはずがありません。
物理法則が壊れるという言い方がまずいなら、より大きな物理法則に取り込まれてしまうといってもいいでしょう。
(宇宙を実行しているコンピュータのプログラマの世界からすれば物理法則は壊れていないのですから)

物理法則が壊れてしまう前と後では話が全く違います。
壊れていない宇宙が本物であり、上位宇宙のプログラマから干渉されて法則を破壊された宇宙は別物なのです。
物理法則が壊れてしまったのに、本物の物理法則がどうこう言っても仕方ありません。
だいたい、干渉されていない、別のコンピュータ中で実行されている、宇宙のインスタンスだってあるはずです。
そのまま全く干渉されずに永遠に実行される宇宙だってあるでしょう。
その場合は、彼らは上位宇宙の存在など知ることはないでしょう。

つまりどういうことか

結局、もし観測結果と矛盾せず、一つの万物の理論を作ることに成功した場合、それが真実なのです。
それが本当の物理法則であり、「その下に更になにかメカニズムがあるかも」と考えるのは意味がありません。
私達の宇宙は別の宇宙Aで実行されているプログラムかもしれませんし、また別の宇宙Bで実行されているプログラムかもしれませんし、その両方かもしれません。
どれか1つ答えを出したとしても、決して正解することはないのです。
正確に言えば、正解したとしても同時に不正解でもある、ですが。
ならばもう上位宇宙の物理法則などというものを考えること自体が無意味だといえるでしょう。

もっと言うと、上位宇宙などがなくても、たとえば私達の宇宙の内部から「本当の」物理法則が見つからない仕掛けになっていた場合も、それ以上考える必要はありません。
(内部にいる人間レベルのAIからその世界の仕組みがわからないようにするプログラムを書くことは可能でしょう)

最後に教訓めいたことを言いますが、つまり人間は、真実に辿り着けるのです!!!!!!

拍手[0回]


デイヴィッド・ドイッチュ『無限の始まり』名言集

※この記事は書きかけです

『無限の始まり』

デイヴィッド・ドイッチュさんの『無限の始まり』を(だいたい)読みました。
ドイッチュさんは量子コンピュータで有名な物理学者です。
しかしこの本は量子コンピュータに限った話ではありません。
科学哲学っぽいことや生物の進化やらコンピュータやら宇宙やらなにやらいろんなことについて書いてあります。
そしてそれぞれが非常に刺激的で面白いのです。

刺激的というのは、私たちの多くが考えているであろうことが、批判されるからです。
それでいて(少なくとも私はそうだったのですが)、その批判が心地良いのです。
自分の信じていることが批判されているのに嫌な気分にならない、というのは、私自身がドイチュさんと基本的なことでは同じ考えだからだというだけかもしれませんが、この上手な批判っぷりは見習いたいです。
建設的な批判というのでしょうか。

もっとも、時々批判ではないけれども面白いというような文章もあります。
ドイッチュさんの言うこと自体が面白いのかもしれません。
ともかくこの本は面白いのです。

この記事では、その刺激的な文章を並べ、それについて私の考えを述べたいと思います。
面白そうだと思ったらぜひドイッチュさんの本を読んでくださいね。

※ちなみにこの『無限の始まり』、一言で言うなら「無限の進歩」についての本です。
人類は無限に科学を発展させ続け、無限に問題を解決し続ける能力があるのです。
まあそのうち自分たちを改造して寿命という問題を解決することがあるかもしれませんが、それも人類の範疇です。
ノリが理解していただけたでしょうか?


拍手[0回]