Bitmap/Bresenham's line algorithm: Difference between revisions

Content added Content deleted
(→‎version 2: correct output)
(→‎version 1: simplified the program, eliminated the re-calculating of the min and max point values, removed the STYLE from the PRE html tag.)
Line 1,978: Line 1,978:
=={{header|REXX}}==
=={{header|REXX}}==
===version 1===
===version 1===
This REXX version has automatic scaling (for displaying the plot).
<lang rexx>/*REXX program plots/draws a line using the Bresenham's line algorithm.*/
<lang rexx>/*REXX program plots/draws a line using the Bresenham's line algorithm.*/
@. = 'fa'x /*fill the array with middle─dots*/
@.='·' /*fill the array with middle─dots*/
plotC = 'fe'x /*character used for plotting pts*/
parse arg x1 y1 x2 y2 . /*allow specifying line─end pts. */
parse arg x0 y0 x1 y1 . /*allow specifying line─end pts. */
if x1=='' | x1==',' then x1 = -1 /*if not specified, use default. */
if x0=='' | x0==',' then x0 = -1 /*if not specified, use default. */
if y1=='' | y1==',' then y1 = -3 /* " " " " " */
if y0=='' | y0==',' then y0 = -3 /* " " " " " */
if x2=='' | x2==',' then x2 = 6 /* " " " " " */
if x1=='' | x1==',' then x1 = 6 /* " " " " " */
if y2=='' | y2==',' then y2 = 10 /* " " " " " */
if y1=='' | y1==',' then y1 = 10 /* " " " " " */
minX=min(x0,x1); minY=min(y0,y1) /*find the min and max X value.*/
maxX=max(x0,x1); maxY=max(y0,y1) /* " " " " " Y " */
border=2 /*border=extra space around plot.*/
border=2 /*border=extra space around plot.*/
minX=minX-border*2; maxX=maxX+border*2 /*find the min and max X borders.*/
minX=min(x1,x2)-border*2; maxX=max(x1,x2)+border*2 /*min,max X display*/
minY=minY-border ; maxY=maxY+border /* " " " " " Y " */
minY=min(y1,y2)-border ; maxY=max(y1,y2)+border /* " " Y " */
do x=minX to maxX; @.x.0='─'; end /*draw dash from left──► right.*/
do x=minX to maxX; @.x.0='─'; end /*draw dash from left──► right.*/
do y=minY to maxY; @.0.y='│'; end /*draw pipe from lowest──►highest*/
do y=minY to maxY; @.0.y='│'; end /*draw pipe from lowest──►highest*/
@.0.0='┼' /*"draw" the axis origin. */
@.0.0='┼' /*define the plot's axis point. */
call draw_line x0, y0, x1, y1 /*call subroutine and draw line. */
call draw_line x1, y1, x2, y2 /*call subroutine and draw line. */
/* [↓] draw the plot. */
/* [↓] display the plot to term.*/
do y=maxY to minY by -1; _= /*display plot one line at a time*/
do y=maxY to minY by -1; _= /*display plot one line at a time*/
do x=minX to maxX /*traipse throught the X axis. */
do x=minX to maxX /*traipse throught the X axis. */
_=_ || @.x.y /*construct a "line" of the plot.*/
_=_ || @.x.y /*construct a "line" of the plot.*/
end /*x*/ /*(a line is a "row" of points.) */
end /*x*/ /*(a line is a "row" of points.) */
say _ /*display a line of the plot. */
say _ /*display a "line" of the plot. */
end /*y*/ /* [↑] all done ploting the pts.*/
end /*y*/ /* [↑] all done ploting the pts.*/
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're done.*/
/*────────────────────────────────DRAW_LINE subroutine──────────────────*/
/*────────────────────────────────DRAW_LINE subroutine──────────────────*/
draw_line: procedure expose @. minX maxX minY maxY plotC
draw_line: procedure expose @.; parse arg x,y,xf,yf; plotChar='Θ'
parse arg x,y,xf,yf; dx=abs(xf-x); dy=abs(yf-y)
dx=abs(xf-x); dy=abs(yf-y)
if x<xf then sx=+1
if x<xf then sx=+1
else sx=-1
else sx=-1
Line 2,011: Line 2,009:
else sy=-1
else sy=-1
err=dx-dy
err=dx-dy
do forever
do forever; @.x.y=plotChar /*plot the points until complete.*/
if x=xf & y=yf then leave /*are plot points at the finish? */
call plotXY x,y,plotC
if x=xf & y=yf then leave
if 2*err > -dy then do; err=err-dy; x=x+sx; end
e2=err+err
if 2*err < dx then do; err=err+dx; y=y+sy; end
end /*while ··· */
if e2>-dy then do; err=err-dy; x=x+sx; end
if e2< dx then do; err=err+dx; y=y+sy; end
end /*forever*/
return
/*────────────────────────────────PLOTXY subroutine─────────────────────*/
plotXY: procedure expose @. minX maxX minY maxY; parse arg xx,yy,pp
@.xx.yy=pp; minX=min(minX,xx); maxX=max(maxX,xx)
minY=min(minY,yy); maxY=max(maxY,yy)
return</lang>
return</lang>
'''output''' when using the default input
'''output''' when using the default input:
<pre>
<pre style="overflow:scroll">
·····│··········
·····│··········
·····│··········
·····│··········
·····│·········
·····│·····Θ····
·····│·········
·····│····Θ·····
·····│·········
·····│····Θ·····
·····│·········
·····│···Θ······
·····│·········
·····│···Θ······
·····│·········
·····│··Θ·······
·····│·········
·····│··Θ·······
·····│·········
·····│·Θ········
·····│·········
·····│·Θ········
·····│■·········
·····│Θ·········
─────┼Θ─────────
─────┼■─────────
···············
·····Θ··········
···············
·····Θ··········
····■│··········
····Θ│··········
·····│··········
·····│··········
·····│··········
·····│··········