计算机图形学运用变换程序绘制二维动画,【计算机图形学】c++ OpenGL 二维变换(包括多边形绘制、平移、旋转及缩放)...

该博客详细介绍了如何使用OpenGL进行二维图形的变换,包括平移、旋转和缩放。通过C++代码展示了如何控制这些变换,并实现了鼠标拖动时实时调整图形状态的功能。此外,还提供了键盘操作用于切换不同的变换模式。
摘要由CSDN通过智能技术生成

// 二维变换.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include

#include

#include

#include

#include

#include

#define PI 3.14159265358

//q,w,e,r分别为平移,绘制多边形,旋转,缩放

#define TRANSLATE 0

#define DRAWPOLYGON 1

#define ROTATE 2

#define SCALE 3

int tran_x,tran_y;

int _xtmp,_ytmp;//作为缩放变量用

int mode=DRAWPOLYGON;//默认为绘制模式

using namespace std;

const int winwidth=800;

const int winheight=640;

struct position{

double x;

double y;

};

typedef GLfloat Matrix3x3[3][3];

Matrix3x3 matComposite;//复合矩阵

vector xy;

position tmp;

void DrawPolygon();

void dragmouse(int x,int y);

void mymouse(int button,int state,int x,int y);

void myKeyboard(unsigned char key,int x,int y);

void myKeyboardUp(unsigned char key,int x,int y);

//设置为单位矩阵

void matrix3x3SetIdentity(Matrix3x3 mat){

GLint row,col;

for(row=0;row<3;row++){

for(col=0;col<3;col++)

mat[row][col]=(row==col);

}

}

void init(){

glClearColor(1.0,1.0,1.0,1.0);//设置绘制窗口颜色为白色

glClear(GL_COLOR_BUFFER_BIT);//清除窗口显示内容

/*设置为投影类型模式和其他观察参数*/

glPointSize(3.0f);

glColor3f(1.0,0.0,0.0);//设置颜色为红

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0,winwidth,winheight,0);

matrix3x3SetIdentity(matComposite);

}

//矩阵相乘

void matrixpreMultiply(Matrix3x3 m1,Matrix3x3 m2){

GLint row,col;

Matrix3x3 tmp;

for(row=0;row<3;row++){

for(col=0;col<3;col++){

tmp[row][col]=m1[row][0]*m2[0][col]+m1[row][1]*

m2[1][col]+m1[row][2]*m2[2][col];

}

}

for(row=0;row<3;row++){

for(col=0;col<3;col++){

m2[row][col]=tmp[row][col];

}

}

}

//平移

void translate2D(GLfloat tx,GLfloat ty){

Matrix3x3 matTransl;

matrix3x3SetIdentity(matTransl);//设置为单位矩阵

matTransl[0][2]=tx;

matTransl[1][2]=ty;

matrixpreMultiply(matTransl,matComposite);

}

//旋转

void rotate2D(int x,int y,float theta){

theta=theta/180*PI;

Matrix3x3 matRot;

matrix3x3SetIdentity(matRot);

matRot[0][0]=cos(theta);

matRot[0][1]=-sin(theta);

matRot[0][2]=x*(1-cos(theta))+y*sin(theta);

matRot[1][0]=sin(theta);

matRot[1][1]=cos(theta);

matRot[1][2]=y*(1-cos(theta))-x*sin(theta);

matrixpreMultiply(matRot,matComposite);

}

//缩放

void scale2D(GLfloat sx,GLfloat sy,int x,int y){

Matrix3x3 matScale;

matrix3x3SetIdentity(matScale);

matScale[0][0]=sx;

matScale[0][2]=(1-sx)*x;

matScale[1][1]=sy;

matScale[1][2]=(1-sy)*y;

matrixpreMultiply(matScale,matComposite);

}

//复合矩阵

void transformVerts2D(){

GLfloat tmp;

for(int i=0;i

tmp=matComposite[0][0]*xy[i].x+matComposite[0][1]*xy[i].y+matComposite[0][2];

xy[i].y=matComposite[1][0]*xy[i].x+matComposite[1][1]*xy[i].y+matComposite[1][2];

xy[i].x=tmp;

}

DrawPolygon();

matrix3x3SetIdentity(matComposite);

}

