樹木曲線はフラクタルで木を再現したもので、コンピュータアートの分野では有名です
ある程度ランダムな要素を入れるとかなり現実の木に近くなります

※クリックでstart

Flash Player 10 にしてください

Line.as


package {
	import flash.display.Sprite;
	import flash.geom.Point;
	public class Line extends Sprite {
		public var startP:Point;
		public var endP:Point;
		public var distance:Number;
		public var angle:Number;
		function Line(startP:Point, endP:Point) {
			this.startP = startP;
			this.endP = endP;
			angle = Math.atan2(endP.y-startP.y, endP.x-startP.x);
			distance = Point.distance(startP, endP);
			graphics.lineStyle(0,0x000000);
			graphics.moveTo(startP.x, startP.y);
			graphics.lineTo(endP.x, endP.y);
			graphics.endFill();
		}
	}
}

TreeCurve.as


package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.geom.Point;
	public class TreeCurve extends Sprite {
		private var list:Array = [];
		private const W:int = 300;
		private const H:int = 300;
		private const RAD:Number = Math.PI/8;
		private const a:Number = 0.75;
		function TreeCurve() {
			var line:Line=new Line(new Point(W/2, H), new Point(W/2, H*4/5));
			list.push(line);
			stage.addChild(line);
			stage.addEventListener(MouseEvent.CLICK,onClick);
			function onClick(event:MouseEvent):void {
				stage.addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
				stage.removeEventListener(MouseEvent.CLICK,onClick);
			}
		}
		private function onEnterFrameHandler(event:Event):void {
			var line:Line=list[0];
			list.splice(0, 1);
			if (line.distance <= 8) {
				stage.removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
				return;
			}
			var p:Point = new Point(line.endP.x + line.distance * a * Math.cos(line.angle + RAD), line.endP.y + line.distance * a * Math.sin(line.angle+RAD));
			var newLine:Line = new Line(line.endP, p);
			list.push(newLine);
			stage.addChild(newLine);
			p = new Point(line.endP.x + line.distance * a * Math.cos(line.angle - RAD), line.endP.y + line.distance * a * Math.sin(line.angle - RAD));
			newLine = new Line(line.endP, p);
			list.push(newLine);
			stage.addChild(newLine);
		}
	}
}
このエントリーを含むはてなブックマークはてなブックマーク - フラクタル~樹木曲線~ この記事をクリップ!Livedoorクリップ - フラクタル~樹木曲線~ BuzzurlにブックマークBuzzurlにブックマーク FC2ブックマークへ追加 Bookmark this on Delicious Digg This

はいはいフラクタルフラクタル

今回はドラゴン曲線
ドラゴン曲線を考えた人はググっても出てきませんでしたw
できた形がドラゴンに似てるからドラゴン曲線らしいです
ドラゴンなのか・・・・?w

ドラゴン曲線を見てもらう前にちょっと説明

コッホ曲線もC曲線も線分を三角形にどんどん置き換えていくことでできあがるものでした
でも、線分の上側に三角形ができるのか下側にできるのかわからないんじゃ・・・?って思った人もいるはずです
そう、実はちゃんと向きがあるのです

こんな感じ
Koch&C Arrow

この規則にしたがって書いていくとコッホ曲線とC曲線ができあがります

さて、本題のドラゴン曲線ですが、実はC曲線とほぼ一緒です
ただ一箇所矢印の向きが違うだけなのです
doragon

たったこれだけで全く違うものになります
なので当然フラクタルも無限にあります
名前の付いているフラクタルは無限にあるフラクタルの内の数個でしかないのです
暇があれば自分でおもしろい形のフラクタルを探してみるのもいいかも・・・?w

繰り返しは10回
※クリックでstart

Flash Player 10 にしてください

ソースはほぼC曲線と同じです
どこが違うか探してみてくださいw

Line.as


package {
	import flash.display.Sprite;
	import flash.geom.Point;
	public class Line extends Sprite{
		public var startP:Point;
		public var endP:Point;
		public var distance:Number;
		public var angle:Number;
		function Line(startP:Point, endP:Point) {
			this.startP = startP;
			this.endP = endP;
			distance = Point.distance(startP, endP);
			angle = Math.atan2(endP.y-startP.y, endP.x-startP.x);

			graphics.lineStyle(0,0x000000);
			graphics.moveTo(startP.x, startP.y);
			graphics.lineTo(endP.x, endP.y);
			graphics.endFill();
		}
	}
}

DoragonCurve.as


