万花筒之等边三角形镜面反射

万花筒 everyinch 3865℃ 0评论

点击图像打开实例文件。操作提示:点击用来变化万花筒图案。

主类:

package{
	import flash.display.Sprite;
	import flash.events.MouseEvent;

	import net.everyinch.kals.KaleidoscopeThreeMirrors;

	[SWF(width=800,height=600,backgroundColor=0x000000)]
	public class KaleidoscopeThreeMirrorsTest1 extends Sprite{
		private var kal:KaleidoscopeThreeMirrors;

		public function KaleidoscopeThreeMirrorsTest1(){
			kal = new KaleidoscopeThreeMirrors("assets/Flower0.jpg",60,200);
			addChild(kal);
			kal.x = 100;
			kal.y = 10;

			stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
		}

		private function onMouseDown(e:MouseEvent):void{
			kal.doSpin();
		}
	}
}

等边三角形镜面反射的实现:

package net.everyinch.kals{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.net.URLRequest;
	import flash.text.TextFieldAutoSize;

	public class KaleidoscopeThreeMirrors extends Sprite{
		private var loaderText:TextField;
		private var loader:Loader;
		private var bmpd:BitmapData;
		private var picWidth:Number;
		private var picHeight:Number;

		private var angle:Number;
		private var triangleSide:Number;
		private var triangleHeight:Number;

		private var segments:Array;
		private var segmentEven:Shape;
		private var segmentOdd:Shape;

		private var hexagons:Array;
		private var hexagonRadius:Number;
		private var numCols:int;
		private var numRows:int;

		private var radius:Number;
		public var displayWidth:Number;
		public var displayHeight:Number;

		private var isReady:Boolean;

		public function KaleidoscopeThreeMirrors(url:String,hr:Number,dr:Number){
			hexagonRadius = hr;
			angle = 60;
			triangleSide = hexagonRadius;
			triangleHeight = triangleSide * Math.sin(Math.PI/3);
			radius = dr;
			isReady = false;
			setUpLoaderText();
			loadImg(url);
		}

		private function setUpLoaderText():void{
			var loaderFormat:TextFormat = new TextFormat();
			loaderFormat.font = "Arial";
			loaderFormat.size = 20;
			loaderFormat.color = 0xEEEEEE;
			loaderText = new TextField();
			loaderText.defaultTextFormat = loaderFormat;
			loaderText.text = "";
			loaderText.autoSize = TextFieldAutoSize.CENTER;
			loaderText.x = 0;
			loaderText.y = 0;
			loaderText.mouseEnabled = false;
			addChild(loaderText);
		}

		private function loadImg(s:String):void{
			loader = new Loader();
			loader.load(new URLRequest(s));
			loaderText.text = "开始加载... ...";
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onError);
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onProgress);
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
		}

		private function onError(e:IOErrorEvent):void{
			loaderText.text = "无法加载图像,请刷新页面!";
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onError);
			loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,onProgress);
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onComplete);
			loader = null;
		}

		private function onProgress(e:ProgressEvent):void{
			loaderText.text = "已加载: " + String(Math.floor(e.bytesLoaded/1024)) + "KB/" + String(Math.floor(e.bytesTotal/1024)) + "KB.";
		}

		private function onComplete(e:Event):void{
			bmpd = Bitmap(loader.content).bitmapData;
			picWidth = bmpd.width;
			picHeight = bmpd.height;
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onError);
			loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,onProgress);
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onComplete);
			loader = null;
			loaderText.text = "";
			loaderText.visible = false;

			createDisplay();
			drawDisplay();
			isReady = true;
		}

		private function createDisplay():void{
			numCols = Math.ceil(radius*2/(triangleSide*3/2))+1; // 直径/(三角形边长*3/2)
			numRows = Math.ceil(radius*2/(triangleHeight*2))+1; // 直径/(三角形高*2)
			displayWidth = numCols*3/2*triangleSide+triangleSide/2; // 三角形边长*3/2*列数+三角形边长/2
			displayHeight = numRows*2*triangleHeight+triangleHeight; //三角形高*2*行数+三角形高

			segmentEven = new Shape();
			segmentOdd = new Shape();

			hexagons = [];
			segments = [];
			for(var i:int=0;i<numRows;i++){
				hexagons[i] = [];
				segments[i] = [];
				for(var j:int=0;j<numCols;j++){
					segments[i][j] = [];
					hexagons[i][j] = new Sprite();
					addChild(hexagons[i][j]);
					hexagons[i][j].x = triangleSide*3/2*j + triangleSide; // 六边形中心点的水平坐标 = 三角形边长*3/2*j+三角形边长
					if(j % 2 == 0){
						// 如果是偶数列,六边形中心点的垂直坐标 = 三角形高*2*i+三角形高
						hexagons[i][j].y = triangleHeight*2*i + triangleHeight;
					}
					else{
						// 如果是奇数列,六边形中心点的垂直坐标 = 三角形高*2*i+三角形高*2
						hexagons[i][j].y = triangleHeight*2*i + triangleHeight*2;
					}
					for(var k:int=0;k<6;k++){
						segments[i][j][k] = new Shape();
						hexagons[i][j].addChild(segments[i][j][k]);
						segments[i][j][k].rotation = k*angle;
					}
				}
			}

		}

		private function drawDisplay():void{
			segmentEven.graphics.clear();
			segmentOdd.graphics.clear();
			for(var i:int=0;i<numRows;i++){
				for(var j:int=0;j<numCols;j++){
					for(var k:int=0;k<6;k++){
						segments[i][j][k].graphics.clear();
					}
				}
			}

			var matrix1:Matrix = new Matrix();
			matrix1.translate(picWidth/2,picHeight/2);
			matrix1.rotate(Math.random()*2*Math.PI);
			matrix1.scale(Math.random()*0.3+0.7,Math.random()*0.3+0.7);
			segmentEven.graphics.lineStyle();
			segmentEven.graphics.beginBitmapFill(bmpd,matrix1,true,true);
			segmentEven.graphics.moveTo(0,0);
			segmentEven.graphics.lineTo(-triangleSide/2,-triangleHeight);
			segmentEven.graphics.lineTo(triangleSide/2,-triangleHeight);
			segmentEven.graphics.lineTo(0,0);
			segmentEven.graphics.endFill();

			var matrix2:Matrix = matrix1.clone();
			matrix2.concat(new Matrix(-1,0,0,1,0,0));
			segmentOdd.graphics.lineStyle();
			segmentOdd.graphics.beginBitmapFill(bmpd,matrix2,true,true);
			segmentOdd.graphics.moveTo(0,0);
			segmentOdd.graphics.lineTo(-triangleSide/2,-triangleHeight);
			segmentOdd.graphics.lineTo(triangleSide/2,-triangleHeight);
			segmentOdd.graphics.lineTo(0,0);
			segmentOdd.graphics.endFill();

			for(i=0;i<numRows;i++){
				for(j=0;j<numCols;j++){
					for(k=0;k<6;k++){
						if(k % 2 == 0){
							segments[i][j][k].graphics.copyFrom(segmentEven.graphics);
						}
						else{
							segments[i][j][k].graphics.copyFrom(segmentOdd.graphics);
						}
					}
				}
			}
		}

		public function doSpin():void{
			if(isReady){
				drawDisplay();
			}
		}

		public function destroy():void{
			if(!isReady){
				return;
			}

			for(var i:int=0;i<numRows;i++){
				for(var j:int=0;j<numCols;j++){
					for(var k:int=0;k<6;k++){
						segments[i][j][k].graphics.clear();
					}
				}
			}

			bmpd.dispose();
			isReady = false;
		}
	}
}
分享&收藏

转载请注明:陈童的博客 » 万花筒之等边三角形镜面反射

喜欢 (1)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
'; } if( dopt('d_footcode_b') ) echo dopt('d_footcode'); ?>