OpenGL曲线绘制

通过菜单完成曲线即曲面的绘制:

  1. Hermite曲线(三次)
  2. Bezier曲线(三次或四次
  3. B样条曲线(二次或三次
  4. Bezier曲面(双三次)
  5. 退出

#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<math.h>
#include<Windows.h>
#include <iostream>
#include <cmath>
#include<stdio.h> //X86
#include<GL/glut.h>
#define PI 3.1415926
int yourselect;
///#include<time.h>
using namespace std;
float ctrlpoints[4][4][3] = {
	{{-280,  0,400},{-200, 20,200} ,{100,180,350},{355,340,-20}},
	{{-280,-35,350},{-200, 40,150},{160,150,290},{375,310,-70}},
	{{-270,-45,120},{-190, 90,160}, {200,100,210},{395,250,-100}},
	{{-300,-200,50} ,{-180,150,170},{275,94,190},{380,220,-200}},

};
void Init() {
	//glClearColor(0.3f, 0.3f, 0.3f, 0.0f);  //灰色
	glClearColor(1.0f, 0.97f, 0.86f, 0.0f);
	glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,&ctrlpoints[0][0][0]);
	glEnable(GL_MAP2_VERTEX_3);
}
void Reshape(int w, int h) {     /
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	glOrtho(-w / 2, w / 2, -h / 2, h / 2, -800, 800);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
//void circlefull(int xx, int yy,int zz, int r) {
//	int n = 1000;
//	glPointSize(3);
//	float st;
//	st = (2 * PI) / n;//角度转换为弧度
//	glBegin(GL_POINTS);
//	for (int i = 0; i <= r; i++) {
//		for (int j = 0; j < n; j++) {
//			glVertex3f(xx + i * cos(j * st), yy + i * sin(j * st),0);
//		}
//	}
//	glEnd();
//	glFlush();
//
//}
void circlenull(int xx, int yy, int zz, int r) {//不填充
	int n = 1000;
	glPointSize(3);
	float st;
	st = (2 * PI) / n;//角度转换为弧度
	glBegin(GL_LINES);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			glVertex3f(xx, yy, zz);
			glVertex3f(xx + r *sin(i*st)* cos(j * st), yy + r * sin(i * st)* sin(j * st), zz + r * cos(i* st));
		}
	}
	glEnd();
	glFlush();
}