package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.geom.Point;
	public class DoragonCurve extends Sprite {
		private var list:Array = [];
		private var endPoint:Point;
		private var count:int=0;
		private const N:int=10;
		private const W:int = 300;
		private const H:int = 300;
		function DoragonCurve() {
			var line:Line=new Line(new Point(W/4,H*2/3),new Point(W-W/4, H*2/3));
			endPoint=line.startP;
			list.push(line);
			stage.addChild(line);

			stage.addEventListener(MouseEvent.CLICK,onClick);
			function onClick(event:MouseEvent):void {
				stage.addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
				stage.removeEventListener(MouseEvent.CLICK,onClick);
			}

		}
		private function onEnterFrameHandler(event:Event):void {
			var line:Line=list[0];
			stage.removeChild(line);
			list.splice(0, 1);

			var p1:Point=new Point();
			p1.x= line.distance/2 * Math.SQRT2 * Math.cos(line.angle-Math.PI/4) + line.startP.x;
			p1.y= line.distance/2 * Math.SQRT2 * Math.sin(line.angle-Math.PI/4) + line.startP.y;

			newLine=new Line(line.endP,p1);
			stage.addChild(newLine);
			list.push(newLine);
			var newLine:Line=new Line(line.startP,p1);
			stage.addChild(newLine);
			list.push(newLine);

			if (line.startP == endPoint) {
				count++;
				trace(count);
				if (count == N) {
					stage.removeEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
				}
			}

		}
	}
}

おまけ

ドラゴン曲線は実際に作ることができます
作り方は細長い紙を同じ方向に半分に折り続けていき、それを開いたあと折り目が90度になるように整えるだけです
実際に作ってみました
写真は5回折ったものです
手作りDoragonCurve

繰り返しを5回にしたflashと比べてみてください

※クリックでstart

Flash Player 10 にしてください

多少雑ですが同じ形になりました(よかったw)
実際に折ってみるとわかりますが、ドラゴン曲線はお互いの線が一回も交わりません
なんでだろー?w
暇つぶしに作ってみるのもおもしろいかもw
10回折りの手作りドラゴン曲線を作れば英雄に?!w

このエントリーを含むはてなブックマークはてなブックマーク - フラクタル~ドラゴン曲線~ この記事をクリップ!Livedoorクリップ - フラクタル~ドラゴン曲線~ BuzzurlにブックマークBuzzurlにブックマーク FC2ブックマークへ追加 Bookmark this on Delicious Digg This

ま た か
ってことでフラクタルw

C曲線とはレヴィさんが考えたフラクタルのことで、Cに似た形になることからC曲線と名づけたそうです。
適当だなおいw

C曲線はコッホ曲線と似ています
コッホ曲線は線分を3分割し、真ん中の線分を正三角形に置き換えていました
C曲線では線分全体を直角二等辺三角形に置き換えます

Koch&C

これだけでできあがる形はまったく違うものになります
これは「ほんのわずかな初期条件の違いが予想もつかないほど大きく違った結果を生む」というカオスの特徴でもあります
実はカオスとフラクタルは密接に関係しており、自然界で多くみられるカオスをグラフにプロットするとそのグラフはフラクタルな性質を示すことが知られています

すごいですなぁw

※クリックでstart

Flash Player 10 にしてください

Line.as


package {
	import flash.display.Sprite;
	import flash.geom.Point;
	public class Line extends Sprite{
		public var startP:Point;
		public var endP:Point;
		public var distance:Number;
		public var angle:Number;
		function Line(startP:Point, endP:Point) {
			this.startP = startP;
			this.endP = endP;
			distance = Point.distance(startP, endP);
			angle = Math.atan2(endP.y-startP.y, endP.x-startP.x);

			graphics.lineStyle(0,0x000000);
			graphics.moveTo(startP.x, startP.y);
			graphics.lineTo(endP.x, endP.y);
			graphics.endFill();
		}
	}
}

CCurve.as


