3点を通る円

by tkinjo
3点を通る円

@author tkinjo
♥2 | Line 145 | Modified 2009-10-23 16:30:01 | MIT License
play

ActionScript3 source code

/**
 * 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);
}