/**
* Copyright tkinjo ( http://wonderfl.net/user/tkinjo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/83XF
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
[SWF(width="465", height="465", backgroundColor="0xffffff", frameRate="60")]
/**
* 3点を通る円
*
* @author tkinjo
*/
public class Main extends Sprite
{
private const POINT_NUM:int = 3;
private const POINT_RADIUS:Number = 10;
private var points:Vector.<Sprite>;
private var textField:TextField;
public function Main()
{
init();
}
private function enterFrameHandler( event:Event ):void {
var pointA:Point = new Point( points[0].x, points[0].y );
var pointB:Point = new Point( points[1].x, points[1].y );
var pointC:Point = new Point( points[2].x, points[2].y );
var centerPoint:Point = getCenterPoint( pointA, pointB, pointC );
var radius:Number = getRadius( centerPoint, pointA );
graphics.clear();
graphics.lineStyle( 1 );
/*
// 線分 AB、AC の中点
var lineABMiddlePoint:Point = middlePoint( pointA, pointB );
var lineBCMiddlePoint:Point = middlePoint( pointB, pointC );
graphics.drawCircle( lineABMiddlePoint.x, lineABMiddlePoint.y, 1 );
graphics.drawCircle( lineBCMiddlePoint.x, lineBCMiddlePoint.y, 1 );
// 線分 AB、AC の垂直二等分線
var lineSegmentABPerpendicularBisectorSlope:Number = -1 / slope( pointA, pointB );
var lineSegmentBCPerpendicularBisectorSlope:Number = -1 / slope( pointB, pointC );
var lineSegmentABPerpendicularBisectorB:Number = linearEquationsSolutionB( lineABMiddlePoint, lineSegmentABPerpendicularBisectorSlope );
var lineSegmentBCPerpendicularBisectorB:Number = linearEquationsSolutionB( lineBCMiddlePoint, lineSegmentBCPerpendicularBisectorSlope );
var lineSegmentABPerpendicularBisectorEquationAB:Point = new Point(lineSegmentABPerpendicularBisectorSlope, lineSegmentABPerpendicularBisectorB);
var lineSegmentBCPerpendicularBisectorEquationAB:Point = new Point(lineSegmentBCPerpendicularBisectorSlope, lineSegmentBCPerpendicularBisectorB);
graphics.moveTo( 0, lineSegmentABPerpendicularBisectorEquationAB.y );
graphics.lineTo( stage.stageWidth, lineSegmentABPerpendicularBisectorEquationAB.x * stage.stageWidth + lineSegmentABPerpendicularBisectorEquationAB.y );
graphics.moveTo( 0, lineSegmentBCPerpendicularBisectorEquationAB.y );
graphics.lineTo( stage.stageWidth, lineSegmentBCPerpendicularBisectorEquationAB.x * stage.stageWidth + lineSegmentBCPerpendicularBisectorEquationAB.y );
//*/
if( centerPoint.x && centerPoint.y ) {
// 3点を通る円
graphics.drawCircle( centerPoint.x, centerPoint.y, radius );
// 3点を通る円の中心
graphics.drawCircle( centerPoint.x, centerPoint.y, 2 );
}
textField.text = "";
textField.appendText( "centerPoint.x = " + centerPoint.x + "\n" );
textField.appendText( "centerPoint.y = " + centerPoint.y + "\n" );
textField.appendText( "radius = " + radius + "\n" );
}
private function init():void {
points = createPoints( POINT_NUM );
points.forEach( function( item:Sprite, index:int, vector:Vector.<Sprite> ):void {
addChild( item );
item.addEventListener(MouseEvent.MOUSE_OVER, pointMouseOverHandler);
item.addEventListener(MouseEvent.MOUSE_OUT, pointMouseOutHandler);
item.addEventListener(MouseEvent.MOUSE_DOWN, pointMouseDownHandler);
item.addEventListener(MouseEvent.MOUSE_UP, pointMouseUpHandler);
} );
points[0].x = stage.stageWidth / ( points.length + 1 );
points[0].y = stage.stageHeight / ( points.length + 1 );
points[1].x = stage.stageWidth / ( points.length + 1 ) * 3;
points[1].y = stage.stageHeight / ( points.length + 1 ) + 1;
points[2].x = stage.stageWidth / ( points.length + 1 ) * 3;
points[2].y = stage.stageHeight / ( points.length + 1 ) * 3;
textField = new TextField();
textField.autoSize = TextFieldAutoSize.LEFT;
addChild( textField );
addEventListener(Event.ENTER_FRAME, enterFrameHandler );
}
private function createPoints( pointNum:int ):Vector.<Sprite> {
var points:Vector.<Sprite> = new Vector.<Sprite>(pointNum);
points.forEach( function( item:Sprite, index:int, vector:Vector.<Sprite> ):void {
item = new Sprite();
vector[index] = item;
item.graphics.beginFill( 0 );
item.graphics.drawCircle( 0, 0, POINT_RADIUS );
item.graphics.endFill();
} );
return points;
}
private function pointMouseOverHandler( event:MouseEvent ):void {
var point:Sprite = event.currentTarget as Sprite;
point.buttonMode = true;
}
private function pointMouseOutHandler( event:MouseEvent ):void {
var point:Sprite = event.currentTarget as Sprite;
point.buttonMode = false;
}
private var pressedPoint:Sprite;
private function pointMouseDownHandler( event:MouseEvent ):void {
var point:Sprite = event.currentTarget as Sprite;
if( !stage.hasEventListener(MouseEvent.MOUSE_MOVE) )
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
pressedPoint = point;
}
private function mouseMoveHandler( event:MouseEvent ):void {
pressedPoint.x = event.stageX;
pressedPoint.y = event.stageY;
}
private function pointMouseUpHandler( event:MouseEvent ):void {
var point:Sprite = event.currentTarget as Sprite;
if( stage.hasEventListener(MouseEvent.MOUSE_MOVE) )
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
}
}
import flash.geom.Point;
function getRadius( centerPoint:Point, pointA:Point ):Number {
var pointAFromCenterPoint:Point = pointA.subtract(centerPoint);
var radius:Number = pointAFromCenterPoint.length;
return radius;
}
function getCenterPoint( pointA:Point, pointB:Point, pointC:Point ):Point {
var lineSegmentABPerpendicularBisectorEquationAB:Point;
var lineSegmentBCPerpendicularBisectorEquationAB:Point;
var lineSegmentABPerpendicularBisectorSlope:Number = -1 / slope( pointA, pointB );
var lineSegmentBCPerpendicularBisectorSlope:Number = -1 / slope( pointB, pointC );
var lineABMiddlePoint:Point = middlePoint( pointA, pointB );
var lineBCMiddlePoint:Point = middlePoint( pointB, pointC );
var lineSegmentABPerpendicularBisectorB:Number = linearEquationsSolutionB( lineABMiddlePoint, lineSegmentABPerpendicularBisectorSlope );
var lineSegmentBCPerpendicularBisectorB:Number = linearEquationsSolutionB( lineBCMiddlePoint, lineSegmentBCPerpendicularBisectorSlope );
lineSegmentABPerpendicularBisectorEquationAB = new Point(lineSegmentABPerpendicularBisectorSlope, lineSegmentABPerpendicularBisectorB);
lineSegmentBCPerpendicularBisectorEquationAB = new Point(lineSegmentBCPerpendicularBisectorSlope, lineSegmentBCPerpendicularBisectorB);
var centerPoint:Point = simultaneousEquationsSolutionXY( lineSegmentABPerpendicularBisectorEquationAB, lineSegmentBCPerpendicularBisectorEquationAB );
return centerPoint;
}
function slope(point1:Point, point2:Point):Number {
var x1:Number = point1.x;
var y1:Number = point1.y;
var x2:Number = point2.x;
var y2:Number = point2.y;
var a:Number = ( y2 - y1 ) / ( x2 - x1 );
return a;
}
function middlePoint(point1:Point, point2:Point):Point {
var x1:Number = point1.x;
var y1:Number = point1.y;
var x2:Number = point2.x;
var y2:Number = point2.y;
var x:Number = ( x1 + x2 ) / 2;
var y:Number = ( y1 + y2 ) / 2;
return new Point(x, y);
}
function linearEquationsSolutionB(point:Point, a:Number):Number {
var x:Number = point.x;
var y:Number = point.y;
var b:Number = y - a * x;
return b;
}
function simultaneousEquationsSolutionXY(point1:Point, point2:Point):Point {
var a1:Number = point1.x;
var b1:Number = point1.y;
var a2:Number = point2.x;
var b2:Number = point2.y;
var x:Number = ( b1 - b2 ) / ( a2 - a1 );
var y:Number = a1 * x + b1;
return new Point(x,y);
}