如何对给定的两个点之间的直线上的所有像素位置进行采样?

3
我正在开发一个项目,涉及绘制一条线。然而,最重要的是我需要获取每个X位置上的Y位置。对于每个X,我都需要一个Y。当我缓慢绘制时,绘制线条和获取位置都能正常工作。但是,当我移动光标更快时,即使线条被绘制,每个X的位置也没有保存,这是一个问题。您可以查看下面的图片。

enter image description here

正如您所看到的,绿线是Unity提供的LineRenderer。为了证明我的问题,我在保存在该线上的每个位置处绘制了一个圆圈。因此,尽管线条被绘制出来了,但我无法保存我的位置。有没有解决这个问题的方法?谢谢,祝您拥有愉快的一天!


1
我不确定我理解问题的意思。如果你在一条直线上有两个点,你可以用简单的数学运算来计算这两个点之间的任何一个点。 - UnholySheep
延伸UnholySheep的评论:在数学中,“线”上有无限多的点……不太清楚你到底想要实现什么。 - derHugo
@UnholySheep 我也曾经考虑过这个问题,但我不知道该如何处理。位置被保存在一个列表中,所以基本上我需要找到一种方法来获取每个未在任何两个采样点之间采样的 x 值的 y 值。虽然我认为有更快的方法,但显然我必须添加这些位置...我该如何处理这个问题呢? - ACode
@derHugo 每个x都由一个像素表示,因此我需要沿着X轴的每个像素的正确Y。 - ACode
@ACode,你的目标是什么?例如,你是否打算在固定时间间隔内处理它们,比如“如果我想让所有X轴步骤为0.1f,我该如何计算所有Y值?” - derHugo
@derHugo 没错,我需要获取未完成的列表以及其行位置,就像我上面提到的那样,然后稍后计算每个缺失 x 值在该位置左右邻居之间的正确 Y 值。例如,假设我只有两个点 A(0,8) 和 B(109,20),在这种情况下,我需要循环从 1 到 108,并找到 A 和 B 之间每个缺失 x 的相应 y 值。抱歉,这是我第一次在这里发布。 - ACode
2个回答

2

如果我正确理解了你的问题,现在你想在图像中找到由给定点构建的所有线上的所有像素。

由于我现在正在手机上打字,所以不是很确定,但我认为你可以这样做:

// Expects givenPoints in pixel coordinates for positions to draw lines between
public List<Vector2Int> CalculateLinePixels(List<Vector2Int> givenPoints)
{
    var output = new List<Vector2Int>();
    // Already add the first point once
    output.Add(givenPoints[0]);

    // start with the second point and calculate the line points back 
    // between the current and the point before
    for (var i = 1; i < givenPoints.Count; i++)
    {
        var startPoint = givenPoints[i - 1];
        var endPoint = givenPoints[i];

        // get the difference between them in pixels
        var dif = endPoint - startPoint;
        // Get the pixel step in Y per pixel step on X
        var step = dif.y / (float)dif.x;

        // go through all the pixels on the X axis between both points
        // excluding the first as these should already match the 
        // startPoint (== last endPoint)
        //
        // Note that for now this assumes that the line goes always strict from left to right 
        // -> no forth and back drawing, no vertical drawing
        for (var x = 1; x < dif.x; x++)
        {
            // every step in X add one step in Y starting from the first points Y
            var y = Mathf.RoundToInt(step * x);

            // Add the new line point
            output.Add(startPoint + new Vector2Int(x, y));
        }
    }

    return output;
}

如代码中所述:
请注意,这假定该行始终严格从左到右。 => 不要来回画,不要水平画。

对于这些情况,您可以添加一些额外的检查,例如if(dif.x < 0),然后您需要在另一个方向上进行迭代for (var x = -1; x > dif.x ; x--)。如果是if(dif.x == 0),您可能更想只画一条水平线到下一个点并填充所有上面/下面。

为了获得更好的结果,您可能需要研究线绘制算法并实现一种不同的方式来获取和以不同的方式填充像素。


1
如果我理解正确的话,您的问题是由于坐标稀疏采样引起的,您可以专注于在移动光标时获取值,然后绘制线条,这将是一种更快的方式。

好的,但我认为这样做会使行落后。虽然我可以尝试,但我不喜欢这种方法。无论如何还是谢谢。 - ACode

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