digitalmars.D.learn - Drawing a line code
- Joel (56/56) Nov 06 2022 I found some code on the net but haven't been able to get it
- claptrap (5/7) Nov 06 2022 this is the classic integer line drawing algorithm...
- Joel (4/11) Nov 06 2022 The algorithm is too hard for me to work out and dg2d doesn't
- rikki cattermole (33/35) Nov 06 2022 Its not as complex as that page initially looks.
- Joel (53/89) Nov 07 2022 Ok, this is working:
- rikki cattermole (3/4) Nov 07 2022 I'm glad to hear it!
- z (14/15) Nov 06 2022 You can add a condition to prevent writing out of the
- z (2/3) Nov 06 2022 I meant above or equal(`>=`), woops
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
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
On Sunday, 6 November 2022 at 11:40:40 UTC, claptrap wrote:On Sunday, 6 November 2022 at 11:22:26 UTC, 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.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
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
On Sunday, 6 November 2022 at 17:15:03 UTC, rikki cattermole wrote:On 07/11/2022 5:48 AM, Joel wrote: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; } } } ```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 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.
Nov 07 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`).
Nov 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
Nov 06 2022