OpenGl使用中点画线法画出自己名字,使用种子算法进行填充

-

简介

  • 这是自己计算机图形老师布置的一个简单的上机作业,叫我们把自己名字里的字扣出空心区域,然后进行填充
  • 大致看了一下,好像没有这方面的文章,所以我来写一篇,给那些有类似题目的提供一下我的思路
  • 主要使用的是 OpenGL中点画线法种子填充法

具体思路

  • 首先先把所有的点给确定下来,因为中点画线法只能够画两点之间的线条
  • 确定点坐标的过程很繁琐,你需要一个点一个点的确定
  • 然后区域围成之后就可以使用种子填充了
  • 在使用种子填充的时候注意一下对边界的判断
  • 我的办法是在画点的时候就把该点置为 1,表示该点被使用过了

MyCode

  • 话不多说,直接上代码
#include <GL/glut.h> 
#include<math.h>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>

using namespace std;

class Point {
public:
	Point(int  _x, int _y) {
		x = _x;
		y = _y;
	}
	int x, y;
};



double x00, y00, x11, y11;


int flag[2021][2021] = {0};


void Flood (int a, int b) {
	

	int dx[4] = { -1, 0, 1, 0 };
	int dy[4] = { 0, -1, 0, 1 };

	stack<Point> q;
	//queue<Point> q;
	q.push(Point(a, b));

	flag[a + 1000][b + 1000] = 1;

	while (q.size()) {
		auto t = q.top();
		//auto t = q.front();
		q.pop();

		for (int i = 0; i < 4; i++) {

			int n = t.x + dx[i];
			int m = t.y + dy[i];
			cout << m << n << endl;

			if (n < -1000 || n > 1000 || m < -1000 || m >= 1000) continue;

			if (flag[n + 1000][m + 1000]) continue;
			
			flag[n + 1000][m + 1000] = 1;
			glBegin(GL_POINTS);
			glColor3f(1, 0, 0);
			glVertex2f((double)n / 1000, (double)m / 1000);
			glEnd();
			q.push(Point(n, m));
			glFlush();
		}
	}

}

void MidPoint() {
	vector<Point> line;

	//第一部分连接点
	line.push_back(Point(100, 500));
	line.push_back(Point(150, 500));

	line.push_back(Point(0, 100));
	line.push_back(Point(100, 500));

	line.push_back(Point(0, 100));
	line.push_back(Point(50, 100));

	line.push_back(Point(130, 420));
	line.push_back(Point(150, 500));

	line.push_back(Point(50, 100));
	line.push_back(Point(100, 300));

	line.push_back(Point(130, 420));
	line.push_back(Point(240, 420));

	line.push_back(Point(100, 300));
	line.push_back(Point(240, 300));

	line.push_back(Point(240, 420));
	line.push_back(Point(240, 300));

	//第二部分连接点
	line.push_back(Point(100, 200));
	line.push_back(Point(100, 250));

	line.push_back(Point(100, 150));
	line.push_back(Point(100, 100));

	line.push_back(Point(100, 250));
	line.push_back(Point(240, 250));

	line.push_back(Point(240, 250));
	line.push_back(Point(240, 200));

	line.push_back(Point(100, 200));
	line.push_back(Point(140, 200));

	line.push_back(Point(200, 200));
	line.push_back(Point(240, 200));

	line.push_back(Point(140, 200));
	line.push_back(Point(140, 150));

	line.push_back(Point(100, 150));
	line.push_back(Point(140, 150));

	line.push_back(Point(200, 200));
	line.push_back(Point(200, 150));

	line.push_back(Point(200, 150));
	line.push_back(Point(240, 150));

	line.push_back(Point(240, 150));
	line.push_back(Point(240, 100));

	line.push_back(Point(100, 100));
	line.push_back(Point(140, 100));

	line.push_back(Point(200, 100));
	line.push_back(Point(240, 100));

	line.push_back(Point(140, 100));
	line.push_back(Point(140, -100));

	line.push_back(Point(200, 100));
	line.push_back(Point(200, -10));

	line.push_back(Point(200, -10));
	line.push_back(Point(240, 10));

	line.push_back(Point(140, -100));
	line.push_back(Point(300, -20));

	line.push_back(Point(240, 10));
	line.push_back(Point(300, -20));
	
	//第三部分连接点
	line.push_back(Point(400, 500));
	line.push_back(Point(450, 500));

	line.push_back(Point(300, 250));
	line.push_back(Point(400, 500));

	line.push_back(Point(300, 250));
	line.push_back(Point(350, 250));

	line.push_back(Point(350, 250));
	line.push_back(Point(370, 300));

	line.push_back(Point(430, 450));
	line.push_back(Point(450, 500));

	line.push_back(Point(430, 450));
	line.push_back(Point(700, 450));

	line.push_back(Point(390, 350));
	line.push_back(Point(410, 400));

	line.push_back(Point(410, 400));
	line.push_back(Point(600, 350));

	line.push_back(Point(560, 250));
	line.push_back(Point(600, 350));

	line.push_back(Point(390, 350));
	line.push_back(Point(560, 250));

	line.push_back(Point(370, 300));
	line.push_back(Point(520, 150));

	line.push_back(Point(400, 100));
	line.push_back(Point(520, 150));

	line.push_back(Point(400, 100));
	line.push_back(Point(500, -50));

	line.push_back(Point(500, -50));
	line.push_back(Point(580, 150));

	line.push_back(Point(620, 250));
	line.push_back(Point(700, 450));

	line.push_back(Point(580, 150));
	line.push_back(Point(580, -100));

	line.push_back(Point(620, 250));
	line.push_back(Point(770, 250));

	line.push_back(Point(770, 250));
	line.push_back(Point(770, -100));

	line.push_back(Point(580, -100));
	line.push_back(Point(770, -100));

	line.push_back(Point(620, 200));
	line.push_back(Point(740, 200));

	line.push_back(Point(740, 200));
	line.push_back(Point(740, -50));

	line.push_back(Point(620, -50));
	line.push_back(Point(740, -50));
	
	line.push_back(Point(620, -50));
	line.push_back(Point(620, 200));

	


	for (int i = 0; i < line.size() - 1; i += 2) {
		x00 = line[i].x;
		y00 = line[i].y;
		x11 = line[i + 1].x;
		y11 = line[i + 1].y;
		
	

		double A = y00 - y11;
		double B = x11 - x00;
		double k = -1 * (A / B);
		

		double  x, y,t;

		double d;

		//保留之前画的线条,所以把这行代码注释掉
		//glClear(GL_COLOR_BUFFER_BIT);

		if (x11 < x00) {
			t = x11;
			x11 = x00;
			x00 = t;
			t = y11;
			y11 = y00;
			y00 = t;
		}

		if (k >= 0 && k <= 1) {
			d = (2 * A + B);
			x = x00;
			y = y00;
			while (x != x11) {
				glBegin(GL_POINTS);
				glColor3f(0, 1, 1);
				glVertex2f(x / 1000, y / 1000);
				flag[(int)(x + 1000)][(int)(y + 1000)] = 1;
				glEnd();
				if (d <= 0) {
					x += 1;
					y += 1;
					d += (2 * (A + B));
				}
				else {
					x++;
					d += (2 * A);
				}
				glFlush();
			}
		}
		if (k > 1) {
			d = (A + 2 * B);
			x = x00;
			y = y00;
			while (y != y11) {
				glBegin(GL_POINTS);
				glColor3f(0, 1, 1);
				glVertex2f(x / 1000, y / 1000);
				flag[(int)(x + 1000)][(int)(y + 1000)] = 1;
				glEnd();
				if (d < 0) {
					y += 1;
					d += (2 * B);
				}
				else {
					y += 1;
					x += 1;
					d += (2 * (A + B));
				}
				glFlush();
			}

		}
		if (k >= -1 && k < 0) {
			d = (2 * A - B);
			x = x00;
			y = y00;
			while (x != x11) {
				glBegin(GL_POINTS);
				glColor3f(0, 1, 1);
				glVertex2f(x / 1000, y / 1000);
				flag[(int)(x + 1000)][(int)(y + 1000)] = 1;
				glEnd();
				if (d < 0) {
					x += 1;
					d += (2 * A);
				}
				else {
					x += 1;
					y -= 1;
					d += (2 * (A - B));
				}
				glFlush();
			}

		}
		if (k < -1) {
			d = (int)(A - 2 * B);
			x = x00;
			y = y00;
			while (y != y11) {
				glBegin(GL_POINTS);
				glColor3f(0, 1, 1);
				glVertex2f(x / 1000, y / 1000);
				flag[(int)(x + 1000)][(int)(y + 1000)] = 1;
				glEnd();
				if (d < 0) {
					y -= 1;
					x += 1;
					d += (2 * (A - B));
				}
				else {
					y -= 1;
					d -= (2 * B);
				}
				glFlush();
			}
		}
		//cout << i << endl;
	}
	Flood(25, 102);
	Flood(141, 90);
	Flood(521, 151);
}

void display() {
	MidPoint();
}

int main(int argc, char** argv) {

	glutInit(&argc, argv); //初始化glut
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);//设置窗口的模式-深度缓存,单缓存,颜色模型
	glutInitWindowPosition(200, 200); //设置窗口的位置
	
	glutInitWindowSize(500, 500); //设置窗口的大小
	glutCreateWindow("对名字进行填充"); //创建窗口并赋予title

	glutDisplayFunc(display);

	glutMainLoop(); //进入循环等待

	return 0;
}


运行结果

在这里插入图片描述在这里插入图片描述

注意事项

  • glVertex2f(x / 1000, y / 1000);xy不能是 int类型的
  • 在种子算法的填充中,使用queuestack都是可以的,但是queue的填充过程更好看一点
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值