⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 curves.c

📁 计算机图形学~想必是很多人需要的~在此共享一下
💻 C
字号:
/*  curves.c       */

/* E. Angel, Interactive Computer Graphics */
/* A Top-Down Approach with OpenGL, Third Edition */
/* Addison-Wesley Longman, 2003 */


/*****  Simple interactive curve drawing program.****  The following keyboard commands are used to control the**  program:****    q - Quit the program**    c - Clear the screen**    e - Erase the curves**    b - Draw Bezier curves**    i - Draw interpolating curves**    s - Draw B-spline curves***/
/* All control points are converted to Bezier
control point to allow use of OpenGL evaluators */

#include <GL/glut.h>typedef enum{    BEZIER,    INTERPOLATED,    BSPLINE} curveType;void keyboard(unsigned char key, int x, int y);void computeMatrix(curveType type, float m[4][4]);void vmult(float m[4][4], float v[4][3], float r[4][3]);/* Colors to draw them in */GLfloat colors[][3] ={   { 1.0, 0.0, 0.0 },   { 0.0, 1.0, 0.0 },   { 0.0, 0.0, 1.0 }};#define MAX_CPTS  25            /* Fixed maximum number of control points */GLfloat cpts[MAX_CPTS][3];int ncpts = 0;static int width = 500, height = 500;           /* Window width and height *//* Matrix stuff *//* This routine multiplies two 4 x 4 matrices. *//* This routine multiplies a 4 x 4 matrix with a vector of 4 points. */void vmult(float m[4][4], float v[4][3], float r[4][3]){    int i, j, k;    for (i = 0; i < 4; i++)        for (j = 0; j < 3; j++)            for (k = 0, r[i][j] = 0.0; k < 4; k++)                r[i][j] += m[i][k] * v[k][j];}/* Interpolating to Bezier matrix */static float minterp[4][4] = {    { 1.0, 0.0, 0.0, 0.0 },    { -5.0/6.0, 3.0, -3.0/2.0, 1.0/3.0 },    { 1.0/3.0, -3.0/2.0, 3.0, -5.0/6.0 },    { 0.0, 0.0, 0.0, 1.0 }, };/* B-spline to Bezier matrix */static float mbspline[4][4] = {    { 1.0/6.0, 4.0/6.0, 1.0/6.0, 0.0 },    { 0.0, 4.0/6.0, 2.0/6.0, 0.0 },    { 0.0, 2.0/6.0, 4.0/6.0, 0.0 },    { 0.0, 1.0/6.0, 4.0/6.0, 1.0/6.0 },};static float midentity[4][4] ={	{ 1.0, 0.0, 0.0, 0.0},	{ 0.0, 1.0, 0.0, 0.0},	{ 0.0, 0.0, 1.0, 0.0},	{ 0.0, 0.0, 0.0, 1.0}};/* Calculate the matrix used to transform the control points */void computeMatrix(curveType type, float m[4][4]){    int i, j;    switch (type)    {        case BEZIER:            /* Identity matrix */            for (i = 0; i < 4; i++)                for (j = 0; j < 4; j++)					m[i][j] = midentity[i][j];            break;        case INTERPOLATED:            for (i = 0; i < 4; i++)                for (j = 0; j < 4; j++)                    m[i][j] = minterp[i][j];            break;        case BSPLINE:            for (i = 0; i < 4; i++)                for (j = 0; j < 4; j++)                    m[i][j] = mbspline[i][j];            break;     }}/* Draw the indicated curves using the current control points. */static void drawCurves(curveType type){    int i;    int step;    GLfloat newcpts[4][3];    float m[4][4];    /* Set the control point computation matrix and the step size. */    computeMatrix(type, m);	if(type == BSPLINE) step = 1;	else step = 3;    glColor3fv(colors[type]);    /* Draw the curves */    i = 0;    while (i + 3 < ncpts)    {        /* Calculate the appropriate control points */        vmult(m, &cpts[i], newcpts);        /* Draw the curve using OpenGL evaluators */        glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &newcpts[0][0]);        glMapGrid1f(30, 0.0, 1.0);        glEvalMesh1(GL_LINE, 0, 30);        /* Advance to the next segment */        i += step;    }    glFlush();}/* This routine displays the control points */static void display(void){    int i;    glClear(GL_COLOR_BUFFER_BIT);    glColor3f(0.0, 0.0, 0.0);    glPointSize(5.0);    glBegin(GL_POINTS);    for (i = 0; i < ncpts; i++)        glVertex3fv(cpts[i]);    glEnd();    glFlush();}/* This routine inputs new control points */static void mouse(int button, int state, int x, int y){    float wx, wy;    /* We are only interested in left clicks */    if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN)        return;    /* Translate back to our coordinate system */    wx = (2.0 * x) / (float)(width - 1) - 1.0;    wy = (2.0 * (height - 1 - y)) / (float)(height - 1) - 1.0;    /* See if we have room for any more control points */    if (ncpts == MAX_CPTS)        return;    /* Save the point */    cpts[ncpts][0] = wx;    cpts[ncpts][1] = wy;    cpts[ncpts][2] = 0.0;    ncpts++;    /* Draw the point */    glColor3f(0.0, 0.0, 0.0);    glPointSize(5.0);    glBegin(GL_POINTS);    glVertex3f(wx, wy, 0.0);    glEnd();     glFlush();}/* This routine handles keystroke commands */void keyboard(unsigned char key, int x, int y){    static curveType lasttype = BEZIER;    switch (key)    {        case 'q': case 'Q':            exit(0);            break;        case 'c': case 'C':			ncpts = 0;			glutPostRedisplay();            break;        case 'e': case 'E':            glutPostRedisplay();            break;        case 'b': case 'B':            drawCurves(BEZIER);            lasttype = BEZIER;             break;        case 'i': case 'I':            drawCurves(INTERPOLATED);            lasttype = INTERPOLATED;             break;        case 's': case 'S':            drawCurves(BSPLINE);            lasttype = BSPLINE;             break;    }}/* This routine handles window resizes */void reshape(int w, int h){    width = w;    height = h;    /* Set the transformations */    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);    glMatrixMode(GL_MODELVIEW);    glViewport(0, 0, w, h);}main(int argc, char **argv){    /* Intialize the program */    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_RGB);    glutInitWindowSize(width, height);    glutCreateWindow("curves");    /* Register the callbacks */    glutDisplayFunc(display);    glutMouseFunc(mouse);    glutKeyboardFunc(keyboard);    glutReshapeFunc(reshape);	glClearColor(1.0, 1.0, 1.0, 1.0);    glEnable(GL_MAP1_VERTEX_3);    glutMainLoop();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -