OpenGL

来源:互联网 发布:找程序员男朋友的坏处 编辑:程序博客网 时间:2024/06/06 04:54

计算公式:
这里写图片描述


使用说明:鼠标在窗口点击绘制B样条曲线,鼠标右键移动控制点。退格键(←)删除鼠标所在的点。


运行效果:
这里写图片描述


代码如下:

#include<gl/glut.h>#include<math.h>#include<windows.h>#include<vector>#include<algorithm>using namespace std;bool mouseRightIsDown = false;struct Point{    int x, y;    Point(){};    Point(int tx, int ty)    {        x = tx;        y = ty;    }};vector<Point> p;double getRatio(double t,double a,double b,double c,double d){    return a * pow(t, 3) + b * pow(t, 2) + c * t + d;}double caculateSquarDistance(Point a, Point b){    return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);}int getIndexNearByMouse(int x, int y){    double precision = 200;     //精确度    int index = -1;    double Min;    for (int i = 0; i < p.size(); i++)    {        double dis = caculateSquarDistance(p[i], Point(x, y));        if (dis < precision)        {            if (index == -1)            {                index = i;                Min = dis;            }            else if (dis < Min)            {                index = i;                Min = dis;            }        }    }    return index;}void Bezier(Point a,Point b,Point c,Point d){    int n = 500;    double derta = 1.0 / n;    glPointSize(2);    glColor3d(0, 0, 0);    glBegin(GL_LINE_STRIP);    for (int i = 0; i <= n; i++)    {        double t = derta * i;        double ratio[4];        ratio[0] = getRatio(t, -1, 3, -3, 1);        ratio[1] = getRatio(t, 3, -6, 0, 4);        ratio[2] = getRatio(t, -3, 3, 3, 1);        ratio[3] = getRatio(t, 1, 0, 0, 0);        double x=0, y=0;        x += ratio[0] * a.x + ratio[1] * b.x + ratio[2] * c.x + ratio[3] * d.x;        y += ratio[0] * a.y + ratio[1] * b.y + ratio[2] * c.y + ratio[3] * d.y;        x /= 6.0;        y /= 6.0;        glVertex2d(x, y);    }    glEnd();}void myDisplay(){    glClear(GL_COLOR_BUFFER_BIT);    //清除颜色缓存和深度缓存    //画点    glPointSize(5);    glColor3d(1, 0, 0);    glBegin(GL_POINTS);    for (int i = 0; i < p.size(); i++)        glVertex2d(p[i].x, p[i].y);    glEnd();    //画线    glLineWidth(2);    glColor3d(0, 1, 0);    glBegin(GL_LINE_STRIP);    for (int i = 0; i < p.size(); i++)        glVertex2d(p[i].x, p[i].y);    glEnd();    if (p.size() >= 4)    for (int i = 0; i < p.size() - 3; i++)        Bezier(p[i], p[i + 1], p[i + 2], p[i + 3]);    glFlush();}void keyboard(unsigned char key, int x, int y){    if (key == 27)      //ESC        exit(0);    if (key == 8)       //退格键    {        int index = getIndexNearByMouse(x, y);        if (index == -1)            return;        p.erase(p.begin() + index);        glutPostRedisplay();    }}void mouse(int button, int state, int x, int y){    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)    {        Point t(x, y);        p.push_back(t);        glutPostRedisplay();    }    if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)        mouseRightIsDown = true;    if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP)        mouseRightIsDown = false;}void motion(int x, int y){    if (mouseRightIsDown)       //按住右键移动点    {        int index = getIndexNearByMouse(x, y);        if (index == -1)            return;        p[index].x = x;        p[index].y = y;        glutPostRedisplay();    }}void Reshape(int w, int h)      //两个参数:窗口被移动后大小{    glViewport(0, 0, w, h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluOrtho2D(0, w, h, 0);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();}void initWindow(int &argc, char *argv[], int width, int height, char *title)    //初始化并显示到屏幕中央{    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);    glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN) - width) >> 1, (GetSystemMetrics(SM_CYSCREEN) - height) >> 1);       //指定窗口位置    glutInitWindowSize(width, height);       //指定窗口大小    glutCreateWindow(title);    glClearColor(1, 1, 1, 0);    glShadeModel(GL_FLAT);}int main(int argc, char *argv[]){    initWindow(argc, argv, 1000, 600, "B样条曲线");    puts("\n\t鼠标在窗口点击绘制B样条曲线,鼠标右键移动控制点");    puts("\t退格键(←)删除鼠标所在的点");    glutDisplayFunc(myDisplay);    glutReshapeFunc(Reshape);    glutMouseFunc(mouse);    glutMotionFunc(motion);    glutKeyboardFunc(keyboard);    glutMainLoop();    return 0;}
原创粉丝点击