综合图形学算法及OpenGL技术开发一个小型图形软件系统

开发一个图形软件包,具有画直线、曲线、曲面填充、几何变换、裁剪等功能:

(1)bresenham画线模块:

  void lineBres(int x0, int y0, int xEnd, int yEnd) {
  	int dx = fabs( xEnd - x0), dy = fabs( yEnd - y0);
  	float k = (float)dy / dx;// 斜率的绝对值
  	if(dx == 0) {
  		//如果斜率为零,可直接画直线
  	}
  //判断斜率是否为整
  	if(xEnd > x0 && yEnd > y0 || xEnd < x0 && yEnd < y0) {
    //斜率大于0
  		if(k < 1.0) {
      //设定开始点(x, y)和结束的上界xEnd	
  			//设定两个增量 twoDy = 2 * dy, twoDyMinusDx = 2 * ( dy - dx);
      //设定初始判定p
  			while(x < xEnd) {
  				//x加1
  				//根据p来绘制(x,y),并计算下一个判定p
  			}
  		}
  		else {
      斜率大于0的情况
  		}
  	}
  	else {
  //斜率小于0的情况
  }

(2)旋转模块:

  /*旋转(base_x, base_y)为旋转中心,angle为旋转角度*/
  void Rotation(const GLfloat base_x, const GLfloat base_y, const GLdouble angle) {
  	int i;
  	wcPoint newPoint;
  	for(i = 0; i < myImage.len; i++)  {
  		newPoint.x = base_x + (myImage.point[i].x - base_x) * cos(angle) - 	(myImage.point[i].y - base_y) * sin(angle);
  		newPoint.y = base_y + (myImage.point[i].x - base_x) * sin(angle) + 	(myImage.point[i].y - base_y) * cos(angle);
  		myImage.point[i].x = newPoint.x;
  		myImage.point[i].y = newPoint.y;
  	}
  }

(3)缩放模块:

  /*缩放 (base_x, base_y)为固定点*/
  void Scaling(const GLfloat base_x, const GLfloat base_y, const GLfloat Sx, const GLfloat Sy) 	{
  	for(int i = 0; i < myImage.len; i++)  {
  		myImage.point[i].x = myImage.point[i].x * Sx + base_x * (1 - Sx);
  		myImage.point[i].y = myImage.point[i].y * Sy + base_y * (1 - Sy);
  	}
  }

(4)平移模块:

  void Translation(const GLfloat direction_x, const GLfloat direction_y) {
  	for(int i = 0; i < myImage.len; i++)  {
  		myImage.point[i].x = myImage.point[i].x + direction_x;
  		myImage.point[i].y = myImage.point[i].y + direction_y;
  	}
}

(5)种子填充模块:

  void boundaryFill4(int x, int y, float *fillColor, float *borderColor) {
  	float interiorColor[3];
  	getPixel(x, y, interiorColor);
  	glColor3fv(fillColor);
  	if(!colorEqual(interiorColor, fillColor) && !colorEqual(interiorColor, borderColor)) {
  		setPixel(x, y);
  		boundaryFill4(x + 1, y, fillColor, borderColor);
  		boundaryFill4(x - 1, y, fillColor, borderColor);
  		boundaryFill4(x, y + 1, fillColor, borderColor);
  		boundaryFill4(x, y - 1, fillColor, borderColor);
  	}
  	return ;
  }

(6)Cohen-Sutherland线段裁剪模块:

  void lineClipCohSuth(wcPoint winMin, wcPoint winMax, wcPoint &p1, wcPoint &p2) {
  	GLubyte code1, code2;
  	GLint done = false, plotLine = false;
  	GLfloat m;
  
  	while(!done) {
  		code1 = encode(p1, winMin, winMax);
  		code2 = encode(p2, winMin, winMax);
  		if(accept(code1, code2)) {
  			done = true;
  			plotLine = true;
  		}
  		else
  			if(reject(code1, code2))
  				done = true;
  			else {
  				if(inside(code1)) {
  					swapPts(&p1, &p2);
  					swapCodes(&code1, &code2);
  				}
  				if(p2.x != p1.x)
  					m = (p2.y - p1.y) / (p2.x - p1.x);
  				if(code1 & winLeftBitCode){
  					p1.y += (winMin.x - p1.x) * m;
  					p1.x = winMin.x;
  				}
  				else
  					if(code1 & winRightBitCode){
  						p1.y += (winMax.x - p1.x) * m;
  						p1.x = winMax.x;
  					}else
  						if(code1 & winBottomBitCode) {
  							if(p2.x != p1.x)
  								p1.x += (winMin.y - p1.y) / m;
  							p1.y = winMin.y;
  						}else
  							if(code1 & winTopBitCode) {
  								if(p2.x != p1.x)
  									p1.x += (winMax.y - p1.y) / m;
  								p1.y = winMax.y;
  							}
  			}
  	}
  	if(plotLine)
  		glutPostRedisplay();
  }

Sutherland-Hodgman多边形裁剪:

  wcPoint intersect(wcPoint p1, wcPoint p2, Boundary winEdge, wcPoint wMin, wcPoint 	wMax) {
  	wcPoint iPt;
  	GLfloat m;
  	if(p1.x != p2.x)
  		m = (p1.y - p2.y) / (p1.x - p2.x);
  	switch(winEdge) {
  	case Left:
  		iPt.x = wMin.x;
  		iPt.y = p2.y + (wMin.x - p2.x) * m;
  		break;
  	case Right:
  		iPt.x = wMax.x;
  		iPt.y = p2.y + (wMax.x - p2.x) * m;
  		break;
  	case Bottom:
  		iPt.y = wMin.y;
  		if(p1.x != p2.x)
  			iPt.x = p2.x + (wMin.y - p2.y) / m;
  		else
  			iPt.x = p2.x;
  		break;
  	case Top:
  		iPt.y = wMax.y;
  		if(p1.x != p2.x)
  			iPt.x = p2.x + (wMax.y - p2.y) / m;
  		else
  			iPt.x = p2.x;
  		break;
  	}
  	return iPt;
  }
  
  void clipPoint(wcPoint &p, Boundary winEdge, wcPoint wMin, wcPoint wMax,
  			   wcPoint *pOut, int *cnt, wcPoint *first[], wcPoint *s) {
  	wcPoint iPt;
  	if(!first[winEdge])
  		first[winEdge] = &p;
  	else
  		if(cross(p, s[winEdge], winEdge, wMin, wMax)) {
  			iPt = intersect(p, s[winEdge], winEdge, wMin, wMax);
  			if(winEdge < Top)
  				clipPoint(iPt, (Boundary)(winEdge + 1), wMin, wMax, pOut, cnt, first, s);
  			else {
  				pOut[*cnt] = iPt;
  				(*cnt)++;
  			}
  		}
  	s[winEdge] = p;
  	if(inside(p, winEdge, wMin, wMax))
  		if(winEdge < Top)
  			clipPoint(p, (Boundary)(winEdge + 1), wMin, wMax, pOut, cnt, first, s);
  		else {
  			pOut[*cnt] = p;
  			(*cnt)++;
  		}
  }
  
  void closeClip(wcPoint wMin, wcPoint wMax,
  			   wcPoint *pOut, int *cnt, wcPoint *first[], wcPoint *s) {
  	wcPoint pt;
  	Boundary winEdge;
  
  	for(int i = 0; i <= Top; i++) {
  		winEdge = (Boundary)i;
  		if(cross(s[winEdge], *first[winEdge], winEdge, wMin, wMax)){
  			pt = intersect(s[winEdge], *first[winEdge], winEdge, wMin, wMax);
  			if(winEdge < Top)
  				clipPoint(pt, (Boundary)(winEdge + 1), wMin, wMax, pOut, cnt, first, s);
  			else {
  				pOut[*cnt] = pt;
  				(*cnt)++;
  			}
  		}
  	}
  }
  
  GLint ploygonClipSuthHodg(wcPoint wMin, wcPoint wMax, GLint n, wcPoint *pIn, wcPoint *pOut) {
  	wcPoint* first[nClip] = {0, 0, 0, 0}, s[nClip];
  	GLint k, cnt = 0;
  	for(k = 0; k < n; k++) 
  		clipPoint(pIn[k], Left, wMin, wMax, pOut, &cnt, first, s);
  	closeClip(wMin, wMax, pOut, &cnt, first, s);
  	return cnt;
  }

(8)Bezier 曲线:

  void bezier(wcPoint *ctrlPts, GLint nCtrlPts, GLint nBezCurvePts) {
  	wcPoint bezCurvePt;
  	GLfloat u;
  	GLint *C, k;
  
  	C = new GLint[nCtrlPts];
  
  	binomialCoeffs(nCtrlPts - 1, C);
  
  	for(k = 0; k <= nBezCurvePts; k++) {
  		u = GLfloat(k) / GLfloat(nBezCurvePts);
  		computeBezPt(u, &bezCurvePt, nCtrlPts, ctrlPts, C);
  		plotPoint(bezCurvePt);
  	}
  	delete [] C;
  }
  
  


(9)2B样条曲线

  void BSplint2(wcPoint *ctrlPts, GLint nCtrlPts, GLint nBezCurvePts) {
  	wcPoint bezCurvePt;
  	for(int i = 0; i < nCtrlPts - 2; i++) {
  		for(int j = 0; j < nBezCurvePts; j++) {
  			float t = (float)j / nBezCurvePts;
  			float _t = 1.0f - t;
  			float B0 = _t * _t / 2.0f;
  			float B1 = (1 + 2 * t - 2 * t * t) / 2.0f ;
  			float B2 = (t * t) / 2.0f;
  			bezCurvePt.x = ctrlPts[i].x * B0 + ctrlPts[i + 1].x * B1 +  ctrlPts[i + 2].x * B2;
  			bezCurvePt.y = ctrlPts[i].y * B0 + ctrlPts[i + 1].y * B1 +  ctrlPts[i + 2].y * B2;
  			plotPoint(bezCurvePt);
  		}
  	}
  }

(10)3B样条曲线-:

  void BSplint3(wcPoint *ctrlPts, GLint nCtrlPts, GLint nBezCurvePts) {
  	wcPoint bezCurvePt;
  	for(int i = 0; i < nCtrlPts - 3; i++) {
  		for(int j = 0; j < nBezCurvePts; j++) {
  			float t = (float)j / nBezCurvePts;
  			float _t = 1.0f - t;
  			float tt = t * t;
  			float ttt = t * t * t;
  			float B0 = _t * _t / 6.0f;
  			float B1 = (3 * ttt - 6 * tt + 4) / 6.0f ;
  			float B2 = (3 * tt - 3 * ttt + 3 * t + 1) / 6.0f;
  			float B3 = ttt / 6.0f;
  			bezCurvePt.x = ctrlPts[i].x * B0 + ctrlPts[i + 1].x * B1 +  ctrlPts[i + 2].x * B2 + ctrlPts[i + 3].x * B3;
  			bezCurvePt.y = ctrlPts[i].y * B0 + ctrlPts[i + 1].y * B1 +  ctrlPts[i + 2].y * B2 + ctrlPts[i + 3].y * B3;
  			plotPoint(bezCurvePt);
  		}
  	}
  }


(11)主程序模块:

  int main(int argc, char **argv) {
  	
  	GLint colorMenu, rotationMenu, scalingMenu, drawMenu, fillColorMenu, clipMenu, dragPointMenu;
  
  	glutInit(&argc, argv);
  	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  	glutInitWindowPosition(200, 200);
  	glutInitWindowSize(winWidth, winHeight);
  	glutCreateWindow("graphics");
  
  	init();
  	glutDisplayFunc(displayImage);
  	glutMouseFunc(mousePtPlot);
  	glutMotionFunc(mouseDrag);//鼠标按键并移动
  //添加各个子菜单
  	glutAttachMenu(GLUT_RIGHT_BUTTON);
  	glutReshapeFunc(reshapeFcn);
  
  	glutMainLoop();
  	return 0;
  }

五、实验结果及分析


源码:http://download.csdn.net/detail/shinnseed/6870887

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值