Friday, February 04, 2011

Solid Area Scan Conversion



/*
 * THIS IS A C PROGRAM THAT DEMONSTRATION OF SOLID AREA SCAN CONVERSION BY
*                       EDGE-FILL ALGORITHM
*                       FENCE-FILL ALGORITHM
*                       EDGE-FLAG ALGORITHM
 */

#include"fill.h"

 void edgefill(point array[], int length);
 void fencefill(point array[], int length, int fencex1, int fencey1, int fencex2, int fencey2);
 void edgeflag(point array[], int length);
 
 int main()
 {
            point polygon[10];
            int choice;
            int i, j, vertices, fencex1,fencey1, fencex2, fencey2;
           
            printf("\n\nEnter number of vertices of the polygon: ");
            scanf("%d",&vertices);
            printf("\nKeep on entering the vertices.................\n");
            for(i=0;i<vertices;i++)
                        scanf("%d%d",&polygon[i].x,&polygon[i].y);
           
            initialize();
           
            do {
            clrscr();
            cleardevice();

            printf("\n\n");
            printf("\t\t ***  1.         USE EDGE-FILL               ***");
            printf("\n\n");
            printf("\t\t ***  2.         USE FENCE-FILL             ***");
            printf("\n\n");
            printf("\t\t ***  3.         USE EDGE-FLAG                        ***");
            printf("\n\n");
            printf("\t\t ---   4.         EXIT                              ---\n\n\t\t ->  ");
            scanf("%d",&choice);
           
                       
            /* clearing the frame buffer */
            for(i=0;i<pixels_in_a_row;i++)
            for(j=0;j<pixels_in_a_col;j++)
                        framebuffer[i][j]=0;
           
            cleardevice();

            switch(choice)
            {
            case(1):

            creategrid(DARKGRAY,WHITE,LIGHTGRAY);
            drawpolygon(polygon,vertices);
            getch();                                                                      
            edgefill(polygon, vertices);
            drawpolygon(polygon,vertices);        
            break;
           
            case(2):
           
            printf("\n\nEnter the endpoints of the fence: ");
            scanf("%d%d%d%d",&fencex1,&fencey1,&fencex2,&fencey2);
            cleardevice();
            creategrid(DARKGRAY,WHITE,LIGHTGRAY);
            drawpolygon(polygon,vertices);                                 /*  draw the polygon  */
            getch();                                                           /* on execution of next key     */
            drawline(fencex1, fencey1, fencex2, fencey2);
            getch();
            fencefill(polygon, vertices, fencex1, fencey1, fencex2, fencey2);
            drawline(fencex1, fencey1, fencex2, fencey2);
            drawpolygon(polygon,vertices);        
            getch();
            break;
           
            case(3):

            creategrid(DARKGRAY,WHITE,LIGHTGRAY);
            drawpolygon(polygon,vertices);         /*   draw the polygon */
            getch();                                               /* on execution of next key     */
            edgeflag(polygon, vertices);
            drawpolygon(polygon,vertices);        
            getch();
            break;
            }
            }while(choice!=4);
           
 outtextxy(getmaxx()/2-90,getmaxy()/2,"Demonstration Completed!");
 getch();                     
 return 0;
}

/*         The following function performs EDGE-FILL algorithm             */
void edgefill(point poly[], int size)
{
            int i=0, plotx, ploty;
            double slope_inv, xintersection, yintersection;
            point p1, p2, temp;
           
            do {
            p1 = poly[i];
            p2 = poly[(i+1)%size];
            if(p1.y==p2.y)               /* leave horizontal lines */
            {   
                        i++;
                        continue;
            }
            else if(p1.y>p2.y)
            {
                        temp = p1;
                        p1 = p2;
                        p2 = temp;
            }
            ploty = p1.y;
            while(ploty<p2.y)
            {
            slope_inv = (double)(p1.x - p2.x)/(p1.y - p2.y);
            yintersection = ploty+ 0.5;
            xintersection = p1.x + slope_inv*(yintersection - p1.y);
            plotx = floor(xintersection);
            if(plotx+0.5<=xintersection)
                        plotx++;
            for(;plotx<pixels_in_a_row/2;plotx++)
            complementpix_in_fb(plotx,ploty);
            ploty++;
            }
            showoutput(poly,size);
            getch();
            i++;
            }while(i<size);  
}

/*         The following function performs FENCE-FILL algorithm                       */
void fencefill(point poly[], int size, int fencex1, int fencey1, int fencex2, int fencey2)
{
            int i=0, plotx, ploty;
            double slope_inv, xintersection, yintersection, fencexintersection;
            double fence_slope_inv = (fencex1-fencex2)/(fencey1-fencey2);
            point p1, p2, temp;
           
            do {
            p1 = poly[i];
            p2 = poly[(i+1)%size];
            if(p1.y==p2.y)               /* leave horizontal lines */
             {  
                        i++;
                        continue;
            }
            else if(p1.y>p2.y)
            {
                        temp = p1;
                        p1 = p2;
                        p2 = temp;
            }
            ploty = p1.y;
            while(ploty<p2.y)
            {
            slope_inv = (double)(p1.x - p2.x)/(p1.y - p2.y);
             yintersection = ploty+ 0.5;
            xintersection = p1.x + slope_inv*(yintersection - p1.y);
            fencexintersection = fencex1 + fence_slope_inv*(yintersection - fencey1);
            if(floor(fencexintersection)+0.5<fencexintersection)
                        fencexintersection = ceil(fencexintersection);
            else
                        fencexintersection = floor(fencexintersection);           
            plotx = floor(xintersection);
            if(plotx+0.5<=xintersection)
                        plotx++;
            if(plotx<fencexintersection)
                        for(;plotx<fencexintersection;plotx++)
                                    complementpix_in_fb(plotx,ploty);
            else
                        for(;fencexintersection<plotx;fencexintersection++)
                                    complementpix_in_fb(fencexintersection,ploty);       
            ploty++;
            }
            showoutput(poly,size);
            drawline(fencex1,fencey1,fencex2,fencey2);
            getch();
            i++;
            }while(i<size);  
}

/*         The following function performs EDGE-FLAG algorithm                      */
void edgeflag(point poly[], int size)
{
            int i=0, j, plotx, ploty, xmax, xmin, ymax, ymin, xhash, yhash;
            int INSIDE;
            double slope_inv, xintersection, yintersection;
            point p1, p2, temp;
            /* contour outline */
            do {
            p1 = poly[i];
            p2 = poly[(i+1)%size];
            if(p1.y==p2.y)               /* leave horizontal lines */
              {  
                        i++;
                        continue;
            }
            else if(p1.y>p2.y)
            {
                        temp = p1;
                        p1 = p2;
                        p2 = temp;
            }
            ploty = p1.y;
            while(ploty<p2.y)
            {
            slope_inv = (double)(p1.x - p2.x)/(p1.y - p2.y);
             yintersection = ploty+ 0.5;
            xintersection = p1.x + slope_inv*(yintersection - p1.y);
            plotx = floor(xintersection);
            if(plotx+0.5<=xintersection)
                plotx++;
            complementpix_in_fb(plotx,ploty);        /* marking the border pixel for each scan line intersecting an edge */           
            ploty++;
            }          
            i++;
            }while(i<size);

            /* bordering complete show to users */
            showoutput(poly, size);
            getch();          

            /* determining minimum & maximum of the abscissa and ordinates respectively */
            xmax=xmin=ymax=ymin=0;
            for(i=1;i<size;i++)
            {
                        if(poly[xmax].x<poly[i].x)
                                    xmax=i;
                        else if(poly[xmin].x>poly[i].x)
                                    xmin=i;
                       
                        if(poly[ymax].y<poly[i].y)
                                    ymax=i;
                        else if(poly[ymin].y>poly[i].y)
                                    ymin=i;
            }
            xmax = poly[xmax].x;
            xmin = poly[xmin].x;
            ymax = poly[ymax].y;
            ymin = poly[ymin].y;   
            /* Now fill: */              
            do        {
            INSIDE=0;
            yhash = pixels_in_a_col - pixels_in_a_col/2 + ymin;
            for(i=xmin;i<=xmax;i++)
            {
                        xhash = pixels_in_a_row - pixels_in_a_row/2 + i;        
                        if(framebuffer[xhash][yhash]==1)
                                    if(INSIDE==1)
                                                INSIDE=0;
                                    else
                                                INSIDE=1;                                 
                        if(INSIDE)
                                    pixelon(i,ymin);
                        else
                                    pixeloff(i,ymin);                       
            }          
            drawpolygon(poly,size);
            getch();          
            ymin++;                      
            }while(ymin<ymax);
}

No comments:

Post a Comment

Do you think this information useful or was not up to the mark? Comment if you have any advices or suggestions about the post.