bresenham_line3d.m 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. % Generate X Y Z coordinates of a 3D Bresenham's line between
  2. % two given points.
  3. %
  4. % A very useful application of this algorithm can be found in the
  5. % implementation of Fischer's Bresenham interpolation method in my
  6. % another program that can rotate three dimensional image volume
  7. % with an affine matrix:
  8. % http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21080
  9. %
  10. % Usage: [X Y Z] = bresenham_line3d(P1, P2, [precision]);
  11. %
  12. % P1 - vector for Point1, where P1 = [x1 y1 z1]
  13. %
  14. % P2 - vector for Point2, where P2 = [x2 y2 z2]
  15. %
  16. % precision (optional) - Although according to Bresenham's line
  17. % algorithm, point coordinates x1 y1 z1 and x2 y2 z2 should
  18. % be integer numbers, this program extends its limit to all
  19. % real numbers. If any of them are floating numbers, you
  20. % should specify how many digits of decimal that you would
  21. % like to preserve. Be aware that the length of output X Y
  22. % Z coordinates will increase in 10 times for each decimal
  23. % digit that you want to preserve. By default, the precision
  24. % is 0, which means that they will be rounded to the nearest
  25. % integer.
  26. %
  27. % X - a set of x coordinates on Bresenham's line
  28. %
  29. % Y - a set of y coordinates on Bresenham's line
  30. %
  31. % Z - a set of z coordinates on Bresenham's line
  32. %
  33. % Therefore, all points in XYZ set (i.e. P(i) = [X(i) Y(i) Z(i)])
  34. % will constitute the Bresenham's line between P1 and P1.
  35. %
  36. % Example:
  37. % P1 = [12 37 6]; P2 = [46 3 35];
  38. % [X Y Z] = bresenham_line3d(P1, P2);
  39. % figure; plot3(X,Y,Z,'s','markerface','b');
  40. %
  41. % This program is ported to MATLAB from:
  42. %
  43. % B.Pendleton. line3d - 3D Bresenham's (a 3D line drawing algorithm)
  44. % ftp://ftp.isc.org/pub/usenet/comp.sources.unix/volume26/line3d, 1992
  45. %
  46. % Which is also referenced by:
  47. %
  48. % Fischer, J., A. del Rio (2004). A Fast Method for Applying Rigid
  49. % Transformations to Volume Data, WSCG2004 Conference.
  50. % http://wscg.zcu.cz/wscg2004/Papers_2004_Short/M19.pdf
  51. %
  52. % - Jimmy Shen (jimmy@rotman-baycrest.on.ca)
  53. %
  54. function [X,Y,Z] = bresenham_line3d(P1, P2, precision)
  55. if ~exist('precision','var') | isempty(precision) | round(precision) == 0
  56. precision = 0;
  57. P1 = round(P1);
  58. P2 = round(P2);
  59. else
  60. precision = round(precision);
  61. P1 = round(P1*(10^precision));
  62. P2 = round(P2*(10^precision));
  63. end
  64. d = max(abs(P2-P1)+1);
  65. X = zeros(1, d);
  66. Y = zeros(1, d);
  67. Z = zeros(1, d);
  68. x1 = P1(1);
  69. y1 = P1(2);
  70. z1 = P1(3);
  71. x2 = P2(1);
  72. y2 = P2(2);
  73. z2 = P2(3);
  74. dx = x2 - x1;
  75. dy = y2 - y1;
  76. dz = z2 - z1;
  77. ax = abs(dx)*2;
  78. ay = abs(dy)*2;
  79. az = abs(dz)*2;
  80. sx = sign(dx);
  81. sy = sign(dy);
  82. sz = sign(dz);
  83. x = x1;
  84. y = y1;
  85. z = z1;
  86. idx = 1;
  87. if(ax>=max(ay,az)) % x dominant
  88. yd = ay - ax/2;
  89. zd = az - ax/2;
  90. while(1)
  91. X(idx) = x;
  92. Y(idx) = y;
  93. Z(idx) = z;
  94. idx = idx + 1;
  95. if(x == x2) % end
  96. break;
  97. end
  98. if(yd >= 0) % move along y
  99. y = y + sy;
  100. yd = yd - ax;
  101. end
  102. if(zd >= 0) % move along z
  103. z = z + sz;
  104. zd = zd - ax;
  105. end
  106. x = x + sx; % move along x
  107. yd = yd + ay;
  108. zd = zd + az;
  109. end
  110. elseif(ay>=max(ax,az)) % y dominant
  111. xd = ax - ay/2;
  112. zd = az - ay/2;
  113. while(1)
  114. X(idx) = x;
  115. Y(idx) = y;
  116. Z(idx) = z;
  117. idx = idx + 1;
  118. if(y == y2) % end
  119. break;
  120. end
  121. if(xd >= 0) % move along x
  122. x = x + sx;
  123. xd = xd - ay;
  124. end
  125. if(zd >= 0) % move along z
  126. z = z + sz;
  127. zd = zd - ay;
  128. end
  129. y = y + sy; % move along y
  130. xd = xd + ax;
  131. zd = zd + az;
  132. end
  133. elseif(az>=max(ax,ay)) % z dominant
  134. xd = ax - az/2;
  135. yd = ay - az/2;
  136. while(1)
  137. X(idx) = x;
  138. Y(idx) = y;
  139. Z(idx) = z;
  140. idx = idx + 1;
  141. if(z == z2) % end
  142. break;
  143. end
  144. if(xd >= 0) % move along x
  145. x = x + sx;
  146. xd = xd - az;
  147. end
  148. if(yd >= 0) % move along y
  149. y = y + sy;
  150. yd = yd - az;
  151. end
  152. z = z + sz; % move along z
  153. xd = xd + ax;
  154. yd = yd + ay;
  155. end
  156. end
  157. if precision ~= 0
  158. X = X/(10^precision);
  159. Y = Y/(10^precision);
  160. Z = Z/(10^precision);
  161. end
  162. return; % bresenham_line3d