home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
ddjmag
/
ddj8908.arc
/
PORTER.LST
< prev
next >
Wrap
File List
|
1989-07-06
|
8KB
|
268 lines
GRAPHICS PROGRAMMING COLUMN
by Kent Porter
[LISTING ONE]
/* ELLIPSE.C: Midpoint algorithm for drawing an ellipse */
/* Based on Wilton's "VIDEO SYSTEMS," pp 230-231 */
/* For inclusion in GRAFIX.LIB */
/* K. Porter, DDJ Graphics Programming Column, 8/89 */
#include "grafix.h"
void far ellipse (int cx, int cy, /* center x, y */
int horiz_rad, int vert_rad) /* radii ("semi-axes") */
{
int x = 0, y = vert_rad; /* starting coords for curve */
long asq = (long) horiz_rad * horiz_rad; /* a^2 */
long a2sq = asq + asq; /* 2a^2 */
long bsq = (long) vert_rad * vert_rad; /* b^2 */
long b2sq = bsq + bsq; /* 2b^2 */
long d, xd, yd; /* control values */
/* Initialize control values */
d = bsq - asq * vert_rad + asq / 4L; /* b^2 - a^2b + a^2/4 */
xd = 0L;
yd = a2sq * vert_rad; /* 2a^2b */
/* Loop to draw first half of quadrant */
while (xd < yd) {
draw_point (cx+x, cy+y); /* set pixels in all quadrants */
draw_point (cx-x, cy+y);
draw_point (cx+x, cy-y);
draw_point (cx-x, cy-y);
if (d > 0L) { /* if nearest pixel is toward the center */
--y; /* move toward center */
yd -= a2sq; /* update control values */
d -= yd;
}
++x; /* next horiz point */
xd += b2sq; /* update control values */
d += bsq + xd;
}
/* Loop to draw second half of quadrant */
d += (3L * (asq-bsq) / 2L - (xd+yd)) / 2L;
while (y >= 0) { /* do until y = 0 */
draw_point (cx+x, cy+y); /* set pixels in all quadrants */
draw_point (cx-x, cy+y);
draw_point (cx+x, cy-y);
draw_point (cx-x, cy-y);
if (d < 0L) { /* if nearest pixel is outside ellipse */
++x; /* move away from center */
xd += b2sq; /* update control values */
d += xd;
}
--y; /* next vertical point */
yd -= a2sq; /* update control values */
d += asq - yd;
}
} /* --------------- */
[LISTING TWO]
Caption: Add these entries to your copy of GRAFIX.H
/* From August '89 */
/* --------------- */
void far ellipse /* draw ellipse */
(int cx, int cy, /* at center x, y */
int horiz_rad, int vert_rad); /* radii (semi-axes) */
void far arc (int x1, int y1, int x2, int y2, int xc, int yc);
/* draw conic spline, where knots are at x1, y1 and */
/* and x2, y2, control point is at xc, yc */
[LISTING THREE]
/* CIRCLES.C: Draws several ellipses to demo ellipse() function */
/* K. Porter, DDJ Graphics Programming Column, Aug '89 */
#include <conio.h>
#include "grafix.h"
void main ()
{
if (init_video (EGA)) {
setcoords (-400, 300, 400, -300);
/* draw a true circle in upper center of screen */
ellipse (dx(0), dy(100), dxunits (150), dyunits (150));
/* tall skinny ellipse to left */
set_color1 (13); /* light magenta */
ellipse (dx(-300), dy(0), dxunits (50), dyunits (250));
/* short fat ellipse lower right */
set_color1 (10); /* light green */
ellipse (dx(150), dy(-200), dxunits (200), dyunits (30));
/* hold for keypress, then quit */
getch();
}
}
[LISTING FOUR]
/* ARC.C: Draws a conic spline using fixed point math */
/* Knots are at x1, y1 and x2, y2, control pt at xc, yc */
/* For inclusion in GRAFIX.LIB */
/* K. Porter, DDJ Graphics Programming Column, Aug '89 */
#include "grafix.h"
#include <math.h>
#define HALFPI 102944L /* fixed-point PI/2 */
void far arc (int x1, int y1, int x2, int y2, int xc, int yc)
{
int i, x, y, prevx = -1, prevy = -1;
int delta_x, delta_y, delta_t, dt = 804, den = 10;
long vx, vy, ux, uy, x0, y0;
/* fixed-point control values for this arc */
vx = (long)(xc - x2) << 16; /* distance to start */
vy = (long)(yc - y2) << 16;
ux = (long)(xc - x1) << 16; /* current point adjustment factor */
uy = (long)(yc - y1) << 16;
x0 = ((long)x1 << 16) - vx; /* center of arc */
y0 = ((long)y1 << 16) - vy;
/* compute pixel density factor (2^den) */
delta_x = (labs (vx) + labs (ux)) >> 16;
delta_y = (labs (vy) + labs (uy)) >> 16;
delta_t = delta_x + delta_y;
while (dt > delta_t) {
dt /= 2;
--den;
}
for (i = (int)((HALFPI << den) >> 16); i >= 0; --i) {
x = (int)((x0 + vx) >> 16); /* current position */
y = (int)((y0 + vy) >> 16);
if ((x != prevx) || (y != prevy)) /* if not same as last point */
draw_point (x, y); /* draw new point */
prevx = x; /* remember this position */
prevy = y;
ux -= vx >> den; /* advance arc */
uy -= vy >> den; /* division by 2^den */
vx += ux >> den;
vy += uy >> den;
}
}
[LISTING FIVE]
/* CONICS.C: Draws several conic splines and their enclosing hulls */
/* K. Porter, DDJ Graphics Programming Column, Aug '89 */
#include <conio.h>
#include "grafix.h"
void main ()
{
if (init_video (EGA)) {
/* Fig. 1a */
set_color1 (12); /* red hull */
draw_line ( 5, 20, 250, 20);
draw_line (50, 180, 250, 20);
set_color1 (15); /* white curve */
arc (5, 20, 50, 180, 250, 20);
/* Fig. 1b */
set_color1 (12); /* red hull */
draw_line (630, 20, 520, 20);
draw_line (470, 120, 520, 20);
set_color1 (15); /* white curve */
arc (630, 20, 470, 120, 520, 20);
/* acute conic in the center */
set_color1 (12);
draw_line (200, 330, 370, 40);
draw_line (340, 200, 370, 40);
set_color1 (15);
arc (200, 330, 340, 200, 370, 40);
/* wait for keypress and quit */
getch();
}
}
[LISTING SIX]
/* HANGER.C: Draws a coat hanger with lines and conic splines */
/* K. Porter, DDJ Graphics Programming Column, Aug '89 */
#include <conio.h>
#include "grafix.h"
void main ()
{
if (init_video (EGA)) {
/* draw body of hanger */
draw_line (320, 180, 140, 240); /* left top */
arc (140, 240, 140, 260, 80, 260); /* left end */
draw_line (140, 260, 500, 260); /* bottom */
arc (500, 260, 500, 240, 560, 260); /* right end */
draw_line (500, 240, 320, 180); /* right top */
/* draw hook at top */
arc (320, 180, 310, 160, 320, 168);
arc (310, 160, 300, 140, 300, 154);
arc (300, 140, 320, 120, 300, 120);
arc (320, 120, 340, 140, 340, 120);
/* wait for keypress and quit */
getch();
}
}
[LISTING SEVEN]
/* BALL.C: Ball throwing a shadow */
#include "grafix.h"
#include <conio.h>
void main ()
{
if (init_video (EGA)) {
setcoords (-320, 240, 319, -239);
/* Draw the backdrop in dark blue */
set_color1 (1);
fill_rect (0, 0, 639, 150);
/* Draw the floor in light blue */
set_color1 (9);
fill_rect (0, 150, 639, 199);
/* Create shadow on floor */
set_color1 (8); /* dark gray */
ellipse (dx(0), dy(-160), 160, 25);
setfillborder (8);
floodfill (dx(0), dy(-130));
/* Draw the ball */
set_color1 (7); /* light gray */
ellipse (dx(0), dy(0), dxunits (150), dyunits (150));
/* Shade the ball underneath */
arc (dx(-150), dy(0), dx(150), dy(0), dx(0), dy(-50));
setfillborder (7);
floodfill (dx(0), dy(-25));
/* Shade the ball white on top */
set_color1 (15);
floodfill (dx(0), dy (145));
/* Hold for keypress and quit */
getch();
}
}