4

我有一条由一系列 x、y 坐标点定义的非直线。我可以毫无问题地在这些点之间直接在屏幕上画一条直线。不幸的是,我必须画出等长的线段。

这是一个示例,说明我需要如何将具有 3 个点的非直线分解为几个等距点的数组。(忽略最后的红点,它是一条线不均分的结果,也是终点)

这是一个示例,说明我需要如何将具有 3 个点的非直线分成几个等距点的数组

请注意“关节”处的红线。考虑到我有一条线 A->B->C,其中向量 AB 和 BC 形成某个角度。基本上,线在 B 点弯曲。

分割点 A 和 B 之间的线直到一点都没有问题。但是当 AB 没有除以段长度时,我需要做一些特别的事情。我需要取剩余的长度并将其视为三角形的一侧。恒定线段长度是与 BC 线段相连的三角形的另一边(上面的红线)。我需要知道从 B 点到这个交叉点的长度。有了这些信息,我可以继续计算 BC 上的线段。

这是我要解决的三角形(此后我将引用这张图片上出现的变量)到目前为止,我已将问题分解为使用余弦定律。c 2 = a 2 + b 2 - 2ab * Cos( y )

问题是我已经知道c,它是段长度。我需要求解 a(我可以计算 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 ) 2 )

现在如何将其放入代码中...

4

1 回答 1

3

这是我解决这个问题的方法。B 和 C 与您定义的相同,我将 A 点称为第一行最后一个完整段的末尾。(弯曲前的最后一点)如果您绘制一个圆心在 A 并且半径 = 您的线段长度的圆,那么该圆与线 BC 相交的位置是 A 线的端点(称为 D),该线切割您的角. 为了找到这一点,我找到了一个简洁的辅助函数它不是很长,为了简单起见,我只是将它粘贴在这里。

/*---------------------------------------------------------------------------
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)

于 2011-04-11T01:37:09.567 回答