www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Drawing a line code

reply Joel <joelcnz gmail.com> writes:
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).

```d
	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
```
Nov 06 2022
parent reply claptrap <clap trap.com> writes:
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
Nov 06 2022
parent reply Joel <joelcnz gmail.com> writes:
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.
Nov 06 2022
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
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.
Nov 06 2022
parent reply Joel <joelcnz gmail.com> writes:
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: ```d 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; } } } ```
Nov 07 2022
parent rikki cattermole <rikki cattermole.co.nz> writes:
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.
Nov 07 2022
prev sibling parent reply z <z z.com> writes:
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`).
Nov 06 2022
parent z <z z.com> writes:
On Sunday, 6 November 2022 at 20:07:47 UTC, z wrote:
 whenever the counter is above `1`
I meant above or equal(`>=`), woops
Nov 06 2022