节点向量 𝑼 = 𝟎, 𝟎, 𝟎, 𝟎, 𝟎. 𝟐, 𝟎. 𝟒, 𝟎. 𝟔, 𝟎. 𝟖, 𝟎. 𝟖, 𝟎. 𝟖, 𝟏, 𝟏, 𝟏, 𝟏 𝑽 = {𝟎, 𝟎, 𝟎, 𝟎, 𝟎. 𝟐, 𝟎. 𝟐, 𝟎. 𝟐, 𝟎. 𝟒, 𝟎. 𝟔, 𝟎. 𝟖, 𝟏, 𝟏, 𝟏, 𝟏} 绘制张量积基函数N0,3 𝑢 ∙ N0,3 𝑣 ,
// ConsoleApplication4.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
// 作业第二问:修改函数cal,basicFun
// 修改参数cal(begin,end,t) basicFun(t,i,k)
#include<gl/glut.h>
#include<GL/GL.h>
#include<math.h>
#include <cmath>
#include <iostream>
GLfloat list[21][21][3];
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
GLfloat function03(GLfloat u)
{
return (1 - u * u * u);
}
static GLfloat knot[6] = {0,0,0,0,0.2,0.4};
GLfloat basisFun(GLfloat t, GLint i, GLint k, GLfloat* knot)
{
GLfloat value1, value2, value;
if (k == 0)
{
if (t >= knot[i] && t < knot[i + 1])
return 1.0;
else
return 0.0;
}
if (k > 0)
{
if (t<knot[i] || t>knot[i + k + 1])
return 0.0;
else
{
GLfloat coffcient1, coffcient2; //凸组合系数
GLfloat denominator = 0.0;
denominator = knot[i + k] - knot[i]; //第一项分母
if (denominator == 0.0)
coffcient1 = 0.0; // 0/0 = 0
else
coffcient1 = (t - knot[i] )/ denominator; //F(i,k-1)(t)
denominator = knot[i + k + 1] - knot[i + 1]; //第二项分母
if (denominator == 0.0)
coffcient2 = 0.0; // 0/0=0
else
coffcient2 = (knot[i + k + 1] - t) / denominator; //F(i+1,k-1)(t)
value1 = coffcient1 * basisFun(t, i, k - 1, knot); //递推公式第一项
value2 = coffcient2 * basisFun(t, i + 1, k - 1, knot); //递推公式第二项
value = value1 + value2;
}
}
return value;
}
//0.0 ~ 1.0
void cal(GLfloat begin,GLfloat end,GLfloat len)
{
int j = 0;
for (GLfloat v = begin; v<= end+len/10;v+= len) {
int i = 0;
for (GLfloat u = begin; u <= end+len/10;u+=len) {
list[j][i][0] = u;
list[j][i][1] = v;
list[j][i][2] = 0.2*basisFun(u,0,3,knot)*basisFun(v, 0, 3, knot);
i++;
}
j++;
}
}
void displayBox()
{
GLfloat Box[8][3] = { {0.0,0.0,0.0},{0.2,0.0,0.0},{0.2,0.2,0.0},{0.0,0.2,0.0},
{0.0,0.0,0.2},{0.2,0.0,0.2},{0.2,0.2,0.2},{0.0,0.2,0.2} };
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POINTS);
for (int num = 0; num < 8; num++) {
glVertex3fv(&Box[num][0]);
}
glEnd();
glColor4f(1.0, 0.0, 0.0,0.5);
glBegin(GL_LINE_STRIP);
for (int down = 0; down < 4; down++) {
glVertex3fv(&Box[down][0]);
}
glVertex3fv(&Box[0][0]); //close down_face of the box
glEnd();
glBegin(GL_LINE_STRIP);
for (int up = 4; up < 8; up++) {
glVertex3fv(&Box[up][0]);
}
glVertex3fv(&Box[4][0]); //close up_face of the box
glEnd();
for (int i = 0; i < 4; i++) {
glBegin(GL_LINE_STRIP);
glVertex3fv(&Box[i][0]);
glVertex3fv(&Box[i+4][0]);
glEnd();
}
/*
///
glBegin(GL_POLYGON);
for (int i = 0; i < 21; i++) {
for (int j = 0; j < 21; j++) {
glVertex3fv(&list[i][j][0]);
}
}
/*/
}
void display()
{
// 保存矩阵状态并进行旋转
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
//
glClearColor(1.0, 1.00, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
//glMatrixMode(GL_PROJECTION);
//gluOrtho2D(-0.5,1.5 ,-0.5,1.5);
//glBegin(GL_TRIANGLES);
glPointSize(1);
glColor3f(0.0, 0.0, 0.0);
GLfloat x, y, z;
for (int j = 0; j < 21; j++) {
for (int i = 0; i < 21; i++) {
x = list[j][i][0];
y = list[j][i][1];
z = list[j][i][2];
glBegin(GL_POINTS);
glVertex3f(x, y, z);
glEnd();
}
}
glColor3f(0.39, 0.58, 0.93);
for (int i = 0; i < 21; i++) {
glBegin(GL_LINE_STRIP);
for (int j = 0; j < 21; j++) {
glVertex3fv(&list[i][j][0]);
}
glEnd();
}
glColor3f(0.39, 0.58, 0.93);
for (int i = 0; i < 21; i++) {
glBegin(GL_LINE_STRIP);
for (int j = 0; j <21; j++) {
glVertex3fv(&list[j][i][0]);
}
glEnd();
}
//
displayBox();
// 恢复变换
glPopMatrix();
// 刷新绘图命令
glutSwapBuffers();
//glColor3f(0.39, 0.58, 0.93);
//glBegin(GL_LINE_STRIP);
//for (int j = 0; j < 6; j++) {
// for (int i = 0; i < 6; i++) {
// for (int k = 0; k < 3; k++) {
// glVertex3fv(&list[j][i][k]);
// }
// }
//}
glFlush();
}
// 键盘箭头键控制旋转图形
void SpecialKeys(int key, int x, int y)
{
if (key == GLUT_KEY_UP)
xRot -= 5.0f;
if (key == GLUT_KEY_DOWN)
xRot += 5.0f;
if (key == GLUT_KEY_LEFT)
yRot -= 5.0f;
if (key == GLUT_KEY_RIGHT)
yRot += 5.0f;
if (key > 356.0f)
xRot = 0.0f;
if (key < -1.0f)
xRot = 355.0f;
if (key > 356.0f)
yRot = 0.0f;
if (key < -1.0f)
yRot = 355.0f;
// 刷新窗口
glutPostRedisplay();
}
// 修改可视区域的视口,当窗口改变时被调用
void ChangeSize(int w, int h)
{
GLfloat nRange = 1.0f;
// 防止被0除
if (h == 0)
h = 1;
// 将视口设置为窗口尺寸
glViewport(0, 0, w, h);
// 重置投影矩阵堆栈
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//建立裁剪区(左,右,下,上,近,远)
if (w <= h)
glOrtho(-nRange, nRange, -nRange * h / w, nRange*h / w, -nRange, nRange);
else
glOrtho(-nRange * w / h, nRange*w / h, -nRange, nRange, -nRange, nRange);
// 重置模型视图矩阵堆栈
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
//glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
//glutInitWindowPosition(0, 0);
//glutInitWindowSize(400, 400);
glutCreateWindow("B样条作业");
cal(0.0, 0.2, 0.01);
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(&display);
// glutDisplayFunc(&LineDisplay);
glutMainLoop();
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件