Here's some REALLY OLD fossilized code I wrote years ago to test a poly
filling algorithm.  This code can be compiled by the old MS DOS (C 8.0)
compiler.  It works DIRECTLY on an old DOS text screen, using the screen
memory address as a 80x25 array in which to draw the polygon and fill it.
If compiled, the program would probably work in a DOS Windows under Windows
9x.

The program expects you to move the cursor around, and enter each vertex of
the polygon (by pressing space).  When done, you hit return, and the code
will draw the polygon using Bresenham lines.  Then when you hit return
again, the code will attempt to fill the polygon.

Even though this code is written for a DOS text screen, the general line
drawing and polygon filling code should be portable without too much effort
(just yank out all the DOS junk).  I don't think this code is recursive, so
it should be relatively Palm-friendly.

Doug.

-------------------- POLYFILL.C --------------------
#include <stdio.h>
#include <stdlib.h>
#include <bios.h>

#ifndef XMAX
#define XMAX            80
#endif
#ifndef YMAX
#define YMAX            25
#endif

#define VMAX            20
#define VRAM(x,y)       (*vram)[y][x].chr

struct coord
{
        int             x;
        int             y;
} vc[VMAX];

typedef struct
{
        char    chr;
        char    att;
} VRam[YMAX][XMAX];

VRam far *vram = (VRam far *)0xb8000000;


void            DrawLine(unsigned, unsigned, unsigned, unsigned, char);
unsigned        GetCoord(unsigned *, unsigned *, char);
unsigned        FillThatSucker(char);
void            NodeDegreeInLAG(int *, int *, unsigned *, unsigned *);
void            FillVram(char, unsigned);
void            PutCursor(unsigned, unsigned);
unsigned        Kybd(void);


int main(int argc, char *argv[])
{
        int i, v;
        unsigned ret;
        char chr;

        argc, argv;

        while (1)
        {
                FillVram(' ', 0x07);
                PutCursor(0, 0);
                vc[0].x = vc[0].y = 0;

                for (v = 0, chr = '0'; v < VMAX; v++)
                {
                        if (v)
                        {
                                vc[v].x = vc[v-1].x;
                                vc[v].y = vc[v-1].y;
                        }
                        if (!(ret = GetCoord(&vc[v].x, &vc[v].y, chr)))
                                break;

                        if (ret == 13)
                        {
                                vc[v].x = vc[0].x;
                                vc[v].y = vc[0].y;
                                break;
                        }
                        chr += (chr == '9') ? (char)8 : (char)1;
                }

                if (!ret) break;
                if (v < 3) continue;

                for (i = 0; i < v; i++)
                        DrawLine(vc[i].x, vc[i].y, vc[i+1].x, vc[i+1].y,
'*');

                if (Kybd() == 0x011b) break;

                FillThatSucker('+');

                if (Kybd() == 0x011b) break;
        }

        return (0);
}


void DrawLine(unsigned x1, unsigned y1, unsigned x2, unsigned y2, char chr)
{
        unsigned x0, y0;
        int dx, dy;
        int i, Yadj, Err, Eadj, Ecor;

        x0 = x1, y0 = y1;
        dx = x2-x1, dy = y2-y1;

        if (dx < 0)
        {
                dx = -dx;
                dy = -dy;
                x0 = x2, y0 = y2;
        }

        Yadj = 1;
        if (dy < 0)
        {
                dy = -dy;
                Yadj = -1;
        }

        if (dx < dy)
        {                                               // scan y
                Ecor = 2*dy;
                Eadj = 2*dx;
                Err = Eadj-dy;

                for (i = 0; i <= dy; i++)
                {
                        VRAM(x0,y0) = chr;
                        if (Err >= 0)
                        {
                                Err -= Ecor;
                                x0++;
                        }
                        Err += Eadj;
                        y0 += Yadj;
                }
        }
        else
        {                                               // scan x
                Ecor = 2*dx;
                Eadj = 2*dy;
                Err = Eadj-dx;

                for (i = 0; i <= dx; i++)
                {
                        VRAM(x0,y0) = chr;
                        if (Err >= 0)
                        {
                                Err -= Ecor;
                                y0 += Yadj;
                        }
                        Err += Eadj;
                        x0++;
                }
        }
}


