c++ openGL利用贝塞尔曲线【Bézier curve】写汉字,seedfilling 填充算法

openGL利用贝塞尔曲线【Bézier curve】写汉字,seedfilling 填充算法

直接贴代码


#include <stack>
#include<GL\glut.h>
#include <iostream>

using namespace std;
#define drawed true
#define undraw false
#define width 498
#define height 444
GLubyte iPixel[3];
GLubyte borderColor[3]{0,0,0 };
GLubyte fillColor[3]{ 0,0,0 };
GLubyte bgColor[3]{255,255,255};
bool isDraw = 0;
struct Point
{
   int x;
   int y;
};


using namespace std;

int control_p[48][2] = {
   {146,13}, {163,9},  {178,8},  {197,4},
   {197,4},  {195,54}, {189,97}, {184,133},
   {184,133},{250,119},{403,97}, {385,113},
   {385,113},{331,162},{249,151},{182,164},
   {182,164},{180,175},{177,184},{173,196},
   {173,196},{330,332},{441,303},{494,440},
   {494,440},{330,386},{223,276},{168,216},
   {168,216},{117,332},{59,386}, {5,385},
   {5,385}, {86,314},{124,228},{140,166},
   {140,166}, {98,178},{15,201}, {14,183},
   {14,183}, {16,167},{102,151},{145,142},
   {145,142},{152,98}, {149,47}, {146,13} };
int xx, yy;//new point
int drag = 0;
int cps[2]{0};
int pos;
bool mouseDown = 0;


void glPoint(int x, int y, GLubyte fill[]) {
   glColor3ub(fill[0], fill[1],fill[2]);
   glPointSize(1);
   glBegin(GL_POINTS);
   glVertex2i(x, y);
   glEnd();   
   glFlush();
}
bool Issamecolor(GLubyte a[], GLubyte b[]) { //if same return 1 or return 0
   if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) {
   	return true;
   }
   else return false;
}

void seedFill(int startX, int startY, GLubyte fill_color[]) {
   stack<Point> pixelStack; 
   Point ortherP{ };
   Point tempPoint{};
   Point point = { startX,startY };
   pixelStack.push(point);
    
   //如果栈不为空
   while (!pixelStack.empty()) {
   	tempPoint = pixelStack.top(); 
   	pixelStack.pop();
   	glReadPixels(tempPoint.x, height - tempPoint.y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, iPixel);//pc=get (x,y) px;
   	if (!Issamecolor(iPixel, borderColor) && !Issamecolor(iPixel, fill_color)) {
   		glPoint(tempPoint.x, tempPoint.y, fill_color);
   		ortherP = { tempPoint .x-1,tempPoint .y};//left
   		pixelStack.push(ortherP);
   		ortherP = { tempPoint.x + 1,tempPoint.y };//right
   		pixelStack.push(ortherP);
   		ortherP = { tempPoint.x ,tempPoint.y-1};//up
   		pixelStack.push(ortherP);
   		ortherP = { tempPoint.x ,tempPoint.y+1 };//down
   		pixelStack.push(ortherP);
   	}
   }
}


void display() {
   glClear(GL_COLOR_BUFFER_BIT);
   if (drag == 1) //update the position of first control point
   {
   	control_p[pos][0] = xx; cout << "xx:    " << xx << endl;
   	control_p[pos][1] = yy; cout << "yy:    " << yy << endl;
   }
   glColor3f(0, 1, 0);//draw the line
   glBegin(GL_LINES); 
   for (int i = 0; i < 47; i++) {
   	glVertex2i(control_p[i][0], control_p[i][1]);
   	glVertex2i(control_p[i + 1][0], control_p[i + 1][1]);
   }
   glEnd();
   glPointSize(7); //draw big control points
   glBegin(GL_POINTS);
   for (int i = 0; i < 48;i+=4) {
   	glColor3f(0, 0.0, 0.0);
   	glVertex2iv(control_p[i]); glVertex2iv(control_p[i+3]);
   	glColor3f(0, 0.0, 1.0);
   	glVertex2iv(control_p[i +1]); glVertex2iv(control_p[i +2]);
   }
   glEnd();

   for (int i = 0; i < 48; i=i+4) // draw 12 bezier curve
   {
   	glBegin(GL_LINE_STRIP); //connect points to line
   	glColor3f(0, 0.0, 0.0);//绘图颜色黑色
   	for (float t = 0; t < 1.0000001; t = t + 0.01)
   	{
   		cps[0] =(float) control_p[i][0] * (1 - t) * (1 - t)* (1 - t) + 3 * (float)control_p[i+1][0] *
   			t * (1 - t) * (1 - t) + 3 * (float)control_p[i+2][0] * t * t * (1 - t) + (float)control_p[i + 3][0] * t * t * t;
   		cps[1] = (float)control_p[i][1] * (1 - t) * (1 - t)  * (1 - t) + 3 * (float)control_p[i + 1][1] *
   			t * (1 - t) * (1 - t) + 3 * (float)control_p[i + 2][1] * t * t * (1 - t) + (float)control_p[i + 3][1] * t * t * t;
   		glVertex2iv(cps);
   	}
   	glEnd();
   };
   seedFill(159, 40, bgColor);//先填bgcolor色
   seedFill(159, 40, fillColor);//再填fillcolor色
   drag = 0;//reset drag
}

void  mouse(int button, int state, int x, int y) {
   if (button == GLUT_LEFT_BUTTON) //left button 
   {
   	if (state == GLUT_DOWN)  //pressed down
   	{

   		for (int i = 0; i < 48; i++) // check each of the 48 control points 	
   		{
   			if (x > control_p[i][0] - 7 && x < control_p[i][0] + 7 && y >  control_p[i][1] - 7 && y < control_p[i][1] + 7) {
   				mouseDown = 1;// 空白位置乱按,鼠标不用变形        obtain the current position by(x, y)
   				pos = i;
   				//glutPostRedisplay(); //告诉display( ),there is updating,re draw it according to the new value	
   				cout << "mouse DOWN" << endl;
   				break;
   			}
   		}
   		
   	}
   	else if(state == GLUT_UP) {
   		if (mouseDown == 1) {
   			drag = 1;
   			xx = x;
   			yy = y;
   			cout << "mouse UP" << endl;
   		}
   	}
   	else {
   		drag = 0;

   	}//if not pressed,set drag=0, do not need a cross shape
   	 
   }
}

void motion(int x, int y) { // deal with the event of mouse move
   if (isDraw == undraw) {//first draw 
   	isDraw = drawed;
   	glutDisplayFunc(display);
   }
   else {
   	if (drag == 1)  // if it is in the drag mode
   	{
   		cout << "it will redisplay ,drag="<<drag<<endl;
   		glutPostRedisplay();
   	}
   }
}



void main(int arge, char** argv)
{
   glutInit(&arge, argv);

   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
   glutInitWindowPosition(200, 100); // Init position window
   glutInitWindowSize(width, height); //size of window
   glutCreateWindow("da"); // name of window
   //converse();
   glClearColor(1.0, 1.0, 1.0, 0); //设定背景白色
   

   glMatrixMode(GL_PROJECTION);//设定投影方式

   gluOrtho2D(0.0, width, height,0.0);

   
   
   glutMouseFunc(mouse);  //interaction of mouse button
   glutMotionFunc(motion); //mouse movement
   glutMainLoop();
   int a;
   std::cin >> a;
}
注: 注解和代码存在多种问题,有待修改,先挂起来。

引用

使用seedfilling算法 要使用C++的stack,感谢这位博主,参考了ta很多的内容。
OpenGL绘图实例三之种子填充算法.

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值