数字媒体二

#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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值