unsigned GetCoord(unsigned *xc, unsigned *yc, char chr)
{
        unsigned key;

        while ((key = Kybd() >> 8 & 0xff) != 0x01)
        {
                switch (key)
                {
                case 0x39:                                      // Space
                        VRAM(*xc,*yc) = chr;
                        return (' ');

                case 0x1c:                                      // Return
                        return (13);

                case 0x48:                                      // Up
                        if ((*yc)-- == 0)
                                *yc = YMAX-1;
                        break;

                case 0x50:                                      // Down
                        if (++(*yc) >= YMAX)
                                *yc = 0;
                        break;

                case 0x4b:                                      // Left
                        if ((*xc)-- == 0)
                                *xc = XMAX-1;
                        break;

                case 0x4d:                                      // Right
                        if (++(*xc) >= XMAX)
                                *xc = 0;
                        break;

                default:
                        break;
                }
                PutCursor(*xc, *yc);
        }

        return (0);
}


unsigned FillThatSucker(char chr)
{
        int xf, yf;
        unsigned ContourCount, above, below, ErrorFlag;

        ErrorFlag = 0;

        for (yf = 0; yf < YMAX; yf++)
        {
                ContourCount = 0;
                xf = 0;
                while (xf < XMAX)               // XMAX could be backscanned
to avoid *++++++**     *+++++++|
                {
                        if (VRAM(xf,yf) == '*')
                        {
                                NodeDegreeInLAG(&xf, &yf, &above, &below);
                                if ((above == 1) && (below == 1))
                                        ContourCount++;
                                if ((above+below) & 0xfffd)             //
a+b == 0 or 2 else error
                                {
                                        (*vram)[yf][xf-1].att = 0x0c;
// ???                          ContourCount = 0;
// Force outside (looks better)
                                        ErrorFlag++;
                                }
                        }
                        else
                        {
                                if (ContourCount & 0x0001)
// odd therefore inside
                                        VRAM(xf,yf) = chr;
                                xf++;
                        }
                }
        }
        return (ErrorFlag);
}


void NodeDegreeInLAG(int *xf, int *yf, unsigned *above, unsigned *below)
{
        *above = *below = 0;
        if (VRAM(*xf-1,*yf-1) == '*') (*above)++;
        if (VRAM(*xf-1,*yf+1) == '*') (*below)++;
        while (VRAM(*xf,*yf) == '*')
        {
                if ( (VRAM(*xf,*yf-1) == '*') && (VRAM(*xf-1,*yf-1) != '*')
) (*above)++;
                if ( (VRAM(*xf,*yf+1) == '*') && (VRAM(*xf-1,*yf+1) != '*')
) (*below)++;
                (*xf)++;
        }
        if ( (VRAM(*xf,*yf-1) == '*') && (VRAM(*xf-1,*yf-1) != '*') )
(*above)++;
        if ( (VRAM(*xf,*yf+1) == '*') && (VRAM(*xf-1,*yf+1) != '*') )
(*below)++;
}


void FillVram(char chr, unsigned atr)
{
        int i, j;

        for (j = 0; j < YMAX; j++)
                for (i = 0; i < XMAX; i++)
                {
                        VRAM(i,j) = chr;
                        (*vram)[j][i].att = (char)atr;
                }
}


void PutCursor(unsigned x, unsigned y)
{
        union REGS Reg;

        Reg.x.ax = 0x0200;
        Reg.x.bx = 0x0000;
        Reg.x.dx = (y << 8) | x;
        int86(0x10, &Reg, &Reg);
}


unsigned Kybd(void)
{
        return (_bios_keybrd(_KEYBRD_READ));
}
----------------------------------------

-- 
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palmos.com/dev/tech/support/forums/

Reply via email to