English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
[概要]
最近、『深奥の简洁』を読んでいて、いくつかのノイズを生成するための分形図の作成方法が紹介されており、とても面白かったので、コンピュータでシミュレーションを試みました。効果はとても良いです(ノイズ法は伝統的な反復法よりもプログラミングが簡単で、後にこの種のアルゴリズムがたくさんあることを発見しました。chaosgameを検索するとさらに多くの情報が見つかります)。
[Sierpinski三角形のノイズ生成法]
これらのノイズゲームで、Sierpinski(シェルビンスキー)三角形の生成ルールは最もシンプルです:
1.平面上で三つの点を選び、1、2、3、を大三角形的頂点として選択します。
2.その中の一点を選択し、「現在の点」として使用します(例えば、1番)。
3.生成します。1~3のランダム数が表す頂点と「現在の点」の中点に新しい点を描画し、新しい点を「現在の点」として設定します。
4.手順を繰り返します。3、すればパターンに近づきます。
*.注意、ランダム数は時間を種子に使用しない方が良いです。
[シミュレーションプログラム]
package com.geiv.chaos; import java.awt.event.KeyEvent; import com.thrblock.util.RandomSet; import geivcore.DefaultFactor; import geivcore.KeyFactor; import geivcore.KeyListener; import geivcore.R; import geivcore.UESI; import geivcore.enginedata.obj.Obj; public class Sierpinski extends DefaultFactor implements KeyListener{ UESI UES; Obj[] basePoint; Obj crtPoint; public Sierpinski(UESI UES,int times){ this.UES = UES; basePoint = new Obj[3]; //三つの基準点を作成 for (int i = 0;i < 3;i++){ basePoint[i] = UES.creatObj(UESI.BGIndex); basePoint[i].addGLPoint("70DBDB",0,0); basePoint[i].show(); } basePoint[0].setCentralX(400); //三点の位置を設定 basePoint[0].setCentralY(60); basePoint[1].setCentralX(60); basePoint[1].setCentralY(550); basePoint[2].setCentralX(740); basePoint[2].setCentralY(550); crtPoint = basePoint[0]; //0番の点を現在の点として設定 this.setKeyListener(this); UES.pushKeyBoardIO(this); for (int i = 0;i < times;i++){ generateNew(); } } @Override public void doKeyBord(KeyFactor whom, int keyCode, Boolean ispressed) { //コールバックをマウント if(ispressed){ if(keyCode == KeyEvent.VK_SPACE){ //スペースに対応して新しい点を作成 generateNew(); } else if(keyCode == KeyEvent.VK_A){ //Aに対応して作成100個の新しい点 for (int i = 0;i < 100;i++){ generateNew(); } } else if(keyCode == KeyEvent.VK_B){ //Bに対応して作成1000個の新しい点 for (int i = 0;i < 1000;i++){ generateNew(); } } } } public void generateNew(){ Obj flagPoint = basePoint[RandomSet.getRandomNum(0, 2); //ランダムに基準点のうちの一つを選択 float nx = (flagPoint.getCentralX() + crtPoint.getCentralX())/2f; //中点を計算します float ny = (flagPoint.getCentralY() + crtPoint.getCentralY())/2f; Obj newPoint = UES.creatObj(UESI.BGIndex); //新しい点を作成します newPoint.addGLPoint("70DBDB",0,0); 色を設定します newPoint.setCentralX(nx); //座標を設定します newPoint.setCentralY(ny); newPoint.show(); crtPoint = newPoint; //現在の点に設定します } public static void main(String[] args) { UESI ues = new R(); new Sierpinski(ues,0); //後続の構造パラメータは初期点数を設定できます。 } }
[シミュレーション結果]
Bボタンが押されたとき
[Barnsley fernのノイズ生成法]
Sierpinski三角の単純なルール性よりも、Barnsley fern(分形羊の草)はより複雑な印象を与えます。その複雑さゆえに、混沌学は「単純なルールでも複雑な物体を生成できる」という結論を証明するためにしばしばそれを使います。
その生成ルールも特に複雑ではありません:
1.まず、"現在の点"(0,0)を指定し、ox、oyを使用して横・縦座標を表します。
2.次の点(nx,ny)を計算するには、以下の4つの迭代公式のうち一つを選択する必要があります:
1)を%で指定します。1の確率で次の迭代公式を選択します:
nx=0;
ny=0.16f*oy;
2)を%で指定します。85の確率で次の迭代公式を選択します:
nx=0.85*ox+0.04*oy;
ny=-0.04*ox+0.85*oy+1.6;
3)を%で指定します。7の確率で次の迭代公式を選択します:
nx=0.2*ox-0.26*oy;
ny=0.23*ox+0.22*oy+1.6;
4)を%で指定します。7の確率で次の迭代公式を選択します:
nx=-0.15*ox+0.28*oy;
ny=0.26*ox+0.24*oy+0.44;
3.(nx,ny)を描画し、それを現在の点として設定し、繰り返します。2、結果に無限に近づくことができます。
↑上記の公式はWikiから引用:http://en.wikipedia.org/wiki/Barnsley_fernプログラミング中に、Wikiがこの座標の絶対値とスクリーンサイズの関係を示していないことに気づき、x、y軸の方向も説明していませんでした。自分で定義した座標系で描画すると常に失敗し、最終的に公式を検索してこの面を見つけました:http://people.sc.fsu.edu/~jburkardt/cpp_src/fern_opengl/fern.cppこれはC++のOPENGLプログラムでは、Wikiと同じ公式を使用しており、つまり、このセットの公式はOpenglの座標系を基準としており、対応する変換を行った後、最終的に成功して描画しました。
[シミュレーションプログラム]
package com.geiv.chaos; import geivcore.DefaultFactor; import geivcore.KeyFactor; import geivcore.KeyListener; import geivcore.R; import geivcore.UESI; import geivcore.enginedata.obj.Obj; import java.awt.Color; import java.awt.event.KeyEvent; import com.thrblock.util.RandomSet; public class Barnsleyfern extends DefaultFactor implements KeyListener{ UESI UES; Obj crtPoint; public Barnsleyfern(UESI UES,int times){ this.UES = UES; crtPoint = UES.creatObj(UESI.BGIndex); crtPoint.addGLPoint("70DBDB",0,0); crtPoint.show(); crtPoint.setCentralX(0); crtPoint.setCentralY(0); UES.setViewOffsetX(90); this.setKeyListener(this); UES.pushKeyBoardIO(this); for (int i = 0;i < times;i++){ generateNew(); } } @Override public void doKeyBord(KeyFactor whom, int keyCode, Boolean ispressed) { //キーボードIOの方法は前例と同じです if(ispressed){ if(keyCode == KeyEvent.VK_SPACE){ generateNew(); } else if(keyCode == KeyEvent.VK_A){ for (int i = 0;i < 100;i++){ generateNew(); } } else if(keyCode == KeyEvent.VK_B){ for (int i = 0;i < 1000;i++){ generateNew(); } } } } public void generateNew(){ float nx,ny; float ox = crtPoint.getCentralX()/150f,oy = (600 - crtPoint.getCentralY())/60f; //ここではOPENGL座標変換を行い、新しいポイント位置を設定する際に反転しています。 double code = 100.0 * RandomSet.getRandomFloatIn_1(); //ランダムな浮動小数点数0~100 if(code >= 0&&code <= 1){ nx = 0; ny = 0.00f * ox + 0.16f * oy; } else if(code > 1&& code <= 86){ nx = 0.85f*ox + 0.04f*oy; ny = -0.04f*ox + 0.85f*oy + 1.6f; } else if(code > 86&& code <= 93){ nx = 0.2f*ox - 0.26f*oy; ny = 0.23f*ox + 0.22f*oy + 1.6f; } else{ nx = -0.15f*ox + 0.28f*oy; ny = 0.26f*ox + 0.24f*oy + 0.44f; } Obj newPoint = UES.creatObj(UESI.BGIndex); newPoint.addGLPoint("70DBDB",0,0); newPoint.setColor(Color.GREEN); newPoint.setCentralX(nx*150f); //前の座標の変換を抵消します newPoint.setCentralY(600 - ny*60f); newPoint.show(); crtPoint = newPoint; //新しい点を現在の点として設定します。 } public static void main(String[] args) { UESI ues = new R(); new Barnsleyfern(ues,0); } }
[シミュレーション結果]
まとめ
これで本文のJava Chaos Game ノイズゲームのサンプルコードについてのすべてです。皆様に役立つことを願っています。興味を持たれた方、他の関連する特集もご覧ください。不十分な点があれば、コメントをお待ちしております。皆様のサポートに感謝します!
声明:本文の内容はインターネットから取得しており、著作権者に帰属します。インターネットユーザーが自発的に貢献し、自己でアップロードしたものであり、本サイトは所有権を持ちません。人工編集は行われていません。著作権侵害が疑われる内容がある場合は、メールで notice#w までお知らせください。3codebox.com(メールを送信する際は、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認がとりつかれれば、本サイトは即座に侵害疑いのコンテンツを削除します。}