1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
/*
** Public Domain mode 13h Bresenham line/circle algorithms
** By Brian Dessent
**
** Written for Borland, modified for others by Bob Stout
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <time.h> /* for randomize */
#ifndef __TURBOC__
#define random(num) (int)(((rand())*(long)(num))/(((long)RAND_MAX)+1))
#define randomize() srand((unsigned)time(NULL)|1)
#else
#endif
#ifndef MK_FP
#define MK_FP(seg,offset) \
((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset)))
#endif
#define SCREEN_WIDTH 320
#define SCREEN_HEIGTH 200
#define MAX_X (SCREEN_WIDTH-1)
#define MAX_Y (SCREEN_HEIGTH-1)
/* prototypes */
void setmode(int mode);
void plotdot(int x, int y, char c);
void bresenham_line(int x, int y, int x2, int y2, char c);
void bresenham_circle(int xc, int yc, int r, char c);
void main(void);
/* code begins */
/* uses BIOS to set video mode */
void setmode(int mode)
{
union REGS r;
r.x.ax = mode;
int86(0x10, &r, &r);
}
/* plots a dot at (x, y) with color c */
void plotdot(int x, int y, char c)
{
register char far *addr;
if(x < 0 || x > MAX_X || y < 0 || y > MAX_Y)
return;
addr = MK_FP(0xa000, (SCREEN_WIDTH * y) + x);
*addr = c;
}
/* draws a line from (x, y) to (x2, y2) in color c */
void bresenham_line(int x, int y, int x2, int y2, char c)
{
int i, steep = 0, sx, sy, dx, dy, e;
dx = abs(x2 - x);
sx = ((x2 - x) > 0) ? 1 : -1;
dy = abs(y2 - y);
sy = ((y2 - y) > 0) ? 1 : -1;
if(dy > dx)
{
steep = 1;
x ^= y; /* swap x and y */
y ^= x;
x ^= y;
dx ^= dy; /* swap dx and dy */
dy ^= dx;
dx ^= dy;
sx ^= sy; /* swap sx and sy */
sy ^= sx;
sx ^= sy;
}
e = 2 * dy - dx;
for(i = 0;i < dx;i++)
{
if(steep)
plotdot(y, x, c);
else plotdot(x, y, c);
while(e >= 0)
{
y += sy;
e -= 2 * dx;
}
x += sx;
e += 2 * dy;
}
plotdot(x2, y2, c);
}
/* draws a circle at (xc, yc) with radius r in color c
**
** note: the scaling factor of (SCREEN_WIDTH / SCREEN_HEIGTH) is used when
** updating d. This makes round circles. If you want ellipses, you can
** modify that ratio.
*/
void bresenham_circle(int xc, int yc, int r, char c)
{
int x = 0, y = r, d = 2 * (1 - r);
while(y > 0)
{
plotdot(xc + x, yc + y, c);
plotdot(xc + x, yc - y, c);
plotdot(xc - x, yc + y, c);
plotdot(xc - x, yc - y, c);
if(d + y > 0)
{
y -= 1;
d -= (2 * y * SCREEN_WIDTH / SCREEN_HEIGTH) - 1;
}
if(x > d)
{
x += 1;
d += (2 * x) + 1;
}
}
}
/* draws random lines and circles until a key is pressed in mode 13h */
/* (draws in colors 0 - 63 only) */
void main(void)
{
int i=0;
randomize();
setmode(0x13);
while(!kbhit())
{
bresenham_line(random(SCREEN_WIDTH), random(SCREEN_HEIGTH),
random(SCREEN_WIDTH), random(SCREEN_HEIGTH), i = ++i % 64);
bresenham_circle(random(SCREEN_WIDTH), random(SCREEN_HEIGTH),
random(50), i = ++i % 64);
}
getch();
setmode(0x03); /* set to color text mode, clearing screen */
}
|