如何将非直线分成均匀的线段?

4
我有一条由一系列x,y坐标点定义的非直线。我可以在屏幕上直接绘制连接这些点的直线,没有问题。不幸的是,我必须将该线段分成等长度的片段进行绘制。
以下是如何将具有3个点的非直线分解为多个等距点数组的示例(忽略最后一个红点,它是当线段不能完全分割并且也是终点时的结果)。

Here is an example of how I need to break up a non-straight line with 3 points into an array of several equidistant points

请注意“连接点”处的红线。假设我有一条A->B->C的线段,向量AB和BC形成某个角度。基本上,该线段在B点弯曲。
在点A和B之间分割一条线段没有问题,但当AB不能被段长均匀分割时,我需要做一些特殊处理。我需要将剩余长度视为三角形的一条边。常数段长度是与BC段(上面的红线)相连的三角形的另一条边。我需要知道从点B到此交点的长度。有了这个信息,我就可以继续计算BC上的线段。 这是我要解决的三角形(以下我将按照此图片中出现的变量来引用) 到目前为止,我已经将问题简化为使用余弦定理。c2 = a2 + b2 - 2ab * Cos(y)
问题在于我已经知道C,它是线段长度。我需要解决A的值(我可以计算出Y)。
我已经写了一个多项式方程,但现在我卡住了: a2 + b2 - 2ab * Cos(y) - c2 = 0
或 Ax2 + Bx + C (A = 1, B = -2b * Cos(y), C = b2 - c2, x = a)
这样做是否正确?接下来该怎么办?我需要在Actionscript中实现这个方程。
编辑:傻瓜,我必须使用二次公式。所以现在我得到了: a = b * Cos(y) +/- SqrRoot(c2 - b2 * Sin(y)2)
现在如何将其转化为代码...

如果您将图片的URL添加到帖子中,我可以在其中进行编辑。 - SynerCoder
我已经为你的问题点赞,你现在有13个声望值,所以你可以发布图片了。 - SynerCoder
谢谢!我非常感激。我认为我已经找到了数学解决方案(通过二次公式)。现在我只需要编写代码。同时,我不得不转向另一个问题,但是当我有机会编写它时,我会尝试回来并发布答案。同时,我欢迎任何建议。解决两个方程,然后测试哪个是正的似乎相当密集。但它只应该在关节处必要,因此希望绘图逻辑不会使事情变得太慢。 - jpwrunyan
你想通过控制点绘制折线或曲线吗?对于折线来说,在一般情况下,所有线段的长度相等是不可能的,除非切角。 - alxx
抱歉,我可能有些困惑或者让您感到困惑了。我将绘制直线段而非曲线,所以我不知道控制点在哪里起作用。我认为对于您的问题,我的答案是,在AB和BC两条线段本应连接的地方附近插入一个1个线段长度的线条,使用上面的公式计算。坚持要求线段具有相同的长度是因为它们将有一个固定大小的附加装饰。例如,天气冷锋线段将有一个三角形(类似于新闻上的那种)。 - jpwrunyan
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)


Mathworld在这里提供了这个计算的背景:http://mathworld.wolfram.com/Circle-LineIntersection.html - Adam Smith
很酷,这应该比我用余弦定理想出的解决方案少处理一些。谢谢! - jpwrunyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接