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