Thread overview
Drawing a line code
Nov 06, 2022
Joel
Nov 06, 2022
claptrap
Nov 06, 2022
Joel
Nov 06, 2022
rikki cattermole
Nov 07, 2022
Joel
Nov 07, 2022
rikki cattermole
Nov 06, 2022
z
Nov 06, 2022
z
November 06, 2022

I found some code on the net but haven't been able to get it working properly. I trying to draw with mouse (any direction).

	void drawLine(Dot s, Dot e) {
		auto d=s;

/+
		// import std.algorithm : swap;

		if (s.pos.X>e.pos.X) {
			int ox=s.pos.Xi;
			s.pos=Point(e.pos.X,s.pos.Y);
			e.pos=Point(ox,e.pos.Y);
			// swap(s.pos.X, e.pos.X);
		}

		if (s.pos.Y>e.pos.Y) {
			int oy=s.pos.Yi;
			s.pos=Point(s.pos.X,e.pos.Y);
			e.pos=Point(e.pos.X,oy);
			// swap(s.pos.Y, e.pos.Y);
		}
+/
		int x0=s.pos.Xi, x1=e.pos.Xi, y0=s.pos.Yi, y1=e.pos.Yi;
		int dy, dx, incrE, incrNE, dt,x,y;

/+
		import std.algorithm : swap;
		if (x0>x1)
			swap(x0,x1);
		if (y0>y1)
			swap(y0,y1);
+/
		dx = x1 - x0;
		dy = y1 - y0;
		dt = 2 * (dy - dx);
		incrE = 2*dy;
		incrNE = 2*(dy - dx);
		x = x0;
		y = y0;

		d.setPos(s.pos);
		drawDot(d);

		while(x < x1)
		{
			if (dt <= 0)
			{
				dt += incrE;
				x++;
			}
			else
			{
				dt += incrNE;
				x++;
				y++;
			}
			d.setPos(Point(x,y));
			drawDot(d);
		}
	} // drawLine
November 06, 2022

On Sunday, 6 November 2022 at 11:22:26 UTC, Joel wrote:

>

I found some code on the net but haven't been able to get it working properly. I trying to draw with mouse (any direction).

this is the classic integer line drawing algorithm...

https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#Algorithm_for_integer_arithmetic

or you could use this...

https://github.com/cerjones/dg2d

November 06, 2022

On Sunday, 6 November 2022 at 11:40:40 UTC, claptrap wrote:

>

On Sunday, 6 November 2022 at 11:22:26 UTC, Joel wrote:

>

I found some code on the net but haven't been able to get it working properly. I trying to draw with mouse (any direction).

this is the classic integer line drawing algorithm...

https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#Algorithm_for_integer_arithmetic

or you could use this...

https://github.com/cerjones/dg2d

The algorithm is too hard for me to work out and dg2d doesn't help either. I want my code fixed up so that works from any two points.

November 07, 2022
On 07/11/2022 5:48 AM, Joel wrote:
> The algorithm is too hard for me to work out and dg2d doesn't help either. I want my code fixed up so that works from any two points.

Its not as complex as that page initially looks.

```
plotLine(x0, y0, x1, y1)
    dx = abs(x1 - x0)
    sx = x0 < x1 ? 1 : -1
    dy = -abs(y1 - y0)
    sy = y0 < y1 ? 1 : -1
    error = dx + dy

    while true
        plot(x0, y0)
        if x0 == x1 && y0 == y1 break
        e2 = 2 * error
        if e2 >= dy
            if x0 == x1 break
            error = error + dy
            x0 = x0 + sx
        end if
        if e2 <= dx
            if y0 == y1 break
            error = error + dx
            y0 = y0 + sy
        end if
    end while
```

That is the pseudo code you want.

Its just a matter of typing the variables to something like int.

I can recommend:

https://www.amazon.com/Computer-Graphics-Principles-Practice-3rd/dp/0321399528

and

https://www.amazon.com/Computer-Graphics-C-Version-2nd/dp/0135309247

