summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/bresnham.c
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONTRIB/SNIP/bresnham.c')
-rwxr-xr-xreference/C/CONTRIB/SNIP/bresnham.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/bresnham.c b/reference/C/CONTRIB/SNIP/bresnham.c
new file mode 100755
index 0000000..6bfc344
--- /dev/null
+++ b/reference/C/CONTRIB/SNIP/bresnham.c
@@ -0,0 +1,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 */
+}