Draw a line

May 6, 2022 at 4:58pm
Hello friend. I hope that all is fine for you. I wish you the best week-end.
I am writing a function in order to draw a line according to two points on a grid. Imagine a board 160x100 pixels. I made a code which works as expected, but it lacks precision because of a simple incrementation so as to "cut" the line. Do you have any idea how I could improve this function?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void xGameEngine::DrawLine(const gck::vi2d& pos1, const gck::vi2d& pos2, Pixel p)
{
    int xx = fabs(pos1.x - pos2.x);
    int yy = fabs(pos1.y - pos2.y);
    float zz = xx / yy; // so I have to cut my line each zz, but it's not enough
    int j = 0; int i = 0;

    for (int o = 0; o <= xx; o++)
    {
        if (pos1.y > pos2.y)
	    Draw(pos1.x + o, pos1.y - i, p);
	else
	    Draw(pos1.x + o, pos1.y + i, p);

	j++;

	if (j >= zz)
	{
	    i++;
	    j = 0;
	}
    }

    Draw(pos1, Pixel(0, 255, 0));
    Draw(pos2, Pixel(0, 255, 0));
}
Last edited on May 6, 2022 at 4:59pm
May 6, 2022 at 5:41pm
As long as you don't implement a form of "anti-aliasing" (AA) it will always look pixelated.

No AA:
https://i.imgur.com/iK5O6CN.png

With AA:
https://i.imgur.com/TQ0v7di.png

(Images are zoomed, with "nearest neighbor" scaling, in for the sake of clarity)
Last edited on May 6, 2022 at 5:41pm
May 6, 2022 at 6:23pm
maybe set up your area to use full screen or at least more than you have for resolution.
I have a rather old monitor, and bad eyes so that matters less, and even so its 1920 x 1080 resolution across about 18 x 12 inches. That works out to about 10k pixels per square inch, and a line on the diagonal through that is using around 100 pixels.
in contrast, the line in the linked image is using not even 200 'pixels' or squares across 4 or 5 inches on my screen.
AA will help. More resolution will help. Both together will make it extremely good.
Note that if you use more pixels / inch, you will need to make it wider by some amount or it will be near invisible. Widening it makes AA easier too, so its a win-win.
Last edited on May 6, 2022 at 6:24pm
May 6, 2022 at 10:10pm
Excuse me. My request was not clear. I know that it will be always pixelated. Furthermore, you cannot test my code... for this reason, you cannot see that it is just a question of precision. Using my code, I can see that breaking the line according to the same integer, I cannot reach the second point (so I am not too far).
May 6, 2022 at 11:04pm
oh, that.
cast the division, its integer division then assign.
float zz = (float)(xx)/yy;
May 7, 2022 at 9:06am
int / int always produces an int. So 6 / 4 will give 1, 3 / 4 will give 0. If you want a floating point result, then at least one of the values needs to be either double or float depending upon the required type. So 6.0 / 4 will give 1.5 and 3 / 4.0 will give 0.75

If both are of type int and a non-int result is needed, then one can be cast to double/float or 0.0 added to one:

1
2
3
4
int i {6};

static_cast<double>(i) / 4
(i + 0.0) / 4

Last edited on May 7, 2022 at 9:07am
May 8, 2022 at 12:08pm
Hello everyone. Sorry for the delay. I had read your explanations conscientiously and I finally found a way to draw lines with really good precision. Thank you for your help. I really appreciated it. Have a nice day ++

https://ibb.co/jZYtsMZ
Topic archived. No new replies allowed.