ActionScript实现两直线相交弧跨越算法

/**
 * 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;
        }
    }
}
}
原文地址:https://www.cnblogs.com/yangpigao/p/2945242.html