zoukankan      html  css  js  c++  java
  • 计算机图形学3——Boundary-Fill Algorithm

    图形学实验:边界填充多边形算法

    算法原理如下:
    种子像素入栈,当栈非空时重复执行如下三步操作:

    (1)栈顶像素出栈
    (2)将出栈像素置成要填充色
    (3)按左、上、右、下顺序检查与栈像素相邻的四个像素,若其中某个像素不在边界且未置成填充色,则把该像素入栈

    核心代码如下:

    void Boundaryfill (int seedx,int seedy)
    {
    	CMyStack stk1;
        long color=RGB(255,0,0); //填充颜色 red
    	long boundary_color=RGB(255,255,255); //边界颜色 white
    	unsigned char params[4]; //保存读取的一个像素点的颜色值
    	dcpt p1;
        p1.x=seedx;
    	p1.y=seedy;
    
    	stk1.push(p1);
    	while(!stk1.isEmpty())
        {
            int next[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
            p1=stk1.gettop();
            stk1.pop();
    
            glColor3f(1,0,0);
            glBegin(GL_POINTS);
                glVertex2i(p1.x,p1.y);
            glEnd();
    
            for(int i=0;i<4;i++)
            {
                int tx=p1.x+next[i][0];
                int ty=p1.y+next[i][1];
                glReadPixels(tx,ty,1,1,GL_RGBA,GL_UNSIGNED_BYTE,params);
                long c1=RGB(params[0],params[1],params[2]);
                if(c1==color||c1==boundary_color)
                    continue;
                dcpt p2;
                p2.x=tx;
                p2.y=ty;
                stk1.push(p2);
            }
        }
    }
    

    MyStack.h(类声明文件)如下:

    // MyStack.h: interface for the MyStack class.
    #if !defined(AFX_MySTACK_H__3657DC2D_E518_4E5E_9A32_023B2A260ED7__INCLUDED_)
    #define AFX_MySTACK_H__3657DC2D_E518_4E5E_9A32_023B2A260ED7__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #include <windows.h>
    #include <GL/glut.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    
    struct dcpt
    {
    	int x;
    	int y;
    };
    
    struct pointStruct
    {
    	dcpt point;
    	pointStruct * pNext;
    };
    
    class CMyStack
    {
    public:
        CMyStack();
        virtual ~CMyStack();
        BOOL pop();
        void push(dcpt pt);
        void empty();
        dcpt gettop();
        BOOL isEmpty();
    private:
        pointStruct *pHead;
        pointStruct *p1;
        pointStruct *pTop;
    
    };
    #endif // !defined(AFX_MySTACK_H__3657DC2D_E518_4E5E_9A32_023B2A260ED7__INCLUDED_)
    

    MyStack.cpp(类实现文件)如下:

    // MyStack.cpp: implementation of the MyStack class.
    #include "MyStack.h"
    CMyStack::CMyStack()
    {
    
        pHead=new pointStruct;
        p1=pTop=pHead;
        pHead->pNext=NULL;
    }
    CMyStack::~CMyStack()
    {
        while(pTop!=NULL)
        {
            p1=pTop;
            pTop=pTop->pNext;
            delete p1;
        }
    }
    
    BOOL CMyStack::pop()
    {
        if(pTop==pHead)
            return 0;
        p1=pTop;
        pTop=pTop->pNext;
        delete p1;
        return 1;
    }
    
    void CMyStack::push(dcpt pt)
    {
        p1=new pointStruct;
        p1->point=pt;
        p1->pNext=pTop;
        pTop=p1;
    }
    
    void CMyStack::empty()
    {
        while(pTop!=NULL)
        {
            p1=pTop;
            pTop=pTop->pNext;
            delete p1;
        }
    
    }
    
    dcpt CMyStack::gettop()
    {
        return pTop->point;
    }
    
    BOOL CMyStack::isEmpty()
    {
    
        if(pTop==pHead)
            return 1;
        return 0;
    }
    
    

    main.cpp(类使用)如下:

    // ====== Computer Graphics Experiment #3 ======
    // |          Boundary-Fill Algorithm          |
    // =============================================
    //
    // Requirement:
    //	Implement Boundary-Fill algorithm to fill polygon.
    
    
    #include "MyStack.h"
    #define WINDOW_HEIGHT 400
    
    void Boundaryfill (int seedx,int seedy)
    {
    	CMyStack stk1;
        long color=RGB(255,0,0); //填充颜色 red
    	long boundary_color=RGB(255,255,255); //边界颜色 white
    	unsigned char params[4]; //保存读取的一个像素点的颜色值
    	dcpt p1;
        p1.x=seedx;
    	p1.y=seedy;
    
    	stk1.push(p1);
    	while(!stk1.isEmpty())
        {
            int next[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
            p1=stk1.gettop();
            stk1.pop();
    
            glColor3f(1,0,0);
            glBegin(GL_POINTS);
                glVertex2i(p1.x,p1.y);
            glEnd();
    
            for(int i=0;i<4;i++)
            {
                int tx=p1.x+next[i][0];
                int ty=p1.y+next[i][1];
                glReadPixels(tx,ty,1,1,GL_RGBA,GL_UNSIGNED_BYTE,params);
                long c1=RGB(params[0],params[1],params[2]);
                if(c1==color||c1==boundary_color)
                    continue;
                dcpt p2;
                p2.x=tx;
                p2.y=ty;
                stk1.push(p2);
            }
        }
    }
    
    void MyPolygonFill(int n, dcpt *vertices)
    // n --- Number of vertices
    // vertices --- vertex coordinates
    {
    	int max=vertices[0].x;
    	int mix=vertices[0].x;
    	int may=vertices[0].y;
    	int miy=vertices[0].y;
    	glColor3f(1.0, 1.0, 1.0);
    	glBegin (GL_LINE_LOOP);
    	for (int i=0;i<n;i++)
    	{
    		glVertex2i(vertices[i].x,vertices[i].y);
    		if (vertices[i].x>max)
    			max=vertices[i].x;
    		if (vertices[i].x<mix)
    			mix=vertices[i].x;
    		if (vertices[i].y>may)
    			may=vertices[i].y;
    		if (vertices[i].y<miy)
    			miy=vertices[i].y;
    	}
        glEnd();
        int sx=(max+mix)/2;
    	int sy=(may+miy)/2;
    	Boundaryfill(sx,sy);
    
    }
    
    // Initialization function
    void init(void)
    {
    	glClearColor (0.0, 0.0, 0.0, 0.0);
        glPixelStorei(GL_PACK_ALIGNMENT, 1);
    }
    
    // Display callback function
    void display(void)
    {
    	static dcpt v[4];
    	v[0].x = 260, v[0].y = 150;
    	v[1].x = 281, v[1].y = 200;
    	v[2].x = 340, v[2].y = 230;
    	v[3].x = 370, v[3].y = 150;
    
    	glClear(GL_COLOR_BUFFER_BIT);
    
    	MyPolygonFill(4, v);
    
    	glFlush();
    }
    
    // Reshape callback function
    void reshape(int w, int h)
    {
    	glViewport (0, 0, w, h);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluOrtho2D(0, w, 0, h);
    }
    
    // Keyboard callback function
    void keyboard(unsigned char key, int x, int y)
    {
    	switch (key) {
    		case 27: exit(0);
    	}
    }
    
    // Main program entrance
    int main(int argc, char* argv[])
    {
    	glutInit(&argc, argv);
    	glutInitDisplayMode (GLUT_RGB);
    	glutInitWindowSize (650, 400);
    	glutInitWindowPosition (50, 100);
    	glutCreateWindow ("Polygon Fill");
    	init ();
    	glutDisplayFunc(display);
    	glutReshapeFunc(reshape);
    	glutKeyboardFunc(keyboard);
    	glutMainLoop();
    	return 0;
    }
    
    
  • 相关阅读:
    webpack 3.X学习之CSS处理
    webpack 3.X学习之图片处理
    webpack 3.X学习之基本配置
    webpack 3.X学习之JS压缩与打包HTML文件
    webpack 3.X学习之初始构建
    【复习】VueJS之内部指令
    前端学习记录之Javascript-DOM
    javascript常用的Math对象的方法
    nodejs+mongoose+websocket搭建xxx聊天室
    Markdown常用语法
  • 原文地址:https://www.cnblogs.com/vivid-victory/p/10090463.html
Copyright © 2011-2022 走看看