flash on 2010-3-31
2010年3月31日
二つの円の接触・包含関係を判定
/**
* Copyright tenasaku ( http://wonderfl.net/user/tenasaku )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/9orf
*/
// 2010年3月31日
// 二つの円の接触・包含関係を判定
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
public class FlashTest extends Sprite {
private const STROKE:Number = 3;
private var tf:TextField;
private var ring1:Sprite,ring2:Sprite;
private var radius1:Number,radius2:Number;
private var velo1:Point,velo2:Point;
private function initialize(e:Event):void {
radius1 = 100;
ring1 = new Sprite();
ring1.graphics.lineStyle(STROKE,0xff0000);
ring1.graphics.beginFill(0x00ff00,0.5);
ring1.graphics.drawCircle(0,0,radius1);
ring1.graphics.endFill();
radius2 = 60;
ring2 = new Sprite();
ring2.graphics.lineStyle(STROKE,0xff0000);
ring2.graphics.beginFill(0x0000ff,0.5);
ring2.graphics.drawCircle(0,0,radius2);
ring2.graphics.endFill();
ring1.x = 232.5;
ring1.y = 232.5;
ring2.x = 300;
ring2.y = 110;
this.addChild(ring1);
this.addChild(ring2);
tf = new TextField();
tf.background = true;
tf.backgroundColor = 0xffff00;
tf.alpha = 0.5;
tf.width = 200;
tf.height = 32;
tf.text = "小さいほうの円をドラッグしてください";
this.addChild(tf);
ring2.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}
private function onMouseDown(e:MouseEvent):void {
ring2.startDrag();
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
private function onMouseMove(e:MouseEvent):void {
e.updateAfterEvent();
switch (howCirclesMeet()) {
case 0: tf.text = "離れている"; break;
case 1: tf.text = "接している"; break;
case 2: tf.text = "部分的に重なっている"; break;
case 3: tf.text = "接している"; break;
case 4: tf.text = "完全に重なっている"; break;
default: tf.text = "";
}
}
private function onMouseUp(e:MouseEvent):void {
ring2.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
}
// 二円の接触状態を返す
// 0: 接触していない
// 1: 外接している
// 2: 部分的に重なっている
// 3: 内接している
// 4: 完全に重なっている
// 「接している」判定には描画の線幅程度に「余裕」を持たせる
private function howCirclesMeet():int {
var dx:Number = ring1.x - ring2.x;
var dy:Number = ring1.y - ring2.y;
var distance:Number = Math.sqrt(dx*dx+dy*dy);
if ( distance > radius1+radius2+STROKE ) {
return 0; // 離れている
} else if ( distance > radius1+radius2-STROKE ) {
return 1; // 外接している
} else if ( distance > Math.abs(radius1-radius2)+STROKE ) {
return 2; // 部分的に重なっている
} else if ( distance > Math.abs(radius1-radius2)-STROKE ) {
return 3; // 内接している
} else {
return 4; // 完全に重なっている
}
}
public function FlashTest() {
if ( stage != null ) {
initialize(null);
} else {
this.addEventListener(Event.ADDED_TO_STAGE, initialize);
}
}
}
}