BRESENHAMLINE_BASE - Base function for BRESENHAMLINE.
Contents
Syntax
[x y pts] = BRESENHAMLINE_BASE(x1, y1, x2, y2);
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.
See also
Ressembles: BRESENHAMLINE, SAMPLEDISK_BASE, SAMPLETRIANGLE_BASE, DRAWLEAKCIRCLE_BASE. Requires: DIFF, SUM, CUMSUM, MESHGRID.
Function implementation
%-------------------------------------------------------------------------- function [x, y, pts] = bresenhamline_base(x1, y1, x2, y2)
transform the inputs in column vector and round the coordinates
x1 = round(x1(:)); x2 = round(x2(:)); y1 = round(y1(:)); y2 = round(y2(:));
main computation starts here
s = size(x1(:),1); dx = abs(x2-x1); dy = abs(y2-y1); steep = dy>dx; % vector column % invert positions t = dx(steep); dx(steep) = dy(steep); dy(steep) = t; % length of the longest line mdx = max(dx)+1; odx = ones(1,mdx);
transform steep
steep = steep(:, odx); % repmat(steep, [1 mdx]); I = dy==0; DX = dx(:, odx); % repmat(dx, [1 mdx]); DY = dy(:, odx); % repmat(dy, [1 mdx]); A = floor(DX/2); B = DX .* DY; Z = cumsum(DY,2) - DY; Z = -Z; Q = A+Z; Q(Q < A-B) = 0; Q = [zeros(s,1) diff(mod(Q,DX),1,2)>=0]; Q = cumsum(Q,2); Q(I,:) = 0; Z = meshgrid(0:mdx-1,1:s); % cumsum(ones(s, mdx),2)-1 Y1 = y1(:, odx); % repmat(y1, [1 mdx]); X1 = x1(:, odx); % repmat(x1, [1 mdx]); Y2 = y2(:, odx); % repmat(y2, [1 mdx]); X2 = x2(:, odx); % repmat(x2, [1 mdx]);
vectorized version of Bresnham algorith (see A.Wetzler's code)
A = X1<=X2; pts = ~A; x = X1 + Z; x(pts) = x(pts) - 2*Z(pts); x(steep & A) = X1(steep & A) + Q(steep & A); x(steep & pts) = X1(steep & pts) - Q(steep & pts); B = (A & x>X2) | (pts & x<X2); A = Y1<=Y2; pts = ~A; y = Y1 + Z; y(pts) = y(pts) - 2*Z(pts); steep = ~steep; y(steep & A) = Y1(steep & A) + Q(steep & A); y(steep & pts) = Y1(steep & pts) - Q(steep & pts); A = (A & y>Y2) | (pts & y<Y2);
trim
A = A | B; % additional output: but can be easily handled also without (using isnan) pts = ~A; % pts = ~isnan(x); x(A) = NaN; y(A) = NaN;
end % end of bresenhamline_base
Original
BRESENHAM - Original implementation by A.Wetzler: single entries only (coordinates of two vertices to be linked by a line).
%-------------------------------------------------------------------------- function [x y] = bresenham(x1,y1,x2,y2) %#ok %Matlab optmized version of Bresenham line algorithm. No loops. %Format: % [x y]=bresenham(x1,y1,x2,y2) % %Input: % (x1,y1): Start position % (x2,y2): End position % %Output: % x y: the line coordinates from (x1,y1) to (x2,y2) % %Usage example: % [x y]=bresenham(1,1, 10,-5); % plot(x,y,'or'); x1=round(x1); x2=round(x2); y1=round(y1); y2=round(y2); dx = abs(x2-x1); dy = abs(y2-y1); steep = dy>dx; % steep=abs(dy)>abs(dx) if steep, t=dx; dx=dy; dy=t; end % the main algorithm goes here. if dy==0 q=zeros(dx+1,1); else q=[0;diff(mod((floor(dx/2):-dy:-dy*dx+floor(dx/2))',dx))>=0]; end % and ends here. if steep if y1<=y2, y = (y1:y2)'; else y = (y1:-1:y2)'; end if x1<=x2, x = x1+cumsum(q); else x = x1-cumsum(q); end else if x1<=x2, x = (x1:x2)'; else x = (x1:-1:x2)'; end if y1<=y2, y = y1+cumsum(q); else y = y1-cumsum(q); end end end