package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.geom.Point;
	public class CCurve extends Sprite {
		private var list:Array = [];
		private var endPoint:Point;
		private var count:int=0;
		private const N:int=10;
		private const W:int = 300;
		private const H:int = 300;
		function CCurve() {
			var line:Line=new Line(new Point(W/4,H*2/3),new Point(W-W/4, H*2/3));
			endPoint=line.endP;
			list.push(line);
			stage.addChild(line);

			stage.addEventListener(MouseEvent.CLICK,onClick);
			function onClick(event:MouseEvent):void {
				stage.addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
				stage.removeEventListener(MouseEvent.CLICK,onClick);
			}

		}
		private function onEnterFrameHandler(event:Event):void {
			var line:Line=list[0];
			stage.removeChild(line);
			list.splice(0, 1);

			var p1:Point=new Point();
			p1.x= line.distance/2 * Math.SQRT2 * Math.cos(line.angle-Math.PI/4) + line.startP.x;
			p1.y= line.distance/2 * Math.SQRT2 * Math.sin(line.angle-Math.PI/4) + line.startP.y;

			var newLine:Line=new Line(line.startP,p1);
			stage.addChild(newLine);
			list.push(newLine);
			newLine=new Line(p1, line.endP);
			stage.addChild(newLine);
			list.push(newLine);

			if (line.endP == endPoint) {
				count++;
				trace(count);
				if (count == N) {
					stage.removeEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
				}
			}
		}
	}
}
このエントリーを含むはてなブックマークはてなブックマーク - フラクタル~C曲線~ この記事をクリップ!Livedoorクリップ - フラクタル~C曲線~ BuzzurlにブックマークBuzzurlにブックマーク FC2ブックマークへ追加 Bookmark this on Delicious Digg This

またフラクタルですw

シェルピンスキーのギャスケットはフラクタル図形の1種であり、自己相似的な無数の三角形からなる図形である。ポーランドの数学者ヴァツワフ・シェルピンスキにちなんで名づけられた。

これも有限の面積で無限の長さを持っています

※クリックでstart

Flash Player 10 にしてください

繰り返し回数は7回にしてます

拡大版
シェルピンスキーのギャスケット拡大版

というか配列の先頭を削除って効率悪すぎだよね・・・・w
連結リストとかキューとか作らないとなぁ・・・Javaにはデフォで入ってるんだけどなぁ
どこかにライブラリないかなぁ・・・?

getterとかはあえてつけてません

Triangle.as


package
{
	import flash.display.Sprite;
	import flash.geom.Point;

	public class Triangle extends Sprite
	{
		public var topP:Point;
		public var leftP:Point;
		public var rightP:Point;
		public function Triangle(topP:Point, leftP:Point, rightP:Point)
		{
			this.topP = topP;
			this.leftP = leftP;
			this.rightP = rightP;

			this.graphics.lineStyle(0, 0x000000);
			this.graphics.moveTo(topP.x, topP.y);
			this.graphics.lineTo(leftP.x, leftP.y);
			this.graphics.lineTo(rightP.x, rightP.y);
			this.graphics.lineTo(topP.x, topP.y);
			this.graphics.endFill();
		}

	}

}

SierpinskiGasket.as


package
{
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.display.Sprite;
	import flash.geom.Point;

	public class SierpinskiGasket extends Sprite
	{
		private const N:int = 7; //繰り返し回数
		private const W:int = 300;
		private const H:int = 300;
		private var lineLength:Number = 300; //三角形の一辺の長さ
		private var endP:Point; //終了ポイント
		private var count:int = 0; //繰り返し数カウント
		private var list:Array = [];
		public function SierpinskiGasket()
		{
			var topP:Point = new Point(lineLength * Math.cos( -Math.PI / 3),
										lineLength * Math.sin( -Math.PI / 3) + H - 20);
			var leftP:Point = new Point(0, H-20);
			var rightP:Point = new Point(W, H-20);
			var triangle:Triangle = new Triangle(topP, leftP, rightP);
			addChild(triangle);
			list.push(triangle);
			endP = rightP;
			lineLength /= 2;

			stage.addEventListener(MouseEvent.CLICK, onClickHandler);
		}

		private function onClickHandler(event:Event):void
		{
			stage.removeEventListener(MouseEvent.CLICK, onClickHandler);
			stage.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
		}

		private function onEnterFrameHandler(event:Event):void
		{
			var parent:Triangle = list[0];
			list.splice(0, 1);
			removeChild(parent);
			var leftHalfP:Point = new Point(parent.leftP.x + lineLength * Math.cos( -Math.PI / 3),
											parent.leftP.y + lineLength * Math.sin( -Math.PI / 3));
			var rightHalfP:Point = new Point(parent.topP.x + lineLength * Math.cos(Math.PI / 3),
											parent.topP.y + lineLength * Math.sin(Math.PI / 3));
			var bottomHalfP:Point = new Point(parent.leftP.x + lineLength, parent.leftP.y);

			var topTriangle:Triangle = new Triangle(parent.topP, leftHalfP, rightHalfP);
			addChild(topTriangle);
			list.push(topTriangle);
			var leftTriangle:Triangle = new Triangle(leftHalfP, parent.leftP, bottomHalfP);
			addChild(leftTriangle);
			list.push(leftTriangle);
			var rightTriangle:Triangle = new Triangle(rightHalfP, bottomHalfP, parent.rightP);
			addChild(rightTriangle);
			list.push(rightTriangle);

			if (parent.rightP == endP)
			{
				lineLength /= 2;
				count++;
				trace(count);
				if (count == N)
				{
					stage.removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
				}
			}
		}
	}
}
このエントリーを含むはてなブックマークはてなブックマーク - フラクタル~シェルピンスキーのギャスケット~ この記事をクリップ!Livedoorクリップ - フラクタル~シェルピンスキーのギャスケット~ BuzzurlにブックマークBuzzurlにブックマーク FC2ブックマークへ追加 Bookmark this on Delicious Digg This