void XY() {
	//gluLookAt(1, 1, 1, 0,0,0, 0, 1, 0);
	glLineWidth(1);
	//glColor3f(0.0, 0.0, 0.0);//坐标轴
	glColor3f(0.1, 0.1, 0.1);
	glBegin(GL_LINES);
	glVertex2i(-1000, 0);
	glVertex2i( 1000, 0);
	glVertex2i(0, -1000);
	glVertex2i(0,  1000);
	/*glVertex3i(0,0, -1000);
	glVertex3i(0,0, 1000);*/
	glEnd();
	glFlush();
}
void XYZ() {
	gluLookAt(-2,-2,2, 0,0,0, 0, 1, 0);
	glLineWidth(1);
	//glColor3f(0.0, 0.0, 0.0);//坐标轴
	glColor3f(0.1, 0.1, 0.1);
	glBegin(GL_LINES);
	glVertex3i(-1000, 0,0);
	glVertex3i(1000, 0,0);
	glVertex3i(0, -1000,0);
	glVertex3i(0, 1000,0);
	glVertex3i(0,0, -1000);
	glVertex3i(0,0, 1000);
	glEnd();
	glFlush();
}
int k = 1;
void Hermiteth(int *x,int *y) {

	//int z[4] = { 100,200,150,200 };

	int n = 20;
	double t, xx, yy, f0, f1, f2, f3;

	//glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(0.1, 0.1, 0.1);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < 4; i++) {
		glVertex2i(x[i], y[i]);
		//glVertex3f(x[i], y[i],z[i]);
	}
	glEnd();
	glFlush();
	Sleep(1000);

	glLineWidth(3);
	glColor3f(1.0, 0.5, 0.3);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < n; i++) {
		t = (float)i / n;
		f0 = 2 * pow(t, 3) - 3 * pow(t, 2) + 1;
		f1 = -2 * pow(t, 3) + 3 * pow(t, 2);
		f2 = pow(t, 3) - 2 * pow(t, 2) + t;
		f3 = pow(t, 3) - pow(t, 2);
		xx = x[1] * f0 + x[2] * f1 + (x[1] - x[0]) * f2 + (x[3] - x[2]) * f3;
		yy = y[1] * f0 + y[2] * f1 + (y[1] - y[0]) * f2 + (y[3] - y[2]) * f3;
		glVertex2d(xx, yy);
	}
	glEnd();
	glFlush();
}
void Bezierth(int* x,int *y) {
	
	int n = 20;
	double t, xx, yy;
	//glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(0.1, 0.1, 0.1);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < 4; i++) {
		glVertex2f(x[i],y[i]);
	}
	glEnd();
	glFlush();
	Sleep(1000);

	glLineWidth(3);
	glColor3f(1.0, 0.0, 0.0);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < n; i++) {
		t = (float)i / n;
		xx = x[0] * pow(1-t,3) + x[1] * pow(1-t,2) +3* x[2]*t*t*(1-t) + x[3]*pow(t,3);
		yy = y[0] * pow(1 - t, 3) + y[1] * pow(1 - t, 2) + 3 * y[2] * t * t * (1 - t) + y[3] * pow(t, 3);
		glVertex2d(xx, yy);
	}
	glEnd();
	glFlush();
}
void Bspline(int *xx,int * yy) {//B样条曲线 好用+++++++++++++++++
	int n = 10, m = 20;
	double t, x1, y1;
	glColor3f(0.1, 0.1, 0.1);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < n; i++) {
		glVertex2f(xx[i],yy[i]);
	}
	glEnd();
	glFlush();
	Sleep(200);
	glLineWidth(3);
	glColor3f(1.0, 0.0, 0.0);
	glBegin(GL_LINE_STRIP); 
	for (int i = 0; i < n-2; i++) {
		for (int j = 0; j < m; j++) {
			t = (float)j / m;
			x1 = 0.5 * (xx[i] * pow((1 - t), 2) + xx[i + 1] * (1 + 2 * t - 2 * t * t) + xx[i + 2] * t * t);
			y1 = 0.5 * (yy[i] * pow((1 - t), 2) + yy[i + 1] * (1 + 2 * t - 2 * t * t) + yy[i + 2] * t * t);
			glVertex2d(x1, y1);
		}
	}
	glEnd();
	glFlush();
}
void Bezierogee() { //Bezier曲面++++++++++++++++++++++++++++++++++++
	glColor3f(1.0, 0.0, 0.0);
	glRotatef(85, 1.0, 1.0, 1.0);
	glPushMatrix();//当前矩阵会被复制一份并压入栈中。这样,在之后的操作中,可以使用栈顶的矩阵进行变换,而不会影响之前的变换
	for (int i = 0; i < 20; i++) {
		glBegin(GL_LINE_LOOP);
		for (int j = 0; j < 20; j++) {
			glEvalCoord2f(j / 20.0, i /20.0);
		}
		glEnd();

		glBegin(GL_LINE_LOOP);
		for (int j = 0; j < 20; j++) {
			glEvalCoord2f(j / 20.0, i / 20.0);
		}
		glEnd();
	}
	glPopMatrix();
	glFlush();
	glDisable(GL_MAP2_VERTEX_3);
}
void improve(int* xx, int* yy) {//B样条guiji
	int n = 10, m = 20;
	double t, x1, y1;
	gluLookAt(0, 0, 2, 0, 0, 0, 0, 1, 0);
	//glBegin(GL_LINE_STRIP);
	//for (int i = 0; i < n; i++) {
	//	glVertex2f(xx[i], yy[i]);
	//}
	//glEnd();
	//glFlush();
	Sleep(10);
	//glLineWidth(3);
	/*glBegin(GL_LINE_STRIP);*/
	for (int i = 0; i < n - 2; i++) {
		for (int j = 0; j < m; j++) {
			t = (float)j / m;
			
			x1 = 0.5 * (xx[i] * pow((1 - t), 2) + xx[i + 1] * (1 + 2 * t - 2 * t * t) + xx[i + 2] * t * t);
			y1 = 0.5 * (yy[i] * pow((1 - t), 2) + yy[i + 1] * (1 + 2 * t - 2 * t * t) + yy[i + 2] * t * t);\
				//if (i % 2 == 0) {
					glColor3f(1.0, 0.0, 0.0);
				//}
				circlenull(50, x1, y1,-20);
				//else {
					glColor3f(0.1, 0.1, 0.1);
				//}
			    circlenull(50, x1, y1,-20);
			
		}
	}
	
}
void myDisplay() { /

	glLoadIdentity();
	XY();
	/*glBegin(GL_POLYGON); 
	glColor3f(1.0, 0.2, 0.2);
	glVertex2f(360, 380);
	glVertex2f(400, 380);
	glVertex2f(400, 400);
	glVertex2f(360, 400);
	glEnd();
	glFlush();*/

	glLineWidth(2);
	int x1[4] = { -350,-200,200,350 };
	int y1[4] = { 200,50,50,200 };

	int x2[4] = { -140,-110,-100,  0 };
	int y2[4] = { 140,-90,-150,-170 };

	int x3[10] = { -350,-300,-150, -70, 50, 25, 175, 220, 250,370 };
	int y3[10] = { -150,-250, -80, 380,350,280, 180,-250,-350,150 };
	if (yourselect == 1) {
		glColor3f(1.0, 0.5, 0.4);
		Hermiteth(x1,y1);
		//glFlush();
	}
	else if (yourselect == 2) {
		glColor3f(0.0, 0.5, 0.4);
		Bezierth(x2,y2);
	}
	else if (yourselect == 3) {
		//glLoadIdentity();
		//glColor3f(1.0, 0.5, 0.4);
		Bspline(x3,y3);
	//	//glTranslatef(50*k, 0, 0);//平移
	//	//glutWireSphere(100, 16, 16);
	}
	else if (yourselect == 4) {
		//glColor3f(1.0, 0.5, 0.4);
		XYZ();
		glColor3f(0.1, 0.1, 0.1);
		Bezierogee();
	/*	glScalef(1.5*k, 1.5*k, 1.5*k);
		glutWireSphere(100, 16, 16);*/
	}
	else if (yourselect == 5) {
		glColor3f(1.0, 0.5, 0.4);
		XYZ();
		improve(x3,y3);
		
	}
	else if(yourselect == 6) {
		exit('End');
		
	}
	
	glFlush();
	k++;
}

void menu(int menultem) {
	yourselect = menultem;
	glutPostRedisplay();
}
	int main(int argc, char* argv[])
	{
		glutInit(&argc, argv);
		glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
		glutInitWindowPosition(100, 100);
		glutInitWindowSize(800, 800);
		glutCreateWindow("the forth plus menu");

		int menuld = glutCreateMenu(menu);
		glutAddMenuEntry("Hermiteth", 1);
		glutAddMenuEntry("Bezierth", 2);
		glutAddMenuEntry("Bspline", 3);
		glutAddMenuEntry("Bezierogee", 4);
		glutAddMenuEntry("improve", 5);
		glutAddMenuEntry("End", 6);
		glutAttachMenu(GLUT_RIGHT_BUTTON);

		Init();
		glutReshapeFunc(Reshape);
		glutDisplayFunc(myDisplay);
		//glutMouseFunc(mouse_hit);
		glutMainLoop();
		return 0;
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值