極座標で獲る

2011.09.08

日々のお仕事シリーズ(仮称)

2 つの円ボタンの中点を結ぶ直線と中点において直交する直線を描画して、さらに、この直線と平行する 2 つの接線を描画するサンプル。ある案件の機能要件を満たすために作成したものですが、これがどのように活かされるかは秘密ということで。

実装コード (Main.mxml)

<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx   = "http://ns.adobe.com/mxml/2009"
xmlns:s    = "library://ns.adobe.com/flex/spark"
fontWeight = "bold"
fontSize   = "20"
>

<fx:Script>
<![CDATA[
    protected const R90               :Number = 1.570796326794897; //90 * Math.PI / 180;
    protected var startMouseDownPoint :Point  = new Point();
    protected var startTargetPoint    :Point  = new Point();
    protected var targetButton        :Button;
    protected override function createChildren():void {
        super.createChildren();
        fromButton.addEventListener(MouseEvent.MOUSE_DOWN, buttonMouseDownHandler);
        toButton.addEventListener(MouseEvent.MOUSE_DOWN, buttonMouseDownHandler);
    }
    protected function buttonMouseDownHandler(event:MouseEvent):void {
        targetButton          = event.currentTarget as Button;
        startMouseDownPoint.x = stage.mouseX;
        startMouseDownPoint.y = stage.mouseY;
        startTargetPoint.x    = targetButton.x;
        startTargetPoint.y    = targetButton.y;
        stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler);
        stage.addEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler);
    }
    protected function stageMouseMoveHandler(event:MouseEvent):void {
        targetButton.move( startTargetPoint.x + stage.mouseX - startMouseDownPoint.x,
                           startTargetPoint.y + stage.mouseY - startMouseDownPoint.y  );
        drawLine();
        event.updateAfterEvent();
    }
    protected function stageMouseUpHandler(event:MouseEvent):void {
        stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler);
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler);
        targetButton = null;
    }
    protected function drawLine():void {
        const R      :int = 50;
        var g        :Graphics = bg.graphics;
        var fromGP   :Point;
        var toGP     :Point;
        var bgFromLP :Point;
        var bgToLP   :Point;
        var bgPP_A   :Point;
        var bgPP_B   :Point;
        var radians  :Number;

        g.clear();

        fromGP   = bg.localToGlobal( new Point(fromButton.x + (fromButton.width * 0.5), fromButton.y + (fromButton.height * 0.5) ) );
        toGP     = bg.localToGlobal( new Point(toButton.x   + (toButton.width * 0.5),   toButton.y   + (toButton.height   * 0.5) ) );

        bgFromLP = bg.globalToContent(fromGP);
        bgToLP   = bg.globalToContent(toGP);

        g.lineStyle(3, 0x333333);
        g.moveTo(bgFromLP.x, bgFromLP.y);
        g.lineTo(bgToLP.x, bgToLP.y);

        radians = Math.atan2(bgToLP.y - bgFromLP.y, bgToLP.x - bgFromLP.x) + R90;

        bgPP_A = Point.polar(R,  radians);
        bgPP_B = Point.polar(-R, radians);


        g.lineStyle(0,0x3333ff);
        g.moveTo(bgFromLP.x + bgPP_A.x, bgFromLP.y + bgPP_A.y);
        g.lineTo(bgFromLP.x + bgPP_B.x, bgFromLP.y + bgPP_B.y);
        g.moveTo(bgToLP.x   + bgPP_A.x, bgToLP.y   + bgPP_A.y);
        g.lineTo(bgToLP.x   + bgPP_B.x, bgToLP.y   + bgPP_B.y);

        g.lineStyle(0,0xff3333);
        g.moveTo(bgFromLP.x + bgPP_A.x, bgFromLP.y + bgPP_A.y);
        g.lineTo(bgToLP.x   + bgPP_A.x, bgToLP.y   + bgPP_A.y);
        g.moveTo(bgFromLP.x + bgPP_B.x, bgFromLP.y + bgPP_B.y);
        g.lineTo(bgToLP.x   + bgPP_B.x, bgToLP.y   + bgPP_B.y);

    }
]]>
</fx:Script>

<s:Group id="bg" width="100%" height="100%">
<s:layout><s:LayoutBase /></s:layout>
<s:Button id="fromButton" width="100" height="100" cornerRadius="50" alpha=".5" label="from" />
<s:Button id="toButton"   width="100" height="100" cornerRadius="50" alpha=".5" label="to" />
</s:Group>

</s:Application>

出力結果

出力結果は次の通り

[SWF]http://public-blog-dev.s3.amazonaws.com/wp-content/uploads/2011/09/PolarSample20110908.swf,640,480[/SWF]