[OpenGL]用鼠标拖拽图形移动
2016-12-14 23:29
232 查看
今天做计算机图形学实验。题目布置了写程序使图形移动,于是我就写了这个程序。
使用的环境是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;
}
使用的环境是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;
}
相关文章推荐
- GDI+绘制随鼠标移动可拉伸,无锯齿图形
- unity鼠标拖拽物体移动
- 鼠标拖拽移动Java界面组件
- 基于原生JS(ES5)的鼠标移动(拖拽)HTML元素的插件(MoveElementJS)
- OpenGL中的鼠标移动和锁定
- 鼠标拖拽移动子窗体的JS实现
- 鼠标移动生出四散图形的效果
- Javascript实现图片位置控制(鼠标拖拽 + 键盘方向键移动)源码分享
- WinForm--(控件的拖拽和跟随鼠标移动)
- 通过屏幕鼠标绘制opengl三维场景图形
- 鼠标拖拽物体移动
- QT界面简单的图形移动和鼠标绘图
- OpenGL3D图形、旋转、纹理、键盘移动、光照、滤波、透明(完整) 复制代码
- 如何通过鼠标移动图形
- opengl中鼠标移动、单击、滚轮事件
- 浏览器实现ACDSEE看图功能之--用鼠标移动观看图形
- 点滴积累【JS】---JS小功能(onmousedown实现鼠标拖拽div移动)
- 鼠标拖拽移动Java界面组件
- Java简单图形编辑器 放置、移动和擦除方块 鼠标事件测试程序 Java核心技术 事件处理
- [VB.NET]类的接口与鼠标移动如何返回图形的结果