home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / ddjmag / ddj8908.zip / PORTER.LST < prev    next >
File List  |  1989-07-06  |  8KB  |  268 lines

  1. GRAPHICS PROGRAMMING COLUMN
  2. by Kent Porter
  3.  
  4. [LISTING ONE]
  5.  
  6. /* ELLIPSE.C: Midpoint algorithm for drawing an ellipse */
  7. /* Based on Wilton's "VIDEO SYSTEMS," pp 230-231 */
  8. /* For inclusion in GRAFIX.LIB */
  9. /* K. Porter, DDJ Graphics Programming Column, 8/89 */
  10.  
  11. #include "grafix.h"
  12.  
  13. void far ellipse (int cx, int cy,                        /* center x, y */
  14.               int horiz_rad, int vert_rad)       /* radii ("semi-axes") */
  15. {
  16. int   x = 0, y = vert_rad;                 /* starting coords for curve */
  17. long  asq = (long) horiz_rad * horiz_rad;                        /* a^2 */
  18. long  a2sq = asq + asq;                                         /* 2a^2 */
  19. long  bsq = (long) vert_rad * vert_rad;                          /* b^2 */
  20. long  b2sq = bsq + bsq;                                         /* 2b^2 */
  21. long  d, xd, yd;                                      /* control values */
  22.  
  23.   /* Initialize control values */
  24.   d = bsq - asq * vert_rad + asq / 4L;            /* b^2 - a^2b + a^2/4 */
  25.   xd = 0L;
  26.   yd = a2sq * vert_rad;                                        /* 2a^2b */
  27.  
  28.   /* Loop to draw first half of quadrant */
  29.   while (xd < yd) {
  30.     draw_point (cx+x, cy+y);             /* set pixels in all quadrants */
  31.     draw_point (cx-x, cy+y);
  32.     draw_point (cx+x, cy-y);
  33.     draw_point (cx-x, cy-y);
  34.     if (d > 0L) {              /* if nearest pixel is toward the center */
  35.       --y;                                        /* move toward center */
  36.       yd -= a2sq;                              /* update control values */
  37.       d  -= yd;
  38.     }
  39.     ++x;                                            /* next horiz point */
  40.     xd += b2sq;                                /* update control values */
  41.     d  += bsq + xd;
  42.   }
  43.  
  44.   /* Loop to draw second half of quadrant */
  45.   d += (3L * (asq-bsq) / 2L - (xd+yd)) / 2L;
  46.   while (y >= 0) {                                   /* do until y = 0 */
  47.     draw_point (cx+x, cy+y);            /* set pixels in all quadrants */
  48.     draw_point (cx-x, cy+y);
  49.     draw_point (cx+x, cy-y);
  50.     draw_point (cx-x, cy-y);
  51.     if (d < 0L) {               /* if nearest pixel is outside ellipse */
  52.       ++x;                                    /* move away from center */
  53.       xd += b2sq;                             /* update control values */
  54.       d  += xd;
  55.     }
  56.     --y;                                        /* next vertical point */
  57.     yd -= a2sq;                               /* update control values */
  58.     d  += asq - yd;
  59.   }
  60. } /* --------------- */
  61.  
  62. [LISTING TWO]
  63.  
  64. Caption: Add these entries to your copy of GRAFIX.H
  65.  
  66.  
  67. /* From August '89 */
  68. /* --------------- */
  69. void far ellipse                                    /* draw ellipse */
  70.             (int cx, int cy,                      /* at center x, y */
  71.              int horiz_rad, int vert_rad);     /* radii (semi-axes) */
  72.  
  73. void far arc (int x1, int y1, int x2, int y2, int xc, int yc);
  74.                 /* draw conic spline, where knots are at x1, y1 and */
  75.                           /* and x2, y2, control point is at xc, yc */
  76.  
  77.  
  78. [LISTING THREE]
  79.  
  80. /* CIRCLES.C: Draws several ellipses to demo ellipse() function */
  81. /* K. Porter, DDJ Graphics Programming Column, Aug '89 */
  82.  
  83. #include <conio.h>
  84. #include "grafix.h"
  85.  
  86. void main ()
  87. {
  88.   if (init_video (EGA)) {
  89.     setcoords (-400, 300, 400, -300);
  90.  
  91.     /* draw a true circle in upper center of screen */
  92.     ellipse (dx(0), dy(100), dxunits (150), dyunits (150));
  93.  
  94.     /* tall skinny ellipse to left */
  95.     set_color1 (13);    /* light magenta */
  96.     ellipse (dx(-300), dy(0), dxunits (50), dyunits (250));
  97.  
  98.     /* short fat ellipse lower right */
  99.     set_color1 (10);    /* light green */
  100.     ellipse (dx(150), dy(-200), dxunits (200), dyunits (30));
  101.  
  102.     /* hold for keypress, then quit */
  103.     getch();
  104.   }
  105. }
  106.  
  107.  
  108. [LISTING FOUR]
  109.  
  110. /* ARC.C: Draws a conic spline using fixed point math */
  111. /* Knots are at x1, y1 and x2, y2, control pt at xc, yc */
  112. /* For inclusion in GRAFIX.LIB */
  113. /* K. Porter, DDJ Graphics Programming Column, Aug '89 */
  114.  
  115. #include "grafix.h"
  116. #include <math.h>
  117. #define HALFPI 102944L                          /* fixed-point PI/2 */
  118.  
  119. void far arc (int x1, int y1, int x2, int y2, int xc, int yc)
  120. {
  121. int i, x, y, prevx = -1, prevy = -1;
  122. int delta_x, delta_y, delta_t, dt = 804, den = 10;
  123. long vx, vy, ux, uy, x0, y0;
  124.  
  125.   /* fixed-point control values for this arc */
  126.   vx = (long)(xc - x2) << 16;                  /* distance to start */
  127.   vy = (long)(yc - y2) << 16;
  128.   ux = (long)(xc - x1) << 16;    /* current point adjustment factor */
  129.   uy = (long)(yc - y1) << 16;
  130.   x0 = ((long)x1 << 16) - vx;                      /* center of arc */
  131.   y0 = ((long)y1 << 16) - vy;
  132.  
  133.   /* compute pixel density factor (2^den) */
  134.   delta_x = (labs (vx) + labs (ux)) >> 16;
  135.   delta_y = (labs (vy) + labs (uy)) >> 16;
  136.   delta_t = delta_x + delta_y;
  137.   while (dt > delta_t) {
  138.     dt /= 2;
  139.     --den;
  140.   }
  141.  
  142. for (i = (int)((HALFPI << den) >> 16); i >= 0; --i) {
  143.     x = (int)((x0 + vx) >> 16);                 /* current position */
  144.     y = (int)((y0 + vy) >> 16);
  145.     if ((x != prevx) || (y != prevy))  /* if not same as last point */
  146.       draw_point (x, y);                          /* draw new point */
  147.     prevx = x;                            /* remember this position */
  148.     prevy = y;
  149.     ux -= vx >> den;                                 /* advance arc */
  150.     uy -= vy >> den;                           /* division by 2^den */
  151.     vx += ux >> den;
  152.     vy += uy >> den;
  153.   }
  154. }
  155.  
  156.  
  157. [LISTING FIVE]
  158.  
  159. /* CONICS.C: Draws several conic splines and their enclosing hulls */
  160. /* K. Porter, DDJ Graphics Programming Column, Aug '89 */
  161.  
  162. #include <conio.h>
  163. #include "grafix.h"
  164.  
  165. void main ()
  166. {
  167.   if (init_video (EGA)) {
  168.  
  169.     /* Fig. 1a */
  170.     set_color1 (12);   /* red hull */
  171.     draw_line ( 5,  20, 250, 20);
  172.     draw_line (50, 180, 250, 20);
  173.     set_color1 (15);   /* white curve */
  174.     arc (5, 20, 50, 180, 250, 20);
  175.  
  176.     /* Fig. 1b */
  177.     set_color1 (12);   /* red hull */
  178.     draw_line (630,  20, 520, 20);
  179.     draw_line (470, 120, 520, 20);
  180.     set_color1 (15);   /* white curve */
  181.     arc (630, 20, 470, 120, 520, 20);
  182.  
  183.     /* acute conic in the center */
  184.     set_color1 (12);
  185.     draw_line (200, 330, 370, 40);
  186.     draw_line (340, 200, 370, 40);
  187.     set_color1 (15);
  188.     arc (200, 330, 340, 200, 370, 40);
  189.  
  190.     /* wait for keypress and quit */
  191.     getch();
  192.   }
  193. }
  194.  
  195. [LISTING SIX]
  196.  
  197. /* HANGER.C: Draws a coat hanger with lines and conic splines */
  198. /* K. Porter, DDJ Graphics Programming Column, Aug '89 */
  199.  
  200. #include <conio.h>
  201. #include "grafix.h"
  202.  
  203. void main ()
  204. {
  205.   if (init_video (EGA)) {
  206.  
  207.     /* draw body of hanger */
  208.     draw_line (320, 180, 140, 240);         /* left top */
  209.     arc (140, 240, 140, 260, 80, 260);      /* left end */
  210.     draw_line (140, 260, 500, 260);         /* bottom */
  211.     arc (500, 260, 500, 240, 560, 260);     /* right end */
  212.     draw_line (500, 240, 320, 180);         /* right top */
  213.  
  214.     /* draw hook at top */
  215.     arc (320, 180, 310, 160, 320, 168);
  216.     arc (310, 160, 300, 140, 300, 154);
  217.     arc (300, 140, 320, 120, 300, 120);
  218.     arc (320, 120, 340, 140, 340, 120);
  219.  
  220.     /* wait for keypress and quit */
  221.     getch();
  222.   }
  223. }
  224.  
  225.  
  226. [LISTING SEVEN]
  227.  
  228. /* BALL.C: Ball throwing a shadow */
  229.  
  230. #include "grafix.h"
  231. #include <conio.h>
  232.  
  233. void main ()
  234. {
  235.   if (init_video (EGA)) {
  236.     setcoords (-320, 240, 319, -239);
  237.  
  238.     /* Draw the backdrop in dark blue */
  239.     set_color1 (1);
  240.     fill_rect (0, 0, 639, 150);
  241.  
  242.     /* Draw the floor in light blue */
  243.     set_color1 (9);
  244.     fill_rect (0, 150, 639, 199);
  245.  
  246.     /* Create shadow on floor */
  247.     set_color1 (8);     /* dark gray */
  248.     ellipse (dx(0), dy(-160), 160, 25);
  249.     setfillborder (8);
  250.     floodfill (dx(0), dy(-130));
  251.  
  252.     /* Draw the ball */
  253.     set_color1 (7);     /* light gray */
  254.     ellipse (dx(0), dy(0), dxunits (150), dyunits (150));
  255.  
  256.     /* Shade the ball underneath */
  257.     arc (dx(-150), dy(0), dx(150), dy(0), dx(0), dy(-50));
  258.     setfillborder (7);
  259.     floodfill (dx(0), dy(-25));
  260.  
  261.     /* Shade the ball white on top */
  262.     set_color1 (15);
  263.     floodfill (dx(0), dy (145));
  264.  
  265.     /* Hold for keypress and quit */
  266.     getch();
  267.   }
  268. }