In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

test of RDC (reference)

Get Adobe Flash player
by kadal 08 Apr 2009
    Embed
package {
	import flash.display.*;
	import flash.events.Event;

	[SWF(width="500", height="500", backgroundColor="#ffffff")];
	public class Main extends MovieClip {
		public var rdc:RDC;
		public var objects:Array;

		public function Main() {
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.align=StageAlign.TOP_LEFT;

			// create some simple objects
			createObjects(50);

			// allow a maximum number of 8 objects/group
			RDC.SUBDIVISION_THRESHOLD=8;

			// create RDC instance with a reference to a function
			// that handles the collision
			rdc=new RDC(collide);

			this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
		}

		private function enterFrameHandler(event:Event):void {

			for each (var c:Circle in objects) {
				c.color=0xff;
				c.x+= c.vx;
				c.y+= c.vy;
				if (c.x - c.radius <= 0) {
					c.vx=Math.abs(c.vx);
				} else if (c.x + c.radius >= stage.stageWidth) {
					c.vx=- Math.abs(c.vx);
				} else if (c.y - c.radius <= 0) {
					c.vy=Math.abs(c.vy);
				} else if (c.y + c.radius >= stage.stageHeight) {
					c.vy=- Math.abs(c.vy);
				}
			}

			// run the recursive algorithm
			// x-axis is first analyzed (0), then y-axis (1)
			rdc.recursiveClustering(objects,0,1);

		}

		private function collide(a:Circle,b:Circle):void {
			// simple bounding sphere distance check
			var r2:Number=a.radius + b.radius;
			var dx:Number=a.x - b.x;
			var dy:Number=a.y - b.y;
			var dist:Number=Math.sqrt(dx * dx + dy * dy) - r2;

			if (dist < -3) {
				for(var i:int = 0 ; i < objects.length ; i++){;
				if (objects[i] == a) {
					removeChild(objects[i]);
					objects.splice(i,1);
					newCircle();
					return;
				}
			}
		}
		if (dist <= 0) {
			// do something meaningful
			a.color=b.color=0xff0000;

			// 衝突軸ベクトル
			var cx:Number=a.x - b.x;
			var cy:Number=a.y - b.y;

			// 正規化
			var len:Number=Math.sqrt(cx * cx + cy * cy);
			cx/= len;
			cy/= len;

			var dot:Number=a.vx - b.vx * cx + a.vy - b.vy * cy;

			// 定数ベクトル
			var constX:Number=dot * cx;
			var constY:Number=dot * cy;

			a.vx=- constX + a.vx;
			a.vy=- constY + a.vy;
			b.vx=constX + b.vx;
			b.vy=constY + b.vy;
		}
	}

	private function createObjects(count:Number):void {
		objects=[];

		for (var i:Number=0; i < count; i++) {
			newCircle();
		}
	}

	private function newCircle():void {
		var radius:Number=rand(1,10);
		var x:Number=rand(radius,stage.stageWidth - radius);
		var y:Number=rand(radius,stage.stageHeight - radius);
		var circle:Circle=new Circle(x,y,radius);
		addChild(circle);
		circle.vx=Math.random() * 2;
		circle.vy=Math.random() * 2;
		objects.push(circle);
	}

	private function rand(min:int,max:int):int {
		return min + Math.floor(Math.random() * max - min + 1);
	}
}
}





import flash.display.*;
class Circle extends Sprite {
	public var radius:uint;
	public var vx:Number;
	public var vy:Number;

	public function Circle(x:uint, y:uint, radius:uint) {
		this.x = x;
		this.y = y;
		this.alpha = 0.6;
		this.radius = radius;
		this.vx = this.vy = 1;
	}

	public function set color(c:int):void {
		this.graphics.clear();
		this.graphics.lineStyle(2, c, 1);
		this.graphics.beginFill(c);
		this.graphics.drawCircle(0, 0, radius);
		this.graphics.endFill();
	}
}





import flash.display.*;
class RDC{

	public static var SUBDIVISION_THRESHOLD:int = 4;
	public static var CONTACT_THRESHOLD:Number = .001;
	public var collide:Function;

	public function RDC(collide:Function){
		this.collide = collide;
	}

	private function bruteForce(group:Array):void{
		var k:uint = group.length;
		for (var i:uint = 0; i < k; i++){
			for (var j:uint = i + 1; j < k; j++)
				collide(group[i], group[j]);
		}
	}
	
	public function recursiveClustering(group:Array, axis1:int, axis2:int):void{
		if (axis1 == -1 || group.length < RDC.SUBDIVISION_THRESHOLD){
			bruteForce(group);
		} else {
			var boundaries:Array = getOpenCloseBounds(group, axis1);
			boundaries.sortOn("pos", Array.NUMERIC);

			var newAxis1:int = axis2;
			var newAxis2:int = -1;

			var groupSubdivided:Boolean = false;

			var subgroup:Array = [], count:uint = 0;
			var k:uint = boundaries.length;
			for (var i:uint = 0; i < k; i++)	{
				var b:Object = boundaries[i];
				if (b.type == "open"){
					count++;
					subgroup.push(b.obj);
				} else {
					count--;
					if (count == 0){
						if (i != (k - 1)){
							groupSubdivided = true;
						}
						
						if (groupSubdivided){
							if (axis1 == 0){
								newAxis1 = 1;
							} else if (axis1 == 1){
								newAxis1 = 0;
							}
						}

						recursiveClustering(subgroup, newAxis1, newAxis2);
						subgroup = [];
					}
				}
			}
		}
	}

	private function getOpenCloseBounds(group:Array, axis:uint):Array{
		var k:uint = group.length;
		var boundaries:Array = [], i:uint, o:Circle;

		switch(axis){
			case 0:
				for (i = 0; i < k; i++){
					o = group[i];
					boundaries.push(new Entity("open",o.x - o.radius + RDC.CONTACT_THRESHOLD, o));
					boundaries.push(new Entity("close", o.x + o.radius - RDC.CONTACT_THRESHOLD, o));
				}
				break;
			case 1:
				for (i = 0; i < k; i++){
					o = group[i];
					boundaries.push(new Entity("open",o.y - o.radius + RDC.CONTACT_THRESHOLD, o));
					boundaries.push(new Entity("close", o.y + o.radius - RDC.CONTACT_THRESHOLD, o));
				}
		}
		return boundaries;
	}
}

class Entity{
	public var obj:Object;
	public var type:String;
	public var pos:Number;

	public function Entity(type:String, pos:Number, obj:*){
		this.type = type;
		this.pos = pos;
		this.obj = obj;
	}
}