(The updated version should be fine too)

If you wish to understand it.
November 06, 2022

On Sunday, 6 November 2022 at 16:48:24 UTC, Joel wrote:

>

I want my code fixed up so that works from any two points.

You can add a condition to prevent writing out of the image/framebuffer/whatever memory so it won't do any out of bounds write.

Another valid algorithm could be testing all pixels for distance from the line.(i believe that's what 2D vector rendering software does?)

incrE and incrNE's use can be replaced with an approach where you increment a counter by dx/dy(assuming dy > dx here) every iteration(after you draw the dot i believe) and whenever the counter is above 1 you add sx or sy to the x or y value then substract the counter by 1.(as the wording implies, you will probably need to branch depending on if dx > dy or dy > dx).

November 06, 2022

On Sunday, 6 November 2022 at 20:07:47 UTC, z wrote:

>

whenever the counter is above 1

I meant above or equal(>=), woops

November 07, 2022

On Sunday, 6 November 2022 at 17:15:03 UTC, rikki cattermole wrote:

>

On 07/11/2022 5:48 AM, Joel wrote:

>

The algorithm is too hard for me to work out and dg2d doesn't help either. I want my code fixed up so that works from any two points.

Its not as complex as that page initially looks.

plotLine(x0, y0, x1, y1)
    dx = abs(x1 - x0)
    sx = x0 < x1 ? 1 : -1
    dy = -abs(y1 - y0)
    sy = y0 < y1 ? 1 : -1
    error = dx + dy

    while true
        plot(x0, y0)
        if x0 == x1 && y0 == y1 break
        e2 = 2 * error
        if e2 >= dy
            if x0 == x1 break
            error = error + dy
            x0 = x0 + sx
        end if
        if e2 <= dx
            if y0 == y1 break
            error = error + dx
            y0 = y0 + sy
        end if
    end while

That is the pseudo code you want.

Its just a matter of typing the variables to something like int.

I can recommend:

https://www.amazon.com/Computer-Graphics-Principles-Practice-3rd/dp/0321399528

and

https://www.amazon.com/Computer-Graphics-C-Version-2nd/dp/0135309247

(The updated version should be fine too)

If you wish to understand it.

Ok, this is working:

	void drawLine(Dot s, Dot e) {
		Dot d=s;
		int x0=s.pos.Xi, y0=s.pos.Yi;
		int x1=e.pos.Xi, y1=e.pos.Yi;

		int dx = abs(x1 - x0);
		int sx = x0 < x1 ? 1 : -1;
		int dy = -abs(y1 - y0);
		int sy = y0 < y1 ? 1 : -1;
		int error = dx + dy;

		while(true) {
			d.setPos(Point(x0,y0));
			drawDot(d);
			if (x0 == x1 && y0 == y1)
				break;
			int e2 = 2 * error;
			if (e2 >= dy) {
				if (x0 == x1) break;
				error = error + dy;
				x0 = x0 + sx;
			}
			if (e2 <= dx) {
				if (y0 == y1) break;
				error = error + dx;
				y0 = y0 + sy;
			}
		}
	}
//[...]
void mouseDraw(ref Dot d) {
	int lmx=g_mx, lmy=g_my, mx,my;
	int mstate = SDL_GetMouseState(&mx,&my);
	if (mstate & SDL_BUTTON_LEFT) {
		if (mx>0 && my>0) {
			g_mx=mx/3;
			g_my=my/3;
			auto s=d, e=d;
			s.setPos(Point(lmx, lmy));
			e.setPos(Point(g_mx, g_my));
			//mixin(tce("lmx lmy g_mx g_my".split));
			g_df.drawLine(s,e);
		}
	} else {
		if (mx>0 && my>0) {
			g_mx=mx/3;
			g_my=my/3;
		}
	}
}
November 07, 2022
On 07/11/2022 10:29 PM, Joel wrote:
> Ok, this is working:

I'm glad to hear it!

Pathing algorithms can be quite fun to mess around with.