123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- % Generate X Y Z coordinates of a 3D Bresenham's line between
- % two given points.
- %
- % A very useful application of this algorithm can be found in the
- % implementation of Fischer's Bresenham interpolation method in my
- % another program that can rotate three dimensional image volume
- % with an affine matrix:
- % http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21080
- %
- % Usage: [X Y Z] = bresenham_line3d(P1, P2, [precision]);
- %
- % P1 - vector for Point1, where P1 = [x1 y1 z1]
- %
- % P2 - vector for Point2, where P2 = [x2 y2 z2]
- %
- % precision (optional) - Although according to Bresenham's line
- % algorithm, point coordinates x1 y1 z1 and x2 y2 z2 should
- % be integer numbers, this program extends its limit to all
- % real numbers. If any of them are floating numbers, you
- % should specify how many digits of decimal that you would
- % like to preserve. Be aware that the length of output X Y
- % Z coordinates will increase in 10 times for each decimal
- % digit that you want to preserve. By default, the precision
- % is 0, which means that they will be rounded to the nearest
- % integer.
- %
- % X - a set of x coordinates on Bresenham's line
- %
- % Y - a set of y coordinates on Bresenham's line
- %
- % Z - a set of z coordinates on Bresenham's line
- %
- % Therefore, all points in XYZ set (i.e. P(i) = [X(i) Y(i) Z(i)])
- % will constitute the Bresenham's line between P1 and P1.
- %
- % Example:
- % P1 = [12 37 6]; P2 = [46 3 35];
- % [X Y Z] = bresenham_line3d(P1, P2);
- % figure; plot3(X,Y,Z,'s','markerface','b');
- %
- % This program is ported to MATLAB from:
- %
- % B.Pendleton. line3d - 3D Bresenham's (a 3D line drawing algorithm)
- % ftp://ftp.isc.org/pub/usenet/comp.sources.unix/volume26/line3d, 1992
- %
- % Which is also referenced by:
- %
- % Fischer, J., A. del Rio (2004). A Fast Method for Applying Rigid
- % Transformations to Volume Data, WSCG2004 Conference.
- % http://wscg.zcu.cz/wscg2004/Papers_2004_Short/M19.pdf
- %
- % - Jimmy Shen (jimmy@rotman-baycrest.on.ca)
- %
- function [X,Y,Z] = bresenham_line3d(P1, P2, precision)
- if ~exist('precision','var') | isempty(precision) | round(precision) == 0
- precision = 0;
- P1 = round(P1);
- P2 = round(P2);
- else
- precision = round(precision);
- P1 = round(P1*(10^precision));
- P2 = round(P2*(10^precision));
- end
- d = max(abs(P2-P1)+1);
- X = zeros(1, d);
- Y = zeros(1, d);
- Z = zeros(1, d);
- x1 = P1(1);
- y1 = P1(2);
- z1 = P1(3);
- x2 = P2(1);
- y2 = P2(2);
- z2 = P2(3);
- dx = x2 - x1;
- dy = y2 - y1;
- dz = z2 - z1;
- ax = abs(dx)*2;
- ay = abs(dy)*2;
- az = abs(dz)*2;
- sx = sign(dx);
- sy = sign(dy);
- sz = sign(dz);
- x = x1;
- y = y1;
- z = z1;
- idx = 1;
- if(ax>=max(ay,az)) % x dominant
- yd = ay - ax/2;
- zd = az - ax/2;
- while(1)
- X(idx) = x;
- Y(idx) = y;
- Z(idx) = z;
- idx = idx + 1;
- if(x == x2) % end
- break;
- end
- if(yd >= 0) % move along y
- y = y + sy;
- yd = yd - ax;
- end
- if(zd >= 0) % move along z
- z = z + sz;
- zd = zd - ax;
- end
- x = x + sx; % move along x
- yd = yd + ay;
- zd = zd + az;
- end
- elseif(ay>=max(ax,az)) % y dominant
- xd = ax - ay/2;
- zd = az - ay/2;
- while(1)
- X(idx) = x;
- Y(idx) = y;
- Z(idx) = z;
- idx = idx + 1;
- if(y == y2) % end
- break;
- end
- if(xd >= 0) % move along x
- x = x + sx;
- xd = xd - ay;
- end
- if(zd >= 0) % move along z
- z = z + sz;
- zd = zd - ay;
- end
- y = y + sy; % move along y
- xd = xd + ax;
- zd = zd + az;
- end
- elseif(az>=max(ax,ay)) % z dominant
- xd = ax - az/2;
- yd = ay - az/2;
- while(1)
- X(idx) = x;
- Y(idx) = y;
- Z(idx) = z;
- idx = idx + 1;
- if(z == z2) % end
- break;
- end
- if(xd >= 0) % move along x
- x = x + sx;
- xd = xd - az;
- end
- if(yd >= 0) % move along y
- y = y + sy;
- yd = yd - az;
- end
- z = z + sz; % move along z
- xd = xd + ax;
- yd = yd + ay;
- end
- end
- if precision ~= 0
- X = X/(10^precision);
- Y = Y/(10^precision);
- Z = Z/(10^precision);
- end
- return; % bresenham_line3d
|