Bitmap/Bresenham's line algorithm: Difference between revisions
Content added Content deleted
m (correct potential edge case failure) |
m (→version 1: changed indentation for subroutine, split do/end groups, added/changed whitespace and comments, used template for the output section.) |
||
Line 3,320: | Line 3,320: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
===version 1=== |
=== version 1 === |
||
This REXX version has automatic scaling (for displaying the plot), includes a border, accepts lines segments from the |
This REXX version has automatic scaling (for displaying the plot), includes a border, accepts lines segments from the |
||
<br>command line, displays a (background) plot field, and it also handles multiple line segments. |
<br>command line, displays a (background) plot field, and it also handles multiple line segments. |
||
Line 3,326: | Line 3,326: | ||
parse arg data /*obtain optional arguments from the CL*/ |
parse arg data /*obtain optional arguments from the CL*/ |
||
if data='' then data= "(1,8) (8,16) (16,8) (8,1) (1,8)" /* ◄──── a rhombus.*/ |
if data='' then data= "(1,8) (8,16) (16,8) (8,1) (1,8)" /* ◄──── a rhombus.*/ |
||
data=translate(data, , '()[]{}/,:;') |
data= translate(data, , '()[]{}/,:;') /*elide chaff from the data points. */ |
||
@.='·' |
@.= '·' /*fill the array with middle─dots chars*/ |
||
do points=1 while data\='' |
do points=1 while data\='' /*put the data points into an array (!)*/ |
||
parse var data x y data; |
parse var data x y data; !.points=x y /*extract the line segments. */ |
||
if points==1 then do; minX=x; maxX=x; minY=y; maxY=y |
if points==1 then do; minX= x; maxX= x; minY= y; maxY= y /*1st case.*/ |
||
end |
|||
minX=min(minX,x); maxX=max(maxX,x); minY=min(minY,y); maxY=max(maxY,y) |
minX= min(minX,x); maxX= max(maxX,x); minY= min(minY,y); maxY= max(maxY,y) |
||
⚫ | |||
end /*points*/ /* [↑] data points pairs in array !. */ |
|||
border= 2 /*border: is extra space around plot. */ |
|||
minX= minX - border*2; maxX= maxX + border*2 /*min and max X for the plot display.*/ |
|||
minY= minY - border ; maxY= maxY + border /* " " " Y " " " " */ |
|||
do y=minY to maxY; @.0.y='│'; end /*draw a pipe from lowest ───► highest*/ |
|||
do x=minX to maxX; @.x.0= '─'; end /*draw a dash from left ───► right.*/ |
|||
do |
do y=minY to maxY; @.0.y= '│'; end /*draw a pipe from lowest ───► highest*/ |
||
@.0.0= '┼' /*define the plot's origin axis point. */ |
|||
do seg=2 to points-1; _= seg - 1 /*obtain the X and Y line coördinates*/ |
|||
call drawLine !._, !.seg /*draw (plot) a line segment. */ |
|||
⚫ | |||
/* [↓] display the plot to terminal. */ |
/* [↓] display the plot to terminal. */ |
||
do y=maxY to minY by -1; _= |
do y=maxY to minY by -1; _= /*display the plot one line at a time. */ |
||
do x=minX to maxX; |
do x=minX to maxX; _= _ || @.x.y /*construct/build a line of the plot. */ |
||
end /*x*/ |
end /*x*/ /* (a line is a "row" of points.) */ |
||
say _ |
say _ /*display a line of the plot──►terminal*/ |
||
end /*y*/ |
end /*y*/ /* [↑] all done plotting the points. */ |
||
exit /*stick a fork in it, we're all done. */ |
exit /*stick a fork in it, we're all done. */ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
drawLine: procedure expose @.; parse arg x y,xf yf; plotChar= 'Θ' |
|||
dx=abs(xf-x); if x<xf then sx= +1 |
dx= abs(xf-x); if x<xf then sx= +1 /*obtain X range, determine the slope*/ |
||
else sx= -1 /* negative slope. */ |
|||
dy=abs(yf-y); if y<yf then sy= +1 |
dy= abs(yf-y); if y<yf then sy= +1 /*obtain Y range, determine the slope*/ |
||
else sy= -1 /* negative slope. */ |
|||
err= dx - dy /*calculate error between adjustments. */ |
|||
do forever; @.x.y=plotChar /*plot the points until it's complete. */ |
|||
do forever; @.x.y= plotChar /*plot the points until it's complete. */ |
|||
if x=xf & y=yf then return /*are the plot points at the finish? */ |
|||
err2= err + err /*calculate double the error number. */ |
|||
if err2 |
if err2 > -dy then do; err= err - dy; x= x + sx; end |
||
if err2 < dx then do; err= err + dx; y= y + sy; end |
|||
end /*forever*/</lang> |
end /*forever*/</lang> |
||
{{out|output|text= when using the default input:}} |
|||
<pre> |
<pre> |
||
···│···················· |
···│···················· |