zoukankan      html  css  js  c++  java
  • [OpenGL]用鼠标拖拽图形移动

    今天做计算机图形学实验。题目布置了写程序使图形移动,于是我就写了这个程序。

    使用的环境是Code::Blocks + GLUT,Code::Blocks配置GLUT实现OpenGL的教程可以看这篇:

    http://blog.csdn.net/yang_7_46/article/details/24674849


    想要实现用鼠标拖拽使图形移动,首先需要考虑两个问题:

    1.如何接受鼠标产生的信号。

    2.如何判断鼠标在图形内。


    解决第一个问题,只需要了解到OpenGL中的GLUT给的函数就可以。

    glutMouseFunc( (void*)Func(int button, int state, int x, int y) );
    如果没有记错,上面是这个函数的原型。其中x,y是当前鼠标指针所在的位置。

    正好利用这个信息可以得到是否在图形内。


    而获取到了这些,还需要获取鼠标的动作。OpenGL提供了两个函数。

    glutMotionFunc( (void*)func(int x, int y) );
    glutPassiveMotionFunc( (void*)func(int x, int y) );
    利用这些函数就可以解决问题了。


    而第二个问题。涉及到凸包,在一个多边形内如果判断点是否在图形内。这部分因为时间问题并没有写,所以先占个坑,回头补。

    下面实现了简略的代码。运行拖动时会出现闪屏,因为没有加缓存。

    #include <cmath>
    #include <cstdlib>
    #include <iostream>
    #include <windows.h>
    #include <GL/glut.h>
    using namespace std;
    
    GLdouble newMat[4][2] = {0,0, 100,0, 100,100, 0,100};
    const GLdouble mat[4][2] = {0,0, 100,0, 100,100, 0,100};
    
    void init() {
        glClearColor( 0.0, 0.0, 0.0, 0.0 );
        glMatrixMode( GL_PROJECTION );
        gluOrtho2D( 0.0, 800.0, 0.0, 600.0 );
    }
    bool isEqual() {
        for( int i = 0; i < 4; ++i ) {
            if( fabs( mat[i][0] - newMat[i][0] ) >= 1e-6 ) return false;
            if( fabs( mat[i][1] - newMat[i][1] ) >= 1e-6 ) return false;
        }
        return true;
    }
    void display() {
        glClear( GL_COLOR_BUFFER_BIT );
        glBegin( GL_POLYGON );
            glColor3f( 1.0, 0.0, 0.0 );
            for( int i = 0; i < 4; ++i )
                glVertex2d( mat[i][0], mat[i][1] );
        glEnd();
        glFlush();
    
        if( !isEqual() ) {
            glBegin( GL_POLYGON );
                glColor3f( 0.0, 1.0, 0.0 ); //移动后用绿色矩阵表示
                for( int i = 0; i < 4; ++i )
                    glVertex2d( newMat[i][0], newMat[i][1] );
            glEnd();
            glFlush();
        }
    }
    bool isInner( int x, int y ) {
        unsigned short int c = 0;
        if( x < newMat[0][0] ) c |= 1; c <<= 1;
        if( x > newMat[1][0] ) c |= 1; c <<= 1;
        if( y > newMat[2][1] ) c |= 1; c <<= 1;
        if( y < newMat[0][1] ) c |= 1;
        if( c == 0 ) return true;
        else return false;
    }
    void mouse_process( int button, int state, int x, int y ) {
        /*
        if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
    
        }
        */
    }
    void mouse_process_active( int x, int y ) {
        y = 600 - y; //因为获取的鼠标位置
        if( isInner( x, y ) ) {
            double avgx = ( newMat[0][0] + newMat[1][0] ) / 2.0;
            double avgy = ( newMat[0][1] + newMat[3][1] ) / 2.0;
    
            double dx = x - avgx;
            double dy = y - avgy;
            for(int i = 0; i < 4; ++i) {
                newMat[i][0] += dx;
                newMat[i][1] += dy;
    
                if( newMat[i][0] > 800) {
                    int dx = newMat[i][0] - 800;
                    for(int j = 0; j < 4; ++j)
                        newMat[j][0] -= dx;
                    MessageBox( NULL, TEXT("Coordinate out of range"), TEXT("Warning"), MB_ICONWARNING | MB_OK );
                    Sleep(1000);
                } else if( newMat[i][0] < 0 ){
                    int dx = 0 - newMat[i][0];
                    for(int j = 0; j < 4; ++j)
                        newMat[j][0] += dx;
                    MessageBox( NULL, TEXT("Coordinate out of range"), TEXT("Warning"), MB_ICONWARNING | MB_OK );
                    Sleep(1000);
                } else if( newMat[i][1] > 600 ){
                    int dy = newMat[i][1] - 600;
                    for(int j = 0; j < 4; ++j)
                        newMat[j][1] -= dy;
                    MessageBox( NULL, TEXT("Coordinate out of range"), TEXT("Warning"), MB_ICONWARNING | MB_OK );
                    Sleep(1000);
                } else if( newMat[i][1] < 0 ) {
                    int dy = 0 - newMat[i][1];
                    for(int j = 0; j < 4; ++j)
                        newMat[j][1] += dy;
                    MessageBox( NULL, TEXT("Coordinate out of range"), TEXT("Warning"), MB_ICONWARNING | MB_OK );
                    Sleep(1000);
                }
            }
            glutPostRedisplay();
        }
    }
    void mouse_process_passtive( int x, int y ) {}
    int main( int argv, char** argc ) {
        glutInit( &argv, argc );
        glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
        glutInitWindowPosition( 100, 100 );
        glutInitWindowSize( 800, 600 );
        glutCreateWindow( "Lab 3" );
        init();
    
        glutDisplayFunc( display );
        glutMouseFunc( mouse_process );
        glutMotionFunc( mouse_process_active );
        glutPassiveMotionFunc( mouse_process_passtive );
    
        glutMainLoop();
        return 0;
    }




  • 相关阅读:
    网络通信过程
    路由表转发分析实例
    随机生成MAC地址和IP地址
    zabbix监控LAMP全教程
    linux ssh利用公钥免密登陆
    如果Mysql插入字符始终乱码怎么办?
    Windows 桌面利用 Navicat等工具连接 虚拟机Mysql
    pagefile.sys 虚拟内存
    linux常用命令---------------find
    当你使用Pycharm编译程序的时候,遇到了这个问题,该怎么办?please select a valid interpreter
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179338.html
Copyright © 2011-2022 走看看