home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / line3d < prev    next >
Encoding:
Text File  |  1992-05-11  |  5.6 KB  |  206 lines

  1. Newsgroups: comp.sources.unix
  2. From: bobp@hal.com (Bob Pendelton)
  3. Subject: v26i048: line3d - 3D Bresenham's (a 3D line drawing algorithm)
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: bobp@hal.com (Bob Pendelton)
  8. Posting-Number: Volume 26, Issue 48
  9. Archive-Name: line3d
  10.  
  11. [ For the mathematically challenged (meaning me, until I looked it up),
  12.   Bresenham's algorithm is a neato and efficient way to enumerate all of
  13.   (actually "most of") the points between two endpoints.  Most such
  14.   algorythms take as an input parameter the resolution wanted -- since
  15.   it would be a waste to calculate at a higher resolution than you use
  16.   (you'd just have a lot of points that would "go in the same place").
  17.   This algorythm uses only integer arithmetic and assumes that you want
  18.   all the contiguous points which can be represented with integers.  
  19.  
  20.   I expect that there's something like this in the X11 Phigs code.  But
  21.   since this submission is short and clean and relatively easy to under-
  22.   stand, I think it's useful and am therefore posting it.  Note that it
  23.   has no man page or README or Makefile, and in the average case I would
  24.   reject a submission absent of any of those three.  If I get a flood of
  25.   small C functions in response to this submission, I'll have to make up
  26.   some rules about what they have to include.  Heck, perhaps I'll start
  27.   a library and post updates to it.  (That's not a promise!) 
  28.  
  29.   --vix ]
  30.  
  31. This is something I've hoped to see on the net for years. And I can't
  32. guess how many times I've seen requests for something like this. It
  33. turned out to be trivial to build, once I spent a couple of weeks of
  34. my spare time researching it... (I don't have a lot of spare time. :-)
  35. So here it is, a simple, fast, 3D version of Bresenham's line drawing
  36. algorithm.
  37.  
  38. -------------------------------------------------------------------------
  39. #! /bin/sh
  40. # This is a shell archive.  Remove anything before this line, then unpack
  41. # it by saving it into a file and typing "sh file".  To overwrite existing
  42. # files, type "sh file -c".  You can also feed this as standard input via
  43. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  44. # will see the following message at the end:
  45. #        "End of shell archive."
  46. # Contents:  dl.c
  47. # Wrapped by bobp@oscar on Tue Feb 25 14:27:48 1992
  48. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  49. if test -f dl.c -a "${1}" != "-c" ; then 
  50.   echo shar: Will not over-write existing file \"dl.c\"
  51. else
  52. echo shar: Extracting \"dl.c\" \(2795 characters\)
  53. sed "s/^X//" >dl.c <<'END_OF_dl.c'
  54. X/*
  55. X * line3d was dervied from DigitalLine.c published as "Digital Line Drawing"
  56. X * by Paul Heckbert from "Graphics Gems", Academic Press, 1990
  57. X * 
  58. X * 3D modifications by Bob Pendleton. The original source code was in the public
  59. X * domain, the author of the 3D version places his modifications in the
  60. X * public domain as well.
  61. X * 
  62. X * line3d uses Bresenham's algorithm to generate the 3 dimensional points on a
  63. X * line from (x1, y1, z1) to (x2, y2, z2)
  64. X * 
  65. X */
  66. X
  67. X/* find maximum of a and b */
  68. X#define MAX(a,b) (((a)>(b))?(a):(b))
  69. X
  70. X/* absolute value of a */
  71. X#define ABS(a) (((a)<0) ? -(a) : (a))
  72. X
  73. X/* take sign of a, either -1, 0, or 1 */
  74. X#define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)
  75. X
  76. Xpoint3d(x, y, z)
  77. X    int x, y, z;
  78. X{
  79. X
  80. X    /* output the point as you see fit */
  81. X
  82. X}
  83. X
  84. Xline3d(x1, y1, x2, y2, z1, z2)
  85. X    int x1, y1, x2, y2, z1, z2;
  86. X{
  87. X    int xd, yd, zd;
  88. X    int x, y, z;
  89. X    int ax, ay, az;
  90. X    int sx, sy, sz;
  91. X    int dx, dy, dz;
  92. X
  93. X    dx = x2 - x1;
  94. X    dy = y2 - y1;
  95. X    dz = z2 - z1;
  96. X
  97. X    ax = ABS(dx) << 1;
  98. X    ay = ABS(dy) << 1;
  99. X    az = ABS(dz) << 1;
  100. X
  101. X    sx = ZSGN(dx);
  102. X    sy = ZSGN(dy);
  103. X    sz = ZSGN(dz);
  104. X
  105. X    x = x1;
  106. X    y = y1;
  107. X    z = z1;
  108. X
  109. X    if (ax >= MAX(ay, az))            /* x dominant */
  110. X    {
  111. X        yd = ay - (ax >> 1);
  112. X        zd = az - (ax >> 1);
  113. X        for (;;)
  114. X        {
  115. X            point3d(x, y, z);
  116. X            if (x == x2)
  117. X            {
  118. X                return;
  119. X            }
  120. X
  121. X            if (yd >= 0)
  122. X            {
  123. X                y += sy;
  124. X                yd -= ax;
  125. X            }
  126. X
  127. X            if (zd >= 0)
  128. X            {
  129. X                z += sz;
  130. X                zd -= ax;
  131. X            }
  132. X
  133. X            x += sx;
  134. X            yd += ay;
  135. X            zd += az;
  136. X        }
  137. X    }
  138. X    else if (ay >= MAX(ax, az))            /* y dominant */
  139. X    {
  140. X        xd = ax - (ay >> 1);
  141. X        zd = az - (ay >> 1);
  142. X        for (;;)
  143. X        {
  144. X            point3d(x, y, z);
  145. X            if (y == y2)
  146. X            {
  147. X                return;
  148. X            }
  149. X
  150. X            if (xd >= 0)
  151. X            {
  152. X                x += sx;
  153. X                xd -= ay;
  154. X            }
  155. X
  156. X            if (zd >= 0)
  157. X            {
  158. X                z += sz;
  159. X                zd -= ay;
  160. X            }
  161. X
  162. X            y += sy;
  163. X            xd += ax;
  164. X            zd += az;
  165. X        }
  166. X    }
  167. X    else if (az >= MAX(ax, ay))            /* z dominant */
  168. X    {
  169. X        xd = ax - (az >> 1);
  170. X        yd = ay - (az >> 1);
  171. X        for (;;)
  172. X        {
  173. X            point3d(x, y, z);
  174. X            if (z == z2)
  175. X            {
  176. X                return;
  177. X            }
  178. X
  179. X            if (xd >= 0)
  180. X            {
  181. X                x += sx;
  182. X                xd -= az;
  183. X            }
  184. X
  185. X            if (yd >= 0)
  186. X            {
  187. X                y += sy;
  188. X                yd -= az;
  189. X            }
  190. X
  191. X            z += sz;
  192. X            xd += ax;
  193. X            yd += ay;
  194. X        }
  195. X    }
  196. X}
  197. END_OF_dl.c
  198. if test 2795 -ne `wc -c <dl.c`; then
  199.     echo shar: \"dl.c\" unpacked with wrong size!
  200. fi
  201. # end of overwriting check
  202. fi
  203. echo shar: End of shell archive.
  204. exit 0
  205.  
  206.