コッホ雪片(コッホせっぺん)は、上記のコッホ曲線をつなぎ合わせ、始点と終点を一致させたものである。
コッホ雪片は、有限の面積であるにもかかわらず、無限の周囲を持つ。 ※Wikipediaより

Wikipedia引用しすぎですねww

コッホ曲線の応用編
ただコッホ曲線三つくっつけただけだけどねw

有限の面積なのに無限の周囲ってすごいね、あくまで理論上だけど。

余談だけど人間の肺と腸もフラクタルになってるらしい
限られた場所の中でできるだけ多くの酸素や栄養素を取り込むには、有限の面積で無限の周囲をもつフラクタルが一番効率がいいみたい
単純な構造の繰り返しだからフラクタル構造を作るための遺伝子情報も少なくてすむし ってことらしい
うーん人間ってすごい

※クリックでstart

Flash Player 10 にしてください

例によって拡大版をどうぞ
コッホ雪片拡大版

Lineクラスは前回と同じ

KochSnow.as


package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.geom.Point;
	public class KochSnow extends Sprite {
		private var list:Array = [];
		private var endPoint:Point;
		private var count:int=0;
		private const N:int=6;
		private const W:int = 300;
		private const H:int = 300;
		private const L:int = 150;
		function KochSnow() {
			var p1:Point = new Point(W/2, H/2 - L);
			var p2:Point = new Point(L * Math.cos(Math.PI/6) + W/2, L * Math.sin(Math.PI/6) + H/2);
			var p3:Point = new Point(L * Math.cos(Math.PI/6*5) + W/2, L * Math.sin(Math.PI/6) + H/2);
			var line:Line=new Line(p1, p2);
			list.push(line);
			stage.addChild(line);
			line = new Line(p2, p3);
			list.push(line);
			stage.addChild(line);
			line = new Line(p3, p1);
			list.push(line);
			stage.addChild(line);
			endPoint = p1;

			stage.addEventListener(MouseEvent.CLICK,onClick);
			function onClick(event:MouseEvent):void {
				stage.addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
				stage.removeEventListener(MouseEvent.CLICK,onClick);
			}

		}
		private function onEnterFrameHandler(event:Event):void {
			var line:Line=list[0];
			stage.removeChild(line);
			list.splice(0, 1);

			var p1:Point=new Point();
			p1.x=Math.cos(line.angle) * line.distance / 3 + line.startP.x;
			p1.y=Math.sin(line.angle) * line.distance / 3 + line.startP.y;
			var p2:Point=new Point();
			p2.x=Math.cos(line.angle - Math.PI / 3) * line.distance / 3 + p1.x;
			p2.y=Math.sin(line.angle - Math.PI / 3) * line.distance / 3 + p1.y;
			var p3:Point=new Point();
			p3.x=Math.cos(line.angle + Math.PI / 3) * line.distance / 3 + p2.x;
			p3.y=Math.sin(line.angle + Math.PI / 3) * line.distance / 3 + p2.y;

			var newLine:Line=new Line(line.startP,p1);
			stage.addChild(newLine);
			list.push(newLine);
			newLine=new Line(p1,p2);
			stage.addChild(newLine);
			list.push(newLine);
			newLine=new Line(p2,p3);
			stage.addChild(newLine);
			list.push(newLine);
			newLine=new Line(p3,line.endP);
			stage.addChild(newLine);
			list.push(newLine);

			if (line.endP == endPoint) {
				count++;
				if (count == N) {
					stage.removeEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
				}
			}
		}
	}
}
このエントリーを含むはてなブックマークはてなブックマーク - フラクタル~コッホ雪片~ この記事をクリップ!Livedoorクリップ - フラクタル~コッホ雪片~ BuzzurlにブックマークBuzzurlにブックマーク FC2ブックマークへ追加 Bookmark this on Delicious Digg This

« Previous Entries