我有一系列由x,y坐标点定义的非直线。我可以在这些点之间直接在屏幕上绘制一条直线,没有任何问题。不幸的是,我必须在相同长度的段中绘制线条。
以下是我需要如何将具有3个点的非直线分解为多个等距点的数组的示例。 (忽略最后一个红点,这是一条线不均匀划分并且也是终点的结果)
请注意“关节”处的红线。考虑我有一条线A-> B-> C,矢量AB和BC形成一些角度。基本上,该线在B点弯曲。
在A点和B点之间划分一条直线是没有问题的。但是当AB没有按段长度均匀划分时,我需要做一些特殊的事情。我需要考虑剩下的长度并将其视为三角形的一侧。恒定段长度是与BC段(上面的红线)连接的三角形的另一侧。我需要知道从B点到这个交叉点的长度。有了这些信息,我可以继续计算BC上的线段。
Here is the triangle I am trying to solve(此后我将参考此图片中显示的变量) 到目前为止,我已经将问题分解为使用余弦定律。 c 2 = a 2 + b 2 - 2ab * Cos( y )
问题是我已经知道c,它是段长度。我需要解决(我可以计算y)。
我已经写了一个多项式方程式,但现在我卡住了: a 2 + b 2 - 2ab * Cos( y ) - c 2 = 0
或Ax 2 + Bx + C(A = 1,B = -2b * Cos( y ),C = b 2 - c 2 ,x = a)
这甚至是正确的方法吗?接下来我该怎么办?我需要在Actionscript中实现它。
编辑:Duh,我必须使用二次公式。所以我现在得到:a = b * Cos( y )+/- SqrRoot(c 2 - b 2 * Sin( y < / em>的) 2 )
现在如何把它放到代码中......
答案 0 :(得分:2)
以下是我解决这个问题的方法。 B和C与你定义它们相同,我将A点称为第一行上最后一个完整段的末尾。 (弯曲前的最后一点)如果绘制一个圆心,其中心位于A,半径=你的线段长度,那么该圆与线BC相交的位置是A的一条线的端点(称为D),它会削减你的角落。为了找到这一点,我找到了一个整洁helper function它不是很长,为简单起见,我只是在这里粘贴它。
/*---------------------------------------------------------------------------
Returns an Object with the following properties:
enter -Intersection Point entering the circle.
exit -Intersection Point exiting the circle.
inside -Boolean indicating if the points of the line are inside the circle.
tangent -Boolean indicating if line intersect at one point of the circle.
intersects -Boolean indicating if there is an intersection of the points and the circle.
If both "enter" and "exit" are null, or "intersects" == false, it indicates there is no intersection.
This is a customization of the intersectCircleLine Javascript function found here:
http://www.kevlindev.com/gui/index.htm
----------------------------------------------------------------------------*/
function lineIntersectCircle(A : Point, B : Point, C : Point, r : Number = 1):Object {
var result : Object = new Object ();
result.inside = false;
result.tangent = false;
result.intersects = false;
result.enter=null;
result.exit=null;
var a : Number = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y);
var b : Number = 2 * ((B.x - A.x) * (A.x - C.x) +(B.y - A.y) * (A.y - C.y));
var cc : Number = C.x * C.x + C.y * C.y + A.x * A.x + A.y * A.y - 2 * (C.x * A.x + C.y * A.y) - r * r;
var deter : Number = b * b - 4 * a * cc;
if (deter <= 0 ) {
result.inside = false;
} else {
var e : Number = Math.sqrt (deter);
var u1 : Number = ( - b + e ) / (2 * a );
var u2 : Number = ( - b - e ) / (2 * a );
if ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) {
if ((u1 < 0 && u2 < 0) || (u1 > 1 && u2 > 1)) {
result.inside = false;
} else {
result.inside = true;
}
} else {
if (0 <= u2 && u2 <= 1) {
result.enter=Point.interpolate (A, B, 1 - u2);
}
if (0 <= u1 && u1 <= 1) {
result.exit=Point.interpolate (A, B, 1 - u1);
}
result.intersects = true;
if (result.exit != null && result.enter != null && result.exit.equals (result.enter)) {
result.tangent = true;
}
}
}
return result;
}
这是一个返回具有多个属性的对象的函数,因此要在代码中实现它非常简单。你需要传递三个点和一个半径。前两个点只是上面定义的B和C,以及我在开头解释的A点。半径也是您的段长度。
//create an object
var myObject:Object = lineIntersectCircle(pointB, pointC, pointA, segmentLength);
就是这样! D点(见上文)的坐标为:(myObject.exit.x, myObject.exit.y)