How to sample all pixel positions for a line between given points?

Viewed 586

I am working on a project which consists of drawing a line, BUT, the most important thing is that I need to get the Y position on every X position. So, for every X I need a Y. Drawing a line and getting the positions works fine while I draw slowly. But when I move the cursor faster, even if the line gets drawn, the positions are not saved for every X, and this is a problem. You can just take a look at the image below.

enter image description here

As you can see, the green line is the one that Unity provides, LineRenderer. Just to prove my problem, I have drawn a circle at every position saved on the Line. So, even though the line gets drawn, I can't save my positions. Is there a way to solve this? Thank you and have a great day!

2 Answers

If I understood your question correct now you want to find all pixels that lie on the lines build by the given points in an image.

Not fully sure since typing on the smartphone right now but I think you could do something like

// 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;
}

As also commented in code:
Note that this assumes that the line goes always strict from left to right. => No forth and back drawing, no horizontal drawing.

For these you could add some additional checks such as if(dif.x < 0) then you would need to iterate in the other direction for (var x = -1; x > dif.x ; x--). And if it is if(dif.x == 0) you might want to rather only draw a horizontal line to the next point filling all above/below.

For better results you might want to look into Line drawing algorithms and implement a different way of how to obtain and fill the pixels differently.

If I understood correctly, your problem is caused by the fact that the coordinates are sampled rarely, you could just focus on getting the values while moving the cursor and then draw the line, it would be a faster way.

Related