#ifndef GLUT_DISABLE_ATEXIT_HACK
#define GLUT_DISABLE_ATEXIT_HACK
#endif
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <vector>
#include <fstream>
#include <string>
#include <cstring>
#include "gult.h"
using namespace std;
int height, width;
static int xOrg = 0, yOrg = 0 , count = 1;
// Max number of lines for drawing: 100
const int max_square=100;
const int max_triangle=100;
struct line_structure //存储线段的两个端点坐标
{
double x0,x1,y0,y1;
};
struct line_data
{
int x,y;
};
//重画线:把所有线点的位置信息存在每个向量上,每个向量上的所有数据就是一条线
vector<line_structure> square_start[max_square]; //存储要画的矩形的线段,元素是line_structure
vector<line_structure> triangle_start[max_triangle]; //储存要画的三角形的线段,元素是line_structure
double pi = acos(-1); //算出pi的值
double currentMatrix[4][4]; //储存当前的转换矩阵
double Vectors[4][4]; //储存当前要操作的矩形或则三角形
//double triangleVectors[4][4];
double View[4][4];
int flat; //因为只有一个数组Vector 储存矩形或则三角形的端点坐标,所以要一个标志提示当前要处理的是矩形还是三角形
int num_square=0; //记录当前的矩形个数
int num_triangle=0; //记录当前的三角形个数
//int Count=0;
//以下都是作业1用来画线的函数
void drawDot(int x, int y, float r, float g, float b);
void drawLine1(double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float wyt, bool xy_interchange, float r , float g, float b);
void drawLine2(double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float wyt, bool xy_interchange, float r , float g, float b);
void drawLine3(double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float wyt, bool xy_interchange, float r , float g, float b);
void drawLine4(double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float wyt, bool xy_interchange, float r , float g, float b);
void drawparr(double dx,double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float vyt, float r, float g, float b);
void drawnor(double dy, double x0, double x1, double y0, double y1,float vxl,float vxr,float wyb,float wyt, float r, float g, float b);
void clearScreen();
void displayFunc(void);
void drawL(double dx, double dy, double x0, double x1 , double y0 , double y1,float wxl,float wxr,float wyb,float wyt, float r, float g, float b);
//作业2添加部分
void ReadInput(bool& IsExit); //read commond file
void reset(); //初始化转换矩阵
void scale(float sx, float sy); //对图形进行伸缩
void translate(float tx, float ty); //对图形进行平移
void matrixMult(double array1[4][4], double array2[4][4],int x); //计算矩阵乘法
void rotate(float degree); //对图形以原点为轴心进行旋转
void square(); //新建一个矩形,然后进行转换
void triangle(); //新建一个三角形,然后进行转换
void clearData(); //清除所有数据,即把Vector,num_square等都重置
void view(double wxl,double wxr,double wyb,double wyt,double vxl,double vxr,double vyb,double vyt); //把world space里的图像投影到view space上
/****************************************操作函数实现*****************************************/
void matrixMult(double array1[4][4],double array2[4][4],int flat){//矩阵相乘,array1是transform matrix,第二个是向量matrix
double Top[3][3];
memset(Top,0.0,sizeof(Top));
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
Top[i][j]=array1[j][i];
//cout<<Top[i][j]<<' ';
}
//cout<<endl;
}
/*cout<<"check"<<endl;
for(int i=0;i<4;i++){
for(int j=0;j<3;j++){
cout<<array2[i][j]<<' ';
}
cout<<endl;
}*/
double temp[4][4];
memset(temp, 0.0 , sizeof(temp));
for(int i=0;i<flat;i++){
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
temp[i][j]+=Top[k][j]*array2[i][k];
}
}
}
//cout<<"vector"<<endl;
for(int i=0;i<flat;i++){
for(int j=0;j<3;j++){
array2[i][j]=temp[i][j];//四舍五入
//cout<<array2[i][j]<<' ';
}
//cout<<endl;
}
//cout<<"Multi"<<endl;
}
void reset(){//初始化变换矩阵
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(i==j)
currentMatrix[i][j]=1;
else
currentMatrix[i][j]=0;
//cout<<currentMatrix[i][j]<<' ';
}
//cout<<endl;
}
flat=0;
}
void scale(float sx, float sy){ //观察转换矩阵可以发现,其实就是对转换矩阵的两个位置进行操作,那么就可以直接对这两个位置上的数据乘相应的倍数
currentMatrix[0][0]*=sx;
currentMatrix[1][1]*=sy;
}
void translate(float tx, float ty){ //变换矩阵前两行最后一个数就是对应轴的平移量
currentMatrix[0][2]+=tx;
currentMatrix[1][2]+=ty;
}
void rotate(float degree){ //这里新建一个旋转矩阵op,然后利用矩阵乘法与当前转换矩阵相乘的到进行旋转后的矩阵,要乘当前转换矩阵的转置
double op[3][3];
memset(op,0.0,sizeof(op));
double d;
d=pi/180*degree;
double Cos,Sin;
if(abs(cos(d))<10e-4)
Cos=0;
else
Cos=cos(d);
if(abs(sin(d))<10e-4)
Sin=0;
else
Sin=sin(d);
op[0][0]=Cos;
op[0][1]=-Sin;
op[1][0]=Sin;
op[1][1]=Cos;
op[2][2]=1;
double temp[4][4];
memset(temp,0.0,sizeof(temp));
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
temp[i][j]+=op[i][k]*currentMatrix[k][j];
}
}
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
currentMatrix[i][j]=temp[i][j];
}
}
}
void square(){
//初始化矩形
Vectors[0][0]=1; Vectors[0][1]=1; Vectors[0][2]=1;
Vectors[1][0]=-1; Vectors[1][1]=1; Vectors[1][2]=1;
Vectors[2][0]=-1; Vectors[2][1]=-1; Vectors[2][2]=1;
Vectors[3][0]=1; Vectors[3][1]=-1; Vectors[3][2]=1;
//设置标志,说明当前要操作的是矩形
flat=4;
//得到进行转化后的矩形,直接和转换矩阵相乘
matrixMult(currentMatrix,Vectors,flat);
//储存当前矩形的四条线段
line_structure temp;
temp.x0=Vectors[0][0];
temp.y0=Vectors[0][1];
temp.x1=Vectors[1][0];
temp.y1=Vectors[1][1];
square_start[num_square].push_back(temp);
temp.x0=Vectors[1][0];
temp.y0=Vectors[1][1];
temp.x1=Vectors[2][0];
temp.y1=Vectors[2][1];
square_start[num_square].push_back(temp);
temp.x0=Vectors[2][0];
temp.y0=Vectors[2][1];
temp.x1=Vectors[3][0];
temp.y1=Vectors[3][1];
square_start[num_square].push_back(temp);
temp.x0=Vectors[3][0];
temp.y0=Vectors[3][1];
temp.x1=Vectors[0][0];
temp.y1=Vectors[0][1];
square_start[num_square].push_back(temp);
num_square++;
}
void triangle(){
//初始化三角形的三个端点
Vectors[0][0]=0; Vectors[0][1]=1; Vectors[0][2]=1;
Vectors[1][0]=-1; Vectors[1][1]=-1; Vectors[1][2]=1;
Vectors[2][0]=1; Vectors[2][1]=-1; Vectors[2][2]=1;
//设置标志,说明当前要操作的是三角形
flat=3;
//得到转换后的三角形
matrixMult(currentMatrix,Vectors,3);
//储存当前三角形的三条线段
line_structure temp;
temp.x0=Vectors[0][0];
temp.y0=Vectors[0][1];
temp.x1=Vectors[1][0];
temp.y1=Vectors[1][1];
triangle_start[num_triangle].push_back(temp);
temp.x0=Vectors[1][0];
temp.y0=Vectors[1][1];
temp.x1=Vectors[2][0];
temp.y1=Vectors[2][1];
triangle_start[num_triangle].push_back(temp);
temp.x0=Vectors[2][0];
temp.y0=Vectors[2][1];
temp.x1=Vectors[0][0];
temp.y1=Vectors[0][1];
triangle_start[num_triangle].push_back(temp);
num_triangle++;
}
//清除所有数据
void clearData(){
for(int i=0;i<num_square;i++){
while(!square_start[i].empty())
square_start[i].pop_back();
}
for(int i=0;i<num_triangle;i++){
while(!triangle_start[i].empty())
triangle_start[i].pop_back();
}
num_square=0;
num_triangle=0;
}
//把世界坐标里的图像投影到窗口
void view(double wxl,double wxr,double wyb,double wyt,double vxl,double vxr,double vyb,double vyt){
drawparr(1,vxl,vxr,height-vyb,height-vyb,0,width,0,height,1.0,1.0,1.0);
drawparr(1,vxl,vxr,height-vyt,height-vyt,0,width,0,height,1.0,1.0,1.0);
drawnor(1,vxl,vxl,height-vyt,height-vyb,0,width,0,height,1.0,1.0,1.0);
drawnor(1,vxr,vxr,height-vyt,height-vyb,0,width,0,height,1.0,1.0,1.0);
double k1,k2;
double translate1,translate2;
k1=(vxr-vxl)/(wxr-wxl);//放大倍数
k2=(vyt-vyb)/(wyt-wyb);//平移量
translate1=vxl-wxl*k1;
translate2=vyb-wyb*k2;
for(int i=0;i<num_square;i++)
{
int len=square_start[i].size();
vector<line_structure> temp;
temp=square_start[i];
for(int j=0;j<len;j++)
{
double dx,dy,x0,x1,y0,y1;
x0=temp[j].x0; x1=temp[j].x1;
y0=temp[j].y0; y1=temp[j].y1;
x0=x0*k1+translate1; x1=x1*k1+translate1;
y0=y0*k2+translate2; y1=y1*k2+translate2;
y0=height-y0; y1=height-y1;
dx=x1-x0;
dy=y1-y0;
drawL(dx, dy, x0, x1, y0, y1, vxl, vxr, height-vyt, height-vyb, 0.0, 1.0, 1.0);
}
}
for(int i=0;i<num_triangle;i++)
{
vector<line_structure> temp;
temp=triangle_start[i];
int len=triangle_start[i].size();
for(int j=0;j<len;j++)
{
double dx,dy,x0,x1,y0,y1;
x0=temp[j].x0; x1=temp[j].x1;
y0=temp[j].y0; y1=temp[j].y1;
x0=x0*k1+translate1; x1=x1*k1+translate1;
y0=y0*k2+translate2; y1=y1*k2+translate2;
y0=height-y0; y1=height-y1;
dx=x1-x0;
dy=y1-y0;
drawL(dx, dy, x0, x1, y0, y1, vxl, vxr, height-vyt, height-vyb, 1.0, 0.0, 1.0);
}
}
}
/********************************************************************************************/
//读取文件信息
void ReadInput(bool& IsExit){
//ifstream fin("hw2A.txt");
//ifstream fin("hw2B.txt");
//ifstream fin("hw2C.txt");
//ifstream fin("hw2D.txt"); //2. open file
ifstream fin("hw2E.txt");
//ifstream fin("hw2F.txt");
string command,comment;
float sx,sy,degree,tx,ty,wxl,wxr,wyb,wyt,vxl,vxr,vyt,vyb;
while (fin>>command) { //3. read text from file
if (command=="scale")
{
fin>>sx;
fin>>sy;
scale(sx,sy);
cout<<command<<endl;
}
else if (command=="rotate")
{
fin>>degree;
rotate(degree);
cout<<command<<endl;
}
else if (command=="translate")
{
fin>>tx;
fin>>ty;
translate(tx,ty);
cout<<command<<endl;
}
else if (command=="reset")
{
reset();
cout<<command<<endl;
}
else if (command=="square")
{
square();
cout<<command<<endl;
}
else if (command=="triangle")
{
triangle();
cout<<command<<endl;
}
else if (command=="view")
{
fin>>wxl>>wxr>>wyb>>wyt>>vxl>>vxr>>vyb>>vyt;
view(wxl,wxr,wyb,wyt,vxl,vxr,vyb,vyt);
cout<<command<<endl;
}
else if (command=="clearData")
{
clearData();
cout<<command<<endl;
}
else if (command=="clearScreen")
{
cout<<"Screen is cleared"<<endl;
clearScreen();
cout<<command<<endl;
}
else if (command=="end")
{
IsExit=true;
cout<<command<<endl;
//system("pause");
//exit(0);
}
else if (command=="#")
{
getline(fin, comment);
cout<<comment<<endl;
}
}
}
/*****************************************************************************************/
//画线,简化代码
void drawL(double dx,double dy, double x0, double x1 , double y0 , double y1,float vxl,float vxr,float vyb,float vyt, float r, float g, float b){
double k=0;
if(dx!=0)
k=abs(1.0*dy/dx);
if(dx>0 && dy>0){
if(k>0&&k<1)
drawLine1(x0, x1, y0, y1, vxl,vxr,vyb,vyt,0, r, g, b);
else
drawLine1(x0, x1, y0, y1, vxl,vxr,vyb,vyt,1, r, g, b);
}
else if(dx>0 && dy<0){
if(k>0&&k<1)
drawLine2(x0, x1, y0, y1, vxl,vxr,vyb,vyt,0, r, g, b);
else
drawLine2(x0, x1, y0, y1,vxl,vxr,vyb,vyt, 1, r, g, b);
}
else if(dx<0 && dy>0){
if(k>0&&k<1)
drawLine3(x0, x1, y0, y1, vxl,vxr,vyb,vyt,0, r, g, b);
else
drawLine3(x0, x1, y0, y1,vxl,vxr,vyb,vyt, 1, r, g, b);
}
else if(dx<0 && dy<0){
if(k>0&&k<1)
drawLine4(x0, x1,y0, y1,vxl,vxr,vyb,vyt, 0, r, g, b);
else
drawLine4(x0, x1,y0,y1,vxl,vxr,vyb,vyt,1, r, g, b);
}
else if(dy==0){
drawparr(dx,x0,x1,y0,y1,vxl,vxr,vyb,vyt,r,g,b);
}
else if(dx==0){
drawnor(dy,x0,x1,y0,y1,vxl,vxr,vyb,vyt,r,g,b);
}
glFlush();
return ;
}
// Clear screen
void clearScreen()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
// draw a dot at location with integer coordinates (x,y), and with color (r,g,b)
void drawDot(int x, int y, float r, float g, float b)
{
glBegin(GL_POINTS);
// set the color of dot
glColor3f(r, g, b);
// invert height because the opengl origin is at top-left instead of bottom-left
glVertex2i(x , height - y);
glEnd();
}
// Draw line for dx>0 and dy>0 右斜下
void drawLine1(double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float vyt, bool xy_interchange, float r , float g, float b)
{
if(xy_interchange){
swap(x0,y0);
swap(x1,y1);
}
int A,B;
A=y1-y0;
B=x0-x1;
int IncE,IncNE;
IncE=2*A;
IncNE=2*(A+B);
int d=2*A+B;
double x=x0,y=y0;
while(x<=x1){
if(xy_interchange)
{
if(y>=vxl&&y<=vxr&&x>=vyb&&x<=vyt)
drawDot(y,x,r,g,b);
}
else{
if(x>=vxl&&x<=vxr&&y>=vyb&&y<=vyt)
drawDot(x,y,r,g,b);
}
if(d<=0){
x++;
d+=IncE;
}
else{
x++;
y++;
d+=IncNE;
}
}
return;
}
// Draw line for dx>0 and dy<0 右斜上
void drawLine2(double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float vyt, bool xy_interchange, float r , float g, float b)
{
if(xy_interchange){
int tempx;
tempx=x0;
x0=-y0;
y0=-tempx;
tempx=x1;
x1=-y1;
y1=-tempx;
}
int A,B;
A=y1-y0;
B=x0-x1;
int IncE,IncSE;
IncE=2*A;
IncSE=2*(A-B);
int d=2*A-B;
int x=x0,y=y0;
while(x<=x1){
if(xy_interchange)
{
if(-y>=vxl&&-y<=vxr&&-x>=vyb&&-x<=vyt)
drawDot(-y,-x,r,g,b);
}
else{
if(x>=vxl&&x<=vxr&&y>=vyb&&y<=vyt)
drawDot(x,y,r,g,b);
}
if(d>=0){
x++;
d+=IncE;
}
else{
x++;
y--;
d+=IncSE;
}
}
return;
}
// Draw line for dx<0 and dy>0 左斜下
void drawLine3(double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float vyt, bool xy_interchange, float r , float g, float b)
{
if(xy_interchange){
int tempx;
tempx=x0;
x0=-y0;
y0=-tempx;
tempx=x1;
x1=-y1;
y1=-tempx;
}
int A,B;
A=y1-y0;
B=x0-x1;
int IncE,IncSE;
IncE=-2*A;
IncSE=2*(B-A);
int d=-2*A+B;
int x=x0,y=y0;
while(x>=x1){
if(xy_interchange)
{
if(-y>=vxl&&-y<=vxr&&-x>=vyb&&-x<=vyt)
drawDot(-y,-x,r,g,b);
}
else{
if(x>=vxl&&x<=vxr&&y>=vyb&&y<=vyt)
drawDot(x,y,r,g,b);
}
if(d>=0){
x--;
d+=IncE;
}
else{
x--;
y++;
d+=IncSE;
}
}
return;
}
// Draw line for dx<0 and dy<0 左斜上
void drawLine4(double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float vyt, bool xy_interchange, float r , float g, float b)
{
if(xy_interchange){
swap(x0,y0);
swap(x1,y1);
}
int A,B;
A=y1-y0;
B=x0-x1;
int IncE,IncNE;
IncE=2*A;
IncNE=2*(A+B);
int d=2*A+B;
int x=x0,y=y0;
while(x>=x1){
if(xy_interchange)
{
if(y>=vxl&&y<=vxr&&x>=vyb&&x<=vyt)
drawDot(y,x,r,g,b);
}
else
{
if(x>=vxl&&x<=vxr&&y>=vyb&&y<=vyt)
drawDot(x,y,r,g,b);
}
if(d<=0){
x--;
d-=IncE;
}
else{
x--;
y--;
d-=IncNE;
}
}
return;
}
// Draw line for dx==0 or dy==0
void drawparr(double dx,double x0, double x1, double y0, double y1,float vxl,float vxr ,float vyb,float vyt,float r, float g, float b){
if(y0>=vyb&&y0<=vyt){
if(dx>0)
{
int tx=x0;
while(tx<=x1)
{
if(tx>=vxl&&tx<=vxr)
drawDot(tx,y0,r,g,b);
tx++;
}
}
else if(dx<0)
{
int tx=x0;
while(tx>=x1)
{
if(tx>=vxl&&tx<=vxr)
drawDot(tx,y0,r,g,b);
tx--;
}
}
}
}
void drawnor(double dy, double x0, double x1, double y0, double y1,float vxl,float vxr,float vyb,float vyt , float r, float g, float b){
if(x0>=vxl&&x0<=vxr){
if(dy>0)
{
int ty=y0;
while(ty<=y1)
{
if(ty>=vyb&&ty<=vyt)
drawDot(x0,ty,r,g,b);
ty++;
}
}
else if(dy<0)
{
int ty=y0;
while(ty>=y1)
{
if(ty>=vyb&&ty<=vyt)
drawDot(x0,ty,r,g,b);
ty--;
}
}
}
}
// Display function
void displayFunc(void){
// clear the entire window to the background color
glClear(GL_COLOR_BUFFER_BIT);
bool IsExit;
IsExit=false;
// draw the contents!!! Iterate your object's data structure!
glClearColor(0.0, 0.0, 0.0, 0.0);
while (!IsExit)
{
// draw the contents!!! Iterate your object's data structure!
// flush the queue to actually paint the dots on the opengl window
ReadInput(IsExit);
glFlush();
}
// infile.close();
//exit(0);
}
// Main
void main(int ac, char** av) {
int winSizeX, winSizeY;
string name;
//initial();
if(ac == 3) {
winSizeX = atoi(av[1]);
winSizeY = atoi(av[2]);
}
else { // default window size
winSizeX = 800;
winSizeY = 600;
}
width = winSizeX;
height = winSizeY;
// initialize OpenGL utility toolkit (glut)
glutInit(&ac, av);
// single disply and RGB color mapping
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowSize(winSizeX, winSizeY); // set window size
glutInitWindowPosition(0, 0); // set window position on screen
glutCreateWindow("Lab2 Window"); // set window title
// set up the mouse and keyboard callback functions
//glutKeyboardFunc(myKeyboard); // register the keyboard action function
// displayFunc is called whenever there is a need to redisplay the window,
// e.g., when the window is exposed from under another window or when the window is de-iconified
glutDisplayFunc(displayFunc); // register the redraw function
// set background color
glClearColor(0.0, 0.0, 0.0, 0.0); // set the background to black
glClear(GL_COLOR_BUFFER_BIT); // clear the buffer
// misc setup
glMatrixMode(GL_PROJECTION); // setup coordinate system
glLoadIdentity();
gluOrtho2D(0, winSizeX, 0, winSizeY);
glShadeModel(GL_FLAT);
glFlush();
glutMainLoop();
}
数字媒体二
最新推荐文章于 2024-07-23 13:09:41 发布