BRESENHAMLINE - 2D Bresenham line algorithm.
Contents
Description
Apply the 2D Bresenham line algorithm [Bres65] to join 2 points of a grid. Given the list of lattice points (ie. points with integer coordinates) linking two (or more) input vertices given by their (X,Y)-coordinates.
It is fully implemented in Matlab, optimized for vector manipulation (no loops) and handles vectors of coordinates in input (contrary to other original implementations).
Syntax
[x y pts] = BRESENHAMLINE(x1, y1, x2, y2); [x y pts] = BRESENHAMLINE(x1, y1, x2, y2, disp);
Inputs
(x1, y1) : start position(s) in the standard (X,Y)-orientated coordinate system (X: horizontal OE and Y: vertical SN); can be vectors (row or column) of vertices.
(x2, y2) : end position(s); must be of the same size as (x1,y1).
disp : (optional) flag for drawing the estimated (discrete) lines joining the (x1,y1) and (x2,y2) points; default: disp=false.
Outputs
[x y] : the line coordinates from (x1,y1) to (x2,y2); if the input vertices are vectors, the list of coordinates for all lines is output; each row of x (resp. y) provides the X(resp. Y)-coordinates of the points on the line joining the vertices whose coordinates are given in the corresponding rows of (x1,y1,x2,y2); the number of columns of x (ibid y) is the maximum number of points found in a line; when a line has less points, it is complemented with NaN values.
pts : logical matrix of same size as x (and y) set to true for the points really belonging to the line, false for the completing NaN values: it is nothing else than ~isnan(x).
Acknowledgment
Entirely derived from the implementation of A.Wetzler; see original source code BRESENHAM included in this file, otherwise available at: http://www.mathworks.com/matlabcentral/fileexchange/28190. Still, this original code did not support vectors of coordinates in input, contrary to the implementation BRESENHAMLINE_BASE proposed herein. See other implementations and source codes: http://www.mathworks.com/matlabcentral/fileexchange/12939, http://www.mathworks.com/matlabcentral/fileexchange/13221.
Example
x1 = [5 16 7 18 9]; y1 = [1 4 2 19 21]'; % whatever, row or column x2 = [10 23 4 26 23]; y2 = [20 14 13 19 15]; % need to be of same size bresenhamline(x1, y1, x2, y2, true);
References
[Bres65] J.E. Bresenham: "Algorithm for computer control of a digital plotter", IBM Systems Journal, 4(1):25-30, 1965. http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=5388473&tag=1
[wiki] http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
See also
Ressembles: SAMPLEDISK, SAMPLETRIANGLE. Requires: BRESENHAMLINE_BASE.
Function implementation
function [x, y, pts] = bresenhamline(x1, y1, x2, y2, disp)
settting/checking variables
% check errors in muber of input/output variables error(nargchk(4, 5, nargin, 'struct')); error(nargoutchk(0, 3, nargout, 'struct')); if nargin<5, disp = false; end if ~(isvector(x1) && isvector(y1) && isvector(x2) && isvector(y2)) error('bresenhamline:inputerror','vectorial inputs required'); end % transform the inputs in column vector and round the coordinates x1 = round(x1(:)); x2 = round(x2(:)); y1 = round(y1(:)); y2 = round(y2(:)); if ~(isequal(size(x1),size(y1)) && isequal(size(y1),size(x2)) && ... isequal(size(x2),size(y2))) error('bresenhamline:inputerror','inputs with same dimension required'); elseif ~islogical(disp) error('bresenhamline:inputerror','logical flag required'); end
main computation starts here
[x, y, pts] = bresenhamline_base(x1, y1, x2, y2);
display
if disp nline = size(x,1); arbitrarymaxnline = 100; % we are cheating here, but plot would be too slow... if nline>arbitrarymaxnline warning('bresenhamline:plotwarning', ... [num2str(arbitrarymaxnline) 'to be displayed only']); nline = arbitrarymaxnline; end nline = min([nline; size(x,1)]); x1 = x(1:nline,:)'; y1 = y(1:nline,:)'; figure, hold on, plot(x1, y1, '-b'); [i,j] = find(diff([pts(1:nline,:) zeros(nline,1)],[],2)); [~,l]=sort(i); j = j(l); plot([x1(1,1:nline); x1(j'+(0:nline-1)*size(x1,1))], ... [y1(1,1:nline); y1(j'+(0:nline-1)*size(x1,1))],'or'); axis([min(x1(:))-1 max(x1(:))+1 min(y1(:))-1 max(y1(:))+1]); hold off end
end % end of bresenhamline