//绘制多边形

void DrawPolygon(){

// glEnable(GL_POLYGON_STIPPLE);

glPolygonMode(GL_BACK,GL_LINE);//设置反面为线性模式

glPolygonMode(GL_FRONT,GL_LINE);//设置正面为线性模式

glClear(GL_COLOR_BUFFER_BIT);//清除窗口显示内容

glBegin(GL_POLYGON);

for(unsigned int i=0;i

glVertex2f(xy[i].x,xy[i].y);

}

glEnd();

glFlush();

}

//鼠标拖动

void dragmouse(int x,int y){

float ssx=1,ssy=1;

switch (mode)

{

//q,w,e,r

case TRANSLATE:

translate2D(x-tran_x,y-tran_y);

transformVerts2D();

tran_x=x;

tran_y=y;

break;

case DRAWPOLYGON:

break;

case ROTATE:

if(x<=_xtmp&&y>=_ytmp)

rotate2D(tran_x,tran_y,-8);

else

rotate2D(tran_x,tran_y,8);

transformVerts2D();

_xtmp=x;

_ytmp=y;

break;

case SCALE:

/*不等比例缩放*/

if(x>_xtmp){

ssx+=0.01f;

}

else if(x<_xtmp>0){

ssx-=0.01f;

}

if(y<_ytmp>

ssy+=0.01f;

}

else if(y>_ytmp&&ssy>0){

ssy-=0.01f;

}

/*等比例缩放

if(x<=_xtmp&&y>=_ytmp){

ssx-=0.01f;

ssy-=0.01f;

}else{

ssx+=0.01f;

ssy+=0.01f;

}*/

scale2D(ssx,ssy,tran_x,tran_y);

transformVerts2D();

_xtmp=x;

_ytmp=y;

break;

default:

break;

}

}

//鼠标

void mymouse(int button,int state,int x,int y){

if(button==GLUT_LEFT_BUTTON &&state==GLUT_DOWN){

switch (mode)

{

//q,w,e,r

case TRANSLATE:

tran_x=x;

tran_y=y;

break;

case DRAWPOLYGON:

tmp.x=x;

tmp.y=y;

xy.push_back(tmp);

DrawPolygon();

break;

case ROTATE:

tran_x=x;

tran_y=y;

_xtmp=x;

_ytmp=y;

break;

case SCALE:

tran_x=x;

tran_y=y;

break;

default:

break;

}

}

}

//键盘

void myKeyboard(unsigned char key,int x,int y){

//清空删除

if(key=='a'){

glClear(GL_COLOR_BUFFER_BIT);//清除窗口显示内容

glFlush();

xy.clear();

}

}

void myKeyboardUp(unsigned char key,int x,int y){

switch (key)

{

case 'q':mode=TRANSLATE;

break;

case 'w':mode=DRAWPOLYGON;

break;

case 'e':mode=ROTATE;

break;

case 'r':mode=SCALE;

break;

default:

break;

}

}

void myDisplay(){

glFlush();

}

void mymenu(int id){

if(id==0)

mode=0;

else if(id==1)

mode=1;

else if(id==2)

mode=2;

else if(id==3)

mode=3;

}

int main(int argc,char**argv){

glutInit(&argc,argv);//初始化

glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB);//设置绘制模式

glutInitWindowPosition(500,300);

glutInitWindowSize(winwidth,winheight);

glutCreateWindow("二维图形的变换");//创建窗口

int id=glutCreateMenu(mymenu);

glutAddMenuEntry("平移",0);

glutAddMenuEntry("绘制多边形",1);

glutAddMenuEntry("旋转",2);

glutAddMenuEntry("缩放",3);

glutAttachMenu(GLUT_RIGHT_BUTTON);

init();

glutDisplayFunc(myDisplay);

glutMouseFunc(mymouse);//鼠标监听回调函数

glutMotionFunc(dragmouse);//鼠标拖动

glutKeyboardFunc(myKeyboard);//键盘监听

glutKeyboardUpFunc(myKeyboardUp);//键盘弹起状态

glutMainLoop();

}

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值