通过菜单完成曲线即曲面的绘制:
|
|
- Hermite曲线(三次)
- Bezier曲线(三次或四次)
- B样条曲线(二次或三次)
- Bezier曲面(双三次)
- 退出
|
|
#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;
}