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

forked from: 平行四辺形に内接する楕円の作図

赤と青の大きい点はドラッグ可能です
平行四辺形に内接する楕円を作図します
出展: 数学100の勝利 43
/**
 * Copyright webdesignkeys ( http://wonderfl.net/user/webdesignkeys )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1wKn
 */

// forked from keno42's 平行四辺形に内接する楕円の作図
package  
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Point;
        // 赤と青の大きい点はドラッグ可能です
        // 平行四辺形に内接する楕円を作図します
        // 出展: 数学100の勝利 43
    public class Heikou_Daen extends Sprite
    {
        private var mpA:MovablePoint = new MovablePoint(4, 0xFFFF0000, true);
        private var mpB:MovablePoint = new MovablePoint(4, 0xFFFF0000, true);
        private var mpC:MovablePoint = new MovablePoint(4, 0xFFFF8888, false);
        private var mpD:MovablePoint = new MovablePoint(4, 0xFFFF0000, true);
        private var mpN:MovablePoint = new MovablePoint(4, 0xFF0000FF, true);
        
        // 弧(1/4)の分割数
        private const NUM:int = 20;
        public function Heikou_Daen() 
        {
            mpA.x = 70;
            mpA.y = 370;
            addChild(mpA);
            mpB.x = 380;
            mpB.y = 310;
            addChild(mpB);
            addChild(mpC);
            mpD.x = 80;
            mpD.y = 130;
            addChild(mpD);
            mpN.x = 300;
            mpN.y = 300;
            addChild(mpN);
            this.addEventListener("startRefresh", onStartRefresh, true);
            this.addEventListener("stopRefresh", onStopRefresh, true);
            _refresh();
        }
        
        private function onStopRefresh(e:Event):void 
        {
            removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            _refresh();
        }
        
        private function onStartRefresh(e:Event):void 
        {
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function onEnterFrame(e:Event):void 
        {
            _refresh();
        }
        
        private function _refresh():void
        {
            // CをAB+ADに移動
            mpC.x = mpB.x + mpD.x - mpA.x;
            mpC.y = mpB.y + mpD.y - mpA.y;
            
            // Nを垂点に移動
            var nLoc:Point = GeomUtil.getSuiten(mpA.x, mpA.y, mpB.x, mpB.y, mpN.x, mpN.y);
            
            var nCase:int = 0;
            if ( nLoc.x > mpA.x && nLoc.x > mpB.x )
                nCase = 1;
            else if ( nLoc.x < mpA.x && nLoc.x < mpB.x )
                nCase = 2;
            if ( mpA.x > mpB.x ) nCase |= 4;
            
            switch( nCase ) {
                case 5:
                case 2:
                    nLoc = GeomUtil.getNaibunten(mpA.x, mpA.y, mpB.x, mpB.y, 0.0001);
                    break;
                case 1:
                case 6:
                    nLoc = GeomUtil.getNaibunten(mpA.x, mpA.y, mpB.x, mpB.y, 0.9999);
                    break;
            }
            
            mpN.x = nLoc.x;
            mpN.y = nLoc.y;
            
            // 描画
            graphics.clear();
            graphics.lineStyle(2, 0x0);
            graphics.moveTo(mpA.x, mpA.y);
            graphics.lineTo(mpB.x, mpB.y);
            graphics.lineTo(mpC.x, mpC.y);
            graphics.lineTo(mpD.x, mpD.y);
            graphics.lineTo(mpA.x, mpA.y);
            
            // 接点の計算
            var temp:Point = new Point(mpC.x - mpA.x, mpC.y - mpA.y);
            var K:Point = GeomUtil.getKoten(mpN.x, mpN.y, mpN.x + temp.x, mpN.y + temp.y, mpB.x, mpB.y, mpC.x, mpC.y);
            var temp2:Point = new Point(mpD.x - mpB.x, mpD.y - mpB.y);
            var H:Point = GeomUtil.getKoten(mpN.x, mpN.y, mpN.x + temp2.x, mpN.y + temp2.y, mpA.x, mpA.y, mpD.x, mpD.y);
            var M:Point = new Point(K.x + H.x - mpN.x, K.y + H.y - mpN.y);
            
            // 中央の計算
            var O:Point = GeomUtil.getChuten(mpA.x, mpA.y, mpC.x, mpC.y);
            
            // 弧上の点の計算
            var i:int, s:Number, p:Point;
            var points:Array = [];
            // N-OK x M-CK
            for ( i = 0; i < NUM; i++ ) {
                s = i / NUM;
                var OKs:Point = GeomUtil.getNaibunten(O.x, O.y, K.x, K.y, s);
                var CKs:Point = GeomUtil.getNaibunten(mpC.x, mpC.y, K.x, K.y, s);
                p = GeomUtil.getKoten( mpN.x, mpN.y, OKs.x, OKs.y, M.x, M.y, CKs.x, CKs.y );
                points.push(p);
            }
            // M-KO x N-KB
            for ( i = 0; i < NUM; i++ ) {
                s = i / NUM;
                var KOs:Point = GeomUtil.getNaibunten(K.x, K.y, O.x, O.y, s);
                var KBs:Point = GeomUtil.getNaibunten(K.x, K.y, mpB.x, mpB.y, s);
                p = GeomUtil.getKoten( M.x, M.y, KOs.x, KOs.y, mpN.x, mpN.y , KBs.x, KBs.y);
                points.push(p);
            }
            for ( i = 0; i < 2*NUM; i++ ) {
                points.push(new Point(2 * O.x - points[i].x, 2 * O.y - points[i].y));
            }
            points.push( M );
            graphics.lineStyle(0, 0x00FF00);
            graphics.moveTo(M.x, M.y);
            var len:int = points.length;
            for ( i = 0; i < len; i++ ) {
                graphics.lineTo(points[i].x, points[i].y);
            }
            graphics.lineStyle(0, 0x0000FF);
            for ( i = 0; i < len; i++ ) {
                graphics.drawCircle(points[i].x, points[i].y, 2);
            }
            
        }
        
        
    }
    
}

import flash.display.*;
import flash.events.*;
import flash.geom.Matrix;
// ドラッグで移動する点
class MovablePoint extends Sprite{
    public function MovablePoint(radius:Number, color:uint, isMovable:Boolean){
        this.graphics.lineStyle(1, color);
        this.graphics.beginFill(color & 0xFFFFFF, 0.75);
        this.graphics.drawCircle(0, 0, radius);
        
        if( isMovable ){
            this.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
            this.buttonMode = true;
        }
    }
    private function onDown(e:MouseEvent):void{
        this.startDrag();
        this.dispatchEvent(new Event("startRefresh"));
        this.addEventListener(MouseEvent.MOUSE_UP, onUp);
        this.stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
    }
    private function onUp(e:MouseEvent):void{
        this.stopDrag();
        this.dispatchEvent(new Event("stopRefresh"));
        this.removeEventListener(MouseEvent.MOUSE_UP, onUp);
        this.stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
    }
}

import flash.geom.Point;
class GeomUtil {
    // 垂点座標計算メソッド
    public static function getSuiten(Ax:Number, Ay:Number, Bx:Number, By:Number, Cx:Number, Cy:Number):Point{
        var A:Point = new Point(Ax, Ay); // 直線上の点A
        var B:Point = new Point(Bx, By); // 直線上の点B
        var C:Point = new Point(Cx, Cy); // 直線外の点C
        var AB:Point = B.subtract(A); // ベクトルAB
        var unitAB:Point = AB.clone(); // ABの単位ベクトル
        unitAB.normalize(1);
        var AC:Point = C.subtract(A); // ベクトルAC
        
        // ACのAB方向の成分を取得
        var unitABxAC:Number = unitAB.x*AC.x+unitAB.y*AC.y;
        
        // ACのAB軸への射影を計算
        var ret:Point = new Point(unitAB.x*unitABxAC, unitAB.y*unitABxAC);
        return ret.add(A); // A+上の射影が垂点の位置
    }
    // 直線ABと直線CDの交点座標計算メソッド
    public static function getKoten(Ax:Number, Ay:Number, Bx:Number, By:Number, Cx:Number, Cy:Number, Dx:Number, Dy:Number):Point {
        var mat:Matrix = new Matrix(By - Ay, Dy - Cy, Ax - Bx, Cx - Dx);
        var XY:Point = mat.transformPoint(new Point(Cx - Ax, Cy - Ay));
        var abcd:Number = mat.a * mat.d - mat.b * mat.c;
        XY.x /= abcd;
        return new Point(Cx + XY.x * (Dx - Cx), Cy + XY.x * (Dy - Cy));
    }
    // 線分ABの中点座標計算メソッド
    public static function getChuten(Ax:Number, Ay:Number, Bx:Number, By:Number):Point {
        return new Point(Ax + 0.5 * (Bx - Ax), Ay + 0.5 * (By - Ay));
    }
    // 線分ABをs:1-sに内分する点の座標計算メソッド
    public static function getNaibunten(Ax:Number, Ay:Number, Bx:Number, By:Number, s:Number):Point {
        return new Point(Ax + s * (Bx - Ax), Ay + s * (By - Ay));
    }
}