B样条张量积基函数

节点向量 𝑼 = 𝟎, 𝟎, 𝟎, 𝟎, 𝟎. 𝟐, 𝟎. 𝟒, 𝟎. 𝟔, 𝟎. 𝟖, 𝟎. 𝟖, 𝟎. 𝟖, 𝟏, 𝟏, 𝟏, 𝟏 𝑽 = {𝟎, 𝟎, 𝟎, 𝟎, 𝟎. 𝟐, 𝟎. 𝟐, 𝟎. 𝟐, 𝟎. 𝟒, 𝟎. 𝟔, 𝟎. 𝟖, 𝟏, 𝟏, 𝟏, 𝟏} 绘制张量积基函数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 文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值