Graphics—边标志算法

#include "stdafx.h"
#include <graphics.h>
#include <iostream>
using namespace std;

//边标志算法
void edgeMarkFill(int n,int *points)
{
	 int flag=0;//标志位,判断在图形区域内(1),还是在外面(0)
	 int c1=0,c2=0;//c1为边界色,c2为背景色

	 int maxX=0,minX=0,maxY=0,minY=0;
	 int i=0,j=0;
 
	 //求maxX和minX
	 for(i=0,maxX=minX=points[0];i<n*2;i+=2)
	 {
		 if(maxX<points[i])
			 maxX=points[i];
		 else
			 minX=points[i];
	 }

	 //求maxY和minY
	 for(i=1,maxY=minY=points[1];i<n*2;i+=2)
	 {
		 if(maxY<points[i])
			 maxY=points[i];
		 else
			 minY=points[i];
	 }
	 
	 //下面进行边标志填充
	 for(i=minY+1;i<maxY;i++)
	 {
		 for(j=minX;j<=maxX;j++)
		 {
			c1=c2;
			c2=getpixel(j,i);//getpixel()返回值为该像素点的RGB值
			if(c1==WHITE&&c2==BLACK)
				flag=!flag;
			if(flag)
				putpixel(j,i,WHITE);
		 }

	     //为现实效果而延迟时间的空循环
		 for(int cc=0;cc<10000000;cc++);
	 }
}


int main()
{
	 int gdriver=DETECT, gmode;
	 initgraph(&gdriver,&gmode,"");//根据测试结果初始化图形界面

	 int points1[]={50,50,200,100,200,250,100,250,50,80,50,50};//定义多边形点的坐标
	 drawpoly(6,points1);          //画多边形
	 edgeMarkFill(6,points1);      //边标志填充

	 getchar();
	 closegraph();
 
	 return 0;
}
运行结果:


/*
边界标志算法

1. 对多边形的每一条边进行扫描转换,即对多边形边界所经过的象素作一个边界标志。

2.填充

    对每条与多边形相交的扫描线,按从左到右的顺序,逐个访问该扫描线上的象素。

    取一个布尔变量inside来指示当前点的状态,若点在多边形内,则inside为真。若点在多边形外,则inside为假。

    Inside 的初始值为假,每当当前访问象素为被打上标志的点,就把inside取反。对未打标志的点,inside不变。
*/
#include "stdafx.h"
#include "math.h"
#include "windows.h"
#include "stdio.h"
#include "conio.h"
#include "graphics.h"
 
int maxx,maxy,minx,miny;   //图形的边界

void dda(int x1,int y1,int x2,int y2)
{
	int steps;
    double xin,yin,dx,dy,x,y;
    dx = x2 - x1;
    dy = y2 - y1;

    if(fabs(dx) > fabs(dy))
		steps = fabs(dx);
	else
        steps = fabs(dy);
    xin = (double)(dx/steps);
	yin = (double)(dy/steps);
	x = x1;
	y = y1;
    int xfom,yfom;  //保存之前一个的坐标
    COLORREF k = RGB(0,0,255);
    for(int i = 0;i < steps;i++)
    {  
		xfom = x;
        yfom = y;    
        x = x + xin;  
        y = y + yin;
          
        if(yfom != (int)y)
			putpixel(x,y,k);
  
        if((y == maxy) || (y == miny))
			putpixel(x,y,RGB(255,255,255));  //处理极值奇点,涂成背景色
	}
	putpixel(x1,y1,RGB(255,255,255));   //涂成背景色 
	putpixel(x2,y2,RGB(255,255,255));   //涂成背景色 
}
 
  //填充多边形
void filling()
{
	putpixel(maxx,maxy,RGB(255,255,255));  //处理极值奇点,涂成背景色
    putpixel(minx,miny,RGB(255,255,255));  //处理极值奇点,涂成背景色

    double x1, y1;
    int in_flag;  //指示当前点的状态是否在边界内部 
    for(y1 = miny-1 ; y1 <maxy;y1++)
    { 
        in_flag = 0;//多边形内部标志变量
		for( x1 = minx-1;x1<maxx;x1++)
		{ 
			COLORREF l,m;
            l = getpixel(x1,y1);
            m = RGB(0,0,255);//多边形边界颜色
            if (l == m)
			{
				if (in_flag == 0)     
					in_flag = 1;
                else
					in_flag = 0;
			}
			if (in_flag)
				putpixel(x1,y1,RGB(0,0,255));
			//在多边形内部填充色蓝色
            else  
                putpixel(x1,y1,RGB(255,255,255));
             //在多边形外部填充色白色    
		}
	}     
} 
  
int main()
{ 
    int x[100],y[100];    
    int n;   //代表边的个数
    printf("请输入多边形边的个数: ");
    scanf("%d",&n);
    printf("\n请依次输入多边形每一个点的坐标:\n");
    scanf("%d%d",&x[0],&y[0]);
    maxx = x[0]; 
    minx = x[0];
    maxy = y[0];
    miny = y[0];
    for(int i = 1;i < n;i ++)
    {
        scanf("%d%d",&x[i],&y[i]);
        if(maxx < x[i])    //图形的边界
            maxx = x[i];
        if(minx > x[i])
            minx = x[i];
        if(maxy < y[i])
            maxy = y[i];
        if(miny > y[i])
            miny = y[i];
    }
    
     //图形初始化
    initgraph(800,800);
     //设置蓝背景
    setbkcolor(WHITE);
    cleardevice();
    
    for(int j = 1;j < n;j ++)
        dda(x[j - 1],y[j - 1],x[j],y[j]);
    dda(x[0],y[0],x[n-1],y[n-1]);
    putpixel(x[0],y[0],RGB(255,255,255));
	putpixel(x[n-1],y[n-1],RGB(255,255,255));
    filling(); //填充多边形
 
    getch(); 
    closegraph(); 
    return 0;
}
/*
100 100
700 100
700 500
600 400
400 600
300 200
200 300
*/
运行结果:


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值