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; } } } }