ActionScriptは2つの直線交差アークを越えたアルゴリズムを実現する

17799 ワード

/**

 * Created with IntelliJ IDEA.

 * User: DongYang

 * Date: 13-3-5

 * Time:   11:04

 * To change this template use File | Settings | File Templates.

 */

package org.un.cava.birdeye.ravis.editor {

import flash.display.Graphics;

import flash.geom.Point;



import mx.charts.LinearAxis;



import org.un.cava.birdeye.ravis.editor.line.LineModel;

import org.un.cava.birdeye.ravis.editor.util.V2D;



public class StepOverLine {





    public function StepOverLine() {

    }



    public static function findIntersection(lineA:LineModel, lineB:LineModel):Point {

        //var p1:Point=new Point(0,1);

        //var p2:Point=new Point(10,1);

        //var p3:Point=new Point(10,1);

        //var p4:Point=new Point(10,8);



        var p1:Point = lineA.p1;

        var p2:Point = lineA.p2;

        var p3:Point = lineB.p1;

        var p4:Point = lineB.p2;

        //float xD1,yD1,xD2,yD2,xD3,yD3;

        var xD1, xD2, yD1, yD2, xD3, yD3:Number;

        var dot, deg, len1, len2:Number;

        //float dot,deg,len1,len2;

        var segmentLen1, segmentLen2:Number;

        //float ;

        var ua, ub, div:Number;



        // calculate differences

        xD1 = p2.x - p1.x;

        xD2 = p4.x - p3.x;

        yD1 = p2.y - p1.y;

        yD2 = p4.y - p3.y;

        xD3 = p1.x - p3.x;

        yD3 = p1.y - p3.y;



        // calculate the lengths of the two lines

        len1 = Math.sqrt(xD1 * xD1 + yD1 * yD1);

        len2 = Math.sqrt(xD2 * xD2 + yD2 * yD2);



        // calculate angle between the two lines.

        dot = (xD1 * xD2 + yD1 * yD2); // dot product

        deg = dot / (len1 * len2);



        // if abs(angle)==1 then the lines are parallell,

        // so no intersection is possible

        if (Math.abs(deg) == 1) return null;



        // find intersection Pt between two lines

        var pt:Point = new Point(0, 0);

        div = yD2 * xD1 - xD2 * yD1;

        ua = (xD2 * yD3 - yD2 * xD3) / div;

        ub = (xD1 * yD3 - yD1 * xD3) / div;

        pt.x = p1.x + ua * xD1;

        pt.y = p1.y + ua * yD1;



        // calculate the combined length of the two segments

        // between Pt-p1 and Pt-p2

        xD1 = pt.x - p1.x;

        xD2 = pt.x - p2.x;

        yD1 = pt.y - p1.y;

        yD2 = pt.y - p2.y;

        segmentLen1 = Math.sqrt(xD1 * xD1 + yD1 * yD1) + Math.sqrt(xD2 * xD2 + yD2 * yD2);



        // calculate the combined length of the two segments

        // between Pt-p3 and Pt-p4

        xD1 = pt.x - p3.x;

        xD2 = pt.x - p4.x;

        yD1 = pt.y - p3.y;

        yD2 = pt.y - p4.y;

        segmentLen2 = Math.sqrt(xD1 * xD1 + yD1 * yD1) + Math.sqrt(xD2 * xD2 + yD2 * yD2);



        // if the lengths of both sets of segments are the same as

        // the lenghts of the two lines the point is actually

        // on the line segment.



        // if the point isn’t on the line, return null

        if (Math.abs(len1 - segmentLen1) > 0.01 || Math.abs(len2 - segmentLen2) > 0.01)

            return null;

        //if the point is the line segment point,return null

        if (pt.equals(p1) || pt.equals(p2) || pt.equals(p3) || pt.equals(p4))

            return null;

        // return the valid intersection

        if (isNaN(pt.x)) {

            return null;

        }

        return pt;

    }



    /**

     * Get two lines intersecion coordinates

     * @param lineA:LineModel

     * @param lineB:LineModel

     * @return Point

     * **/



    /**

     * Draw a arc,



     * center      ,         。

     *  radius   

     *  statrtAngle        ,   getLineR    

     *

     * **/

    public static function drawArc(centerX:Number, centerY:Number, radius:Number, startAngle:Number, g:Graphics, arcAngle:Number = -180 / 360, steps:Number = 20):void {

        //

        //

        startAngle -= .25;

        //

        var twoPI:Number = 2 * Math.PI;

        var angleStep:Number = arcAngle / steps;

        var xx:Number = centerX + Math.cos(startAngle * twoPI) * radius;

        var yy:Number = centerY + Math.sin(startAngle * twoPI) * radius;

        g.moveTo(xx, yy);

        for (var i:int = 1; i <= steps; i++) {

            var angle:Number = startAngle + i * angleStep;

            xx = centerX + Math.cos(angle * twoPI) * radius;

            yy = centerY + Math.sin(angle * twoPI) * radius;

            g.lineTo(xx, yy);

        }

    }



    /**

     * @param pointFrom       

     * @param pointTo        

     * @return        

     * **/

    public static function getBetweenPoint(pointFrom:Point, pointTo:Point, d:Number):Point {

        var x1:Number = pointFrom.x;

        var y1:Number = pointFrom.y;

        var x2:Number = pointTo.x;

        var y2:Number = pointTo.y;



        var myPoint:Point = new Point();



        var x:Number = (x2 - x1 + (Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))) / d * x1) / ((Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))) / d);

        var y:Number = (y2 - y1 + (Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))) / d * y1) / ((Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))) / d);



        if (isNaN(x)) {

            x = x1;

        }

        if (isNaN(y)) {

            y = y1;

        }



        myPoint.x = x;

        myPoint.y = y;



        return myPoint;

    }



    /**

     *    center      

     *   if(centter) null,       ,

     *     ,  lineA    ,lineB     

     * */

    public static function drawOverLine(lineA:LineModel, lineB:LineModel, g:Graphics):void {

       //

        var center:Point = findIntersection(lineA, lineB);

        if (center == null) {



        } else {



            if (lineA.p1) {

                var p1:Point = lineA.p1;

            }



            var p2:Point = getBetweenPoint(lineA.p1, lineA.p2, Point.distance(lineA.p1, center) - 3);

            var p3:Point = getBetweenPoint(lineA.p1, lineA.p2, Point.distance(lineA.p1, center) + 3);

            var p4:Point = lineA.p2;

            g.moveTo(p1.x, p1.y);

            g.lineTo(p2.x, p2.y);

            drawArc(center.x, center.y, 10, getLineR(lineA) / 360, g);

            g.moveTo(p3.x, p3.y);

            g.lineTo(p4.x, p4.y);

        }

    }



    //  LineA X    。return    

    public static function getLineR(lineA:LineModel):Number {

        // if ((lineA.p2.y-lineA.p1.y)/(lineA.p2.x-lineA.p1.x)

        //var vertor:V2D=new V2D(lineA.p2.x-lineA.p1.x,lineA.p2.y-lineA.p1.y);

    

       //return  vertor.getTangle();

       //       

       ///

    if(lineA.p2.x-lineA.p1.x==0)

    {

        return 180;

    }

        if (Math.atan2(lineA.p2.y - lineA.p1.y, lineA.p2.x - lineA.p1.x) * 180 / Math.PI == 0) {

            return 90;

        }

        if (Math.atan2(lineA.p2.y - lineA.p1.y, lineA.p2.x - lineA.p1.x) * 180 / Math.PI == 90) {

            return 180;

        }



        if (Math.atan2(lineA.p2.y - lineA.p1.y, lineA.p2.x - lineA.p1.x) * 180 / Math.PI > 0) {

            return 180 - Math.atan2(lineA.p2.y - lineA.p1.y, lineA.p2.x - lineA.p1.x) * 180 / Math.PI;

        } else {

            return -Math.atan2(lineA.p2.y - lineA.p1.y, lineA.p2.x - lineA.p1.x) * 180 / Math.PI;

        }

    }

}

}