沿着线找到点的问题

时间:2014-01-30 21:53:43

标签: vba graphics geometry

我画了一条线,使用X1,X2,Y1,Y2变量。我希望在这一行找到任意数量的点,并且在那个程度上我写了这个:

Private Function genPointsArray(ByRef xPointArray() As Integer, ByRef yPointArray() As Integer, startX As Integer, finX As Integer, startY As Integer, finY As Integer, numPoints As Integer) As Integer
        ReDim xPointArray(numPoints)
        ReDim yPointArray(numPoints)

        xPointArray(0) = startX
        xPointArray(numPoints - 1) = finX
        yPointArray(0) = startY
        yPointArray(numPoints - 1) = finY

        For i = 1 To numPoints - 2
            xPointArray(i) = xPointArray(i - 1) + (finX - startX) \ numPoints
            yPointArray(i) = yPointArray(i - 1) + (finY - startY) \ numPoints
        Next

        Return 0
    End Function

如您所见,它接受X1,X2,Y1,Y2变量(startX等),两个数组来存储结果点,以及要查找的多个点。它的问题是(令人担忧的是)一个点是一个像素关闭(由于实际结果是十进制)。然后逐渐变得更糟,因为每个后续点都是2,3,4,5等像素关闭,使得效果非常明显。有没有人知道如何通过更好的算法或验证确保每个点都在线上?

由于

3 个答案:

答案 0 :(得分:1)

就几何而言,线条是一维的,即它没有宽度,因此很难知道一个点是否在一条线上而没有定义一个标准。

测试点是否位于线上的常用方法是计算从该点到线的距离,如果这样的距离足够小(小于epsilon值),则该点被认为是在线上。我不知道VB,但这里有一段代表这个想法的片段:

boolean inLine(Point2D a, Point2D b, Point2D p)
{
    double a1 = b.x() - a.x();
    double b1 = b.y() - a.y();
    double a2 = p.x() - a.x();
    double b2 = p.y() - a.y();

    double alpha = Math.atan2(b1, a1);
    double beta = Math.atan2(b2, a2);
    double theta = Math.abs(alpha - beta);
    double dist = Math.abs(a.distanceTo(p) * Math.sin(theta));
    double eps = Math.abs(fx(3) - fx(0));

    return dist < eps;
}

此算法称为Distance from a Point to a Line

epsilon值取决于您的特定问题,需要多少精度,对于大多数应用程序 1e-9 都可以。

代码中的方法distanceTo()只是计算两点之间的Euclidean distance

答案 1 :(得分:1)

生成点漂移的原因是因为您允许整数舍入的误差累积。这就像闭着眼睛走路一样。

不要将每个点都放在前一个点上,而是继续回到原始端点。由于四舍五入,结果中的每个点都将在最坏的位置关闭。

替换

    xPointArray(0) = startX
    xPointArray(numPoints - 1) = finX
    yPointArray(0) = startY
    yPointArray(numPoints - 1) = finY

    For i = 1 To numPoints - 2
        xPointArray(i) = xPointArray(i - 1) + (finX - startX) \ numPoints
        yPointArray(i) = yPointArray(i - 1) + (finY - startY) \ numPoints
    Next

只需

    For i = 0 To numPoints - 1
        xPointArray(i) = startX + (finX - startX) * i / numPoints
        yPointArray(i) = startX + (finX - startX) * i / numPoints
    Next

请原谅任何语法或循环绑定错误;我不写VBA

答案 2 :(得分:1)

一个万无一失的公式是((N - I) * Start + I * Fin) / N。对于I=0,准确地为您提供Start,而对于I=N,则为您提供Fin。中间值将定期对齐。

这在整数和浮点坐标中均有效,但令人头脑溢出。