• C++实现数字媒体二维图像变换


    C++实现数字媒体二维图像变换

    必备环境

    • glut.h 头文件
    • glut32.lib 对象文件库
    • glut32.dll 动态连接库

    程序说明

    C++实现了用glut画正方形,画三角形的功能。并附带放大缩小,旋转,平移的功能。同时实现了填充颜色这个功能。

    操作说明

    重要说明

    define CLIP_METHOD 0
    该参数为0时,切割方式为 多边形 切割(默认)
    该参数为1时,切割方式为 点 切割
    define FILL_ENABLE !CLIP_METHOD&&1
    该参数为1并且启用多边形切割时,启用填充对象(默认)
    该参数为0时,不填充对象,仅描绘边界
    define READ_MULTI_FILE 0
    该参数为0时,读取文件为单文件,窗口可移动
    该参数为1时,读取文件为多文件,在任意键盘控制确认显示下一个,窗口可移动(默认)

    指令说明

    • reset :把变换矩阵重置为单位矩阵
    • scale :把变换矩阵进行相应的放大缩小
    • rotate : 把变换矩阵进行相应的旋转
    • translate : 把变换矩阵进行相应的平移
    • square :根据变换矩阵创建一个矩形对象
    • triangle :根据变换矩阵创建一个三角形对象
    • clearData :清空所有的对象数据
    • clearScreen :清空屏幕
    • end : 结束程序

    函数说明

    void initial()
    输出程序信息,并提示如何输入

    void scale(float sx, float sy)
    改变变换矩阵进行相应放大缩小

    void rotate(float degree)
    改变变换矩阵进行相应的角度旋转

    void translate(float tx, float ty)
    改变变换矩阵进行相应的平移变换

    void reset()
    重置变换矩阵为单位矩阵

    void square()
    根据变换矩阵创建一个矩形对象并存储

    void triangle()
    根据变换矩阵创建一个三角形对象并存储

    void view(float wxl, float wxr, float wyb, float wyt, float vxl, float vxr, float vyb, float vyt)
    根据参数把对象坐标系的区域进行投影到视图坐标系下,同时把裁剪非可见区域,并对投影区域进行颜色填充

    void clearData()
    清除全部对象的数据

    void clearScreen()
    清空整个视窗屏幕

    void displayFunc(void)
    视窗初始化和恢复的时候调用的函数

    void ReadInput(bool& IsExit)
    从标准输入输出中读取指令

    void Matrix_Multi_Matrix(float a[][CTM_SIZE], float b[][CTM_SIZE], float c[][CTM_SIZE])
    矩阵乘法,c = a * b

    void update_CurMatrix(float resource[][CTM_SIZE], float destination[][CTM_SIZE])
    更新变换矩阵

    void update_WVM(int sx, int sy, int tx, int ty)
    更新投影函数

    void AddtoSquareStore(float matrix[][CTM_SIZE])
    增加一个矩形对象到仓库中

    void AddtoTriangleStore(float matrix[][CTM_SIZE])
    增加一个三角形到仓库中

    void GetFromSquareStore(int index, float destination[][CTM_SIZE])
    从仓库中获取一个矩形对象

    void GetFromTriangleStore(int index, float destination[][CTM_SIZE])
    从仓库中获取一个三角形对象

    void DrawSquareDirect(int matrix[][CTM_SIZE])
    直接绘制出仓库中最新的矩形对象

    void DrawSquareByindex(int index)
    根据序号绘制出仓库中指定的矩形对象

    void DrawTriangleDirect(int matrix[][CTM_SIZE])
    直接绘制出仓库中最新的三角形对象

    void drawDot(int x, int y)
    在视窗坐标系中绘制一个点

    void DrawLine(int x0, int x1, int y0, int y1)
    各个方向均可使用,绘制一条直线

    void drawLine0(int x0, int x1, int y0, int y1)
    绘制直线函数,决定调用哪一个直线函数

    void drawLine1(int x0, int x1, int y0, int y1, bool xy_interchange)
    绘制一号区域和五号区域的直线

    void drawLine2(int x0, int x1, int y0, int y1, bool xy_interchange)
    绘制二号区域和六号区域的直线

    void drawLine3(int x0, int x1, int y0, int y1, bool xy_interchange)
    绘制三号区域和七号区域的直线

    void drawLine4(int x0, int x1, int y0, int y1, bool xy_interchange)
    绘制四号区域和八号区域的直线

    void ReadFile(bool& IsExit)
    从文件中批量读取指令

    void DrawFrame()
    绘制投影区域的边框

    bool DotToDraw(const int& x, const int& y)
    决定这个点是否绘制

    void redraw()
    重绘整个视窗,恢复显示的时候调用

    void FillPolygon(int PointVectorSize, string object)
    填充函数,根据object决定填充颜色。方式是通过遍历一个多边形存储的边,以y轴从上往下扫描边的两个端点,然后水平绘制一条直线。颜色的选择是从颜色库中轮询选择。

    void DrawHorizontalLine(int x0, int x1, int y)
    绘制一条水平直线

    template void printMatrix(T matrix, int row, int col, string str)*
    打印矩阵函数,debug时使用

    vector( pair(int, int) ) ClipPolygon(const vector( pair(int, int) )& PointVector, string boundary)
    多边形剪切函数,boundary指定剪切方向。容器中存储一个多边形的各个点,如果需要被裁剪,这容器中的点会变成裁剪边界的点。

    bool cmp_pair(const pair(int, int)& a, const pair(int, int)& b)
    比较函数,对点进行排序时调用

    void myKeyboard(unsigned char key, int x, int y)
    键盘回调函数

    运行效果

    F
    A
    B
    C
    D
    E

    完整代码

    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include "glut.h"
    using namespace std;
    
    #pragma region Data
    
    #define CLIP_METHOD 0
    // 0 for compile to clip polygon
    // 1 for compile to clip dot
    #define FILL_ENABLE !CLIP_METHOD&&1
    // only enalbe it when CLIP_METHOD is 0 
    #define READ_MULTI_FILE 1
    
    #define CTM_SIZE 3
    #define MAX_SQUARE 20
    #define MAX_TRIANGLE 20
    #define MAX_LINE 200
    // MAX_LINE >= MAX_SQUARE * 4 + MAX_TRIANGLE * 3 + MAX_VIEW_IN_FIN * 4
    #define PI 3.14159265
    //const float PI = acos(-1);
    #define MAX_COLOR 8
    #define MAX_FILL_LINE 1000
    #define MAX_FILE 6
    
    struct line_structure{
    	int x0, x1, y0, y1;
    };
    
    struct line_data{
    	int x, y;
    	line_data* next;
    	line_data(int _x = -1, int _y = -1){
    		x = _x;
    		y = _y;
    		next = NULL;
    	}
    };
    
    struct point{
    	float x, y;
    	float z;
    };
    
    struct square_struct{
    	point right_up;
    	point left_up;
    	point left_down;
    	point right_down;
    }SquareStore[MAX_SQUARE];
    
    struct triangle_struct{
    	point first;
    	point second;
    	point third;
    }TriangleStore[MAX_TRIANGLE];
    
    struct fill_line_struct{
    	int x0, x1, y;
    	fill_line_struct(int _x0, int _x1, int _y){
    		x0 = _x0;
    		x1 = _x1;
    		y = _y;
    	}
    };
    
    struct frame_struct{
    	int vxl, vxr, vyb, vyt;
    	frame_struct(int _vxl, int _vxr, int _vyb, int _vyt){
    		vxl = _vxl;
    		vxr = _vxr;
    		vyb = _vyb;
    		vyt = _vyt;
    	}
    };
    vector<frame_struct> frame_store;
    
    struct color_struct{
    	float r, g, b;
    	color_struct(float _r = 0, float _g = 0, float _b = 0){
    		r = _r;
    		g = _g;
    		b = _b;
    	}
    };
    const color_struct Color[MAX_COLOR] = { { 0.0, 0.0, 0.0 },	// black for default 
    								  { 0.0, 0.0, 1.0 },	// blue for triangle
    								  { 1.0, 0.0, 0.0 },	// red for square
    								  { 1.0, 0.5, 0.0 },	// orange for square 
    								  { 1.0, 1.0, 0.0 },	// yellow for square
    								  { 0.0, 1.0, 0.0 },	// green for square
    								  { 0.0, 1.0, 1.0 },	// light blue for square 
    								  { 1.0, 0.0, 1.0 } };	// purple for square
    int color_index = 2;
    
    string file_list[MAX_FILE] = { "hw2E.in", "hw2B.in", "hw2A.in", "hw2D.in", "hw2F.in", "hw2C.in" };
    int cur_file = 0;
    
    int height, width;
    int Frame[4];
    /*
     * Frame[0] = vxl;
     * Frame[1] = vxr;
     * Frame[2] = vyb;
     * Frame[3] = vyt;
     */
    float current_matrix[CTM_SIZE][CTM_SIZE];
    int WVM[CTM_SIZE][CTM_SIZE] = { { 15, 0, 100 }, { 0, 15, 100 }, { 0, 0, 1 } };
    
    line_structure line[MAX_LINE];
    line_data line_start[MAX_LINE];
    int line_color[MAX_LINE];
    line_data* lcp;
    line_data* temp;
    vector<fill_line_struct> fill_line;
    vector<int> fill_line_color;
    
    int num_square = 0;
    int num_triangle = 0;
    int num_line = 0;
    int num_fill_line = 0;
    
    const float default_r = 255.0;
    const float default_g = 255.0;
    const float default_b = 255.0;
    float r = 1.0;
    float g = 0.0;
    float b = 0.0;
    float alpha = 0.0;
    
    bool IsExit = false;
    
    enum ScanFlag{ odd, even };
    
    #pragma endregion
    
    #pragma region FunctionDefinition
    
    void initial();
    void scale(float sx, float sy);
    void rotate(float degree);
    void translate(float tx, float ty);
    void reset();
    void square();
    void triangle();
    void view(float wxl, float wxr, float wyb, float wyt, float vxl, float vxr, float vyb, float vyt);
    void clearData();
    void clearScreen();
    void displayFunc(void);
    void ReadInput(bool& IsExit);
    void Matrix_Multi_Matrix(float a[][CTM_SIZE], float b[][CTM_SIZE], float c[][CTM_SIZE]);
    void update_CurMatrix(float resource[][CTM_SIZE], float destination[][CTM_SIZE]);
    void update_WVM(int sx, int sy, int tx, int ty);
    void AddtoSquareStore(float matrix[][CTM_SIZE]);
    void AddtoTriangleStore(float matrix[][CTM_SIZE]);
    void GetFromSquareStore(int index, float destination[][CTM_SIZE]);
    void GetFromTriangleStore(int index, float destination[][CTM_SIZE]);
    void DrawSquareDirect(int matrix[][CTM_SIZE]);
    void DrawSquareByindex(int index);
    void DrawTriangleDirect(int matrix[][CTM_SIZE]);
    void drawDot(int x, int y);
    void DrawLine(int x0, int x1, int y0, int y1);
    void drawLine0(int x0, int x1, int y0, int y1);
    void drawLine1(int x0, int x1, int y0, int y1, bool xy_interchange);
    void drawLine2(int x0, int x1, int y0, int y1, bool xy_interchange);
    void drawLine3(int x0, int x1, int y0, int y1, bool xy_interchange);
    void drawLine4(int x0, int x1, int y0, int y1, bool xy_interchange);
    void ReadFile(bool& IsExit);
    void DrawFrame();
    bool DotToDraw(const int& x, const int& y);
    void redraw();
    vector<pair<int, int>> ClipPolygon(const vector<pair<int, int>>& PointVector, string boundary);
    void FillPolygon(int PointVectorSize, string object);
    bool cmp_pair(const pair<int, int>& a, const pair<int, int>& b);
    void DrawHorizontalLine(int x0, int x1, int y);
    template<class T> void printMatrix(T* matrix, int row, int col, string str);
    void myKeyboard(unsigned char key, int x, int y);
    
    #pragma endregion
    
    #pragma region FunctionImplement
    
    template<class T>
    void printMatrix(T* matrix, int row, int col, string str){
    	cout << endl;
    	cout << str << " : " << endl;
    	for (int i = 0; i < row; i++){
    		cout << "	[ ";
    		for (int j = 0; j < col; j++){
    			cout << matrix[i][j] << ", ";
    		}
    		cout << " ]" << endl;
    	}
    }
    
    // Set current transform matrix to Identity
    void reset(){
    	for (int i = 0; i < CTM_SIZE; i++){
    		for (int j = 0; j < CTM_SIZE; j++){
    			if (i == j)
    				current_matrix[i][j] = 1.0;
    			else
    				current_matrix[i][j] = 0;
    		}
    	}
    	printMatrix(current_matrix, 3, 3, "current_matrix");
    }
    
    // Multiply current matrix by scaling matrix
    void scale(float sx, float sy){
    	float scaling_matrix[CTM_SIZE][CTM_SIZE]
    		= { { sx, 0, 0 },
    			{ 0, sy, 0 },
    			{ 0, 0, 1  } };
    
    	float new_matrix[CTM_SIZE][CTM_SIZE];
    
    	Matrix_Multi_Matrix(scaling_matrix, current_matrix, new_matrix);
    
    	update_CurMatrix(new_matrix, current_matrix);
    
    	printMatrix(current_matrix, 3, 3, "current_matrix");
    
    }
    
    // Multiply current matrix by rotation matrix
    void rotate(float degree){
    	float rad = degree * PI / 180.0;
    	float rotation_matrix[CTM_SIZE][CTM_SIZE]
    		= { { cos(rad), -sin(rad), 0 },
    			{ sin(rad), cos(rad),  0 },
    			{ 0,		0,		   1 } };
    
    	//printMatrix(rotation_matrix, 3, 3, "rotation_matrix");
    
    	float new_matrix[CTM_SIZE][CTM_SIZE];
    
    	Matrix_Multi_Matrix(rotation_matrix, current_matrix, new_matrix);
    
    	update_CurMatrix(new_matrix, current_matrix);
    	
    	printMatrix(current_matrix, 3, 3, "current_matrix");
    
    }
    
    // Multiply current matrix by translation matrix
    void translate(float tx, float ty){
    	float translate_matrix[CTM_SIZE][CTM_SIZE]
    		= { { 1, 0, tx },
    			{ 0, 1, ty },
    			{ 0, 0, 1  } };
    
    	float new_matrix[CTM_SIZE][CTM_SIZE];
    
    	Matrix_Multi_Matrix(translate_matrix, current_matrix, new_matrix);
    
    	update_CurMatrix(new_matrix, current_matrix);
    
    	printMatrix(current_matrix, 3, 3, "current_matrix");
    
    }
    
    // Two 3 * 3 Matrixs Multiplication
    void Matrix_Multi_Matrix(float a[][CTM_SIZE], float b[][CTM_SIZE], float c[][CTM_SIZE]){
    	float multi_sum = 0;
    	for (int i = 0; i < CTM_SIZE; i++){
    		for (int j = 0; j < CTM_SIZE; j++){
    			multi_sum = 0;
    			for (int k = 0; k < CTM_SIZE; k++){
    				multi_sum += b[k][j] * a[i][k];
    			}
    			c[i][j] = multi_sum;
    		}
    	}
    }
    
    // update the current_matrix
    void update_CurMatrix(float resource[][CTM_SIZE], float destination[][CTM_SIZE]){
    	for (int i = 0; i < CTM_SIZE; i++){
    		for (int j = 0; j < CTM_SIZE; j++){
    			destination[i][j] = resource[i][j];
    		}
    	}
    }
    
    // Create a square and save it
    void square(){
    	float org_square[4][CTM_SIZE]
    		= { { 1,  1,  1 },
    			{ -1, 1,  1 },
    			{ -1, -1, 1 },
    			{ 1,  -1, 1 } };
    
    	float WorldCoord_square[4][CTM_SIZE];
    
    	float multi_sum = 0;
    	for (int i = 0; i < 4; i++){
    		for (int j = 0; j < CTM_SIZE; j++){
    			multi_sum = 0;
    			for (int k = 0; k < CTM_SIZE; k++){
    				multi_sum += org_square[i][k] * current_matrix[j][k];
    			}
    			WorldCoord_square[i][j] = multi_sum;
    		}
    	}
    
    	AddtoSquareStore(WorldCoord_square);
    	num_square++;
    
    	printMatrix(WorldCoord_square, 4, 3, "WorldCoord_square");
    
    }
    
    // Add a new square to SquareStore
    void AddtoSquareStore(float matrix[][CTM_SIZE]){
    	SquareStore[num_square].right_up.x = matrix[0][0];
    	SquareStore[num_square].right_up.y = matrix[0][1];
    	SquareStore[num_square].right_up.z = matrix[0][2];
    
    	SquareStore[num_square].left_up.x = matrix[1][0];
    	SquareStore[num_square].left_up.y = matrix[1][1];
    	SquareStore[num_square].left_up.z = matrix[1][2];
    
    	SquareStore[num_square].left_down.x = matrix[2][0];
    	SquareStore[num_square].left_down.y = matrix[2][1];
    	SquareStore[num_square].left_down.z = matrix[2][2];
    
    	SquareStore[num_square].right_down.x = matrix[3][0];
    	SquareStore[num_square].right_down.y = matrix[3][1];
    	SquareStore[num_square].right_down.z = matrix[3][2];
    
    }
    
    // Show all objects on the screen
    void view(float wxl, float wxr, float wyb, float wyt, float vxl, float vxr, float vyb, float vyt){
    	int scaling_x = (int)((vxr - vxl) / (wxr - wxl));
    	int scaling_y = (int)((vyt - vyb) / (wyt - wyb));
    	int shift_x = (int)(vxl - scaling_x * wxl);
    	int shift_y = (int)(vyb - scaling_y * wyb);
    	update_WVM(scaling_x, scaling_y, shift_x, shift_y);
    
    	printMatrix(WVM, 3, 3, "WVM");
    
    	float WorldCoord_matrix[4][CTM_SIZE];
    	int ScreenCoord_matrix[4][CTM_SIZE];
    
    	//Set Frame
    	Frame[0] = (int)vxl;
    	Frame[1] = (int)vxr;
    	Frame[2] = (int)vyb;
    	Frame[3] = (int)vyt;
    	frame_store.push_back(frame_struct(Frame[0], Frame[1], Frame[2], Frame[3]));
    	
    	//Draw Square
    	r = 1.0;	g = 0.0;	b = 0.0;
    	float multi_sum = 0;
    	int count = 0;
    	while (count < num_square){
    		GetFromSquareStore(count, WorldCoord_matrix);
    		printMatrix(WorldCoord_matrix, 4, 3, "WorldCoord_matrix");
    		for (int i = 0; i < 4; i++){
    			for (int j = 0; j < CTM_SIZE; j++){
    				multi_sum = 0;
    				for (int k = 0; k < CTM_SIZE; k++){
    					multi_sum += WorldCoord_matrix[i][k] * WVM[j][k];
    				}
    				ScreenCoord_matrix[i][j] = (int)multi_sum;
    			}
    		}
    		printMatrix(ScreenCoord_matrix, 4, 3, "ScreenCoord_matrix");
    		DrawSquareDirect(ScreenCoord_matrix);
    		//void DrawSquareByindex(count);
    		count++;
    	}
    	
    	//Draw Triangle
    	r = 0.0;	g = 0.0;	b = 1.0;
    	count = 0;
    	while (count < num_triangle){
    		GetFromTriangleStore(count, WorldCoord_matrix);
    		printMatrix(WorldCoord_matrix, 3, 3, "WorldCoord_matrix");
    		for (int i = 0; i < 3; i++){
    			for (int j = 0; j < CTM_SIZE; j++){
    				multi_sum = 0;
    				for (int k = 0; k < CTM_SIZE; k++){
    					multi_sum += WorldCoord_matrix[i][k] * WVM[j][k];
    				}
    				ScreenCoord_matrix[i][j] = (int)multi_sum;
    			}
    		}
    		printMatrix(ScreenCoord_matrix, 3, 3, "ScreenCoord_matrix");
    		DrawTriangleDirect(ScreenCoord_matrix);
    		count++;
    	}
    
    	// Draw Frame
    	r = 0.0;	g = 0.0;	b = 0.0;
    	DrawFrame();
    
    	return;
    }
    
    // Draw a frame
    void DrawFrame(){
    	temp = &line_start[num_line];
    	line_color[num_line] = 0;
    	DrawLine(Frame[0], Frame[1], Frame[2], Frame[2]);
    	num_line++;
    
    	temp = &line_start[num_line];
    	line_color[num_line] = 0;
    	DrawLine(Frame[1], Frame[1], Frame[2], Frame[3]);
    	num_line++;
    
    	temp = &line_start[num_line];
    	line_color[num_line] = 0;
    	DrawLine(Frame[1], Frame[0], Frame[3], Frame[3]);
    	num_line++;
    
    	temp = &line_start[num_line];
    	line_color[num_line] = 0;
    	DrawLine(Frame[0], Frame[0], Frame[3], Frame[2]);
    	num_line++;
    }
    
    // Draw a square
    void DrawSquareDirect(int matrix[][CTM_SIZE]){
    #if CLIP_METHOD
    	temp = &line_start[num_line];
    	line_color[num_line] = 2;
    	DrawLine(matrix[1][0], matrix[0][0], matrix[1][1], matrix[0][1]);
    	num_line++;
    
    	temp = &line_start[num_line];
    	line_color[num_line] = 2;
    	DrawLine(matrix[0][0], matrix[3][0], matrix[0][1], matrix[3][1]);
    	num_line++;
    
    	temp = &line_start[num_line];
    	line_color[num_line] = 2;
    	DrawLine(matrix[3][0], matrix[2][0], matrix[3][1], matrix[2][1]);
    	num_line++;
    
    	temp = &line_start[num_line];
    	line_color[num_line] = 2;
    	DrawLine(matrix[2][0], matrix[1][0], matrix[2][1], matrix[1][1]);
    	num_line++;
    #else
    	vector<pair<int, int>> PointVector;
    	PointVector.push_back(make_pair(matrix[1][0], matrix[1][1]));
    	PointVector.push_back(make_pair(matrix[0][0], matrix[0][1]));
    	PointVector.push_back(make_pair(matrix[3][0], matrix[3][1]));
    	PointVector.push_back(make_pair(matrix[2][0], matrix[2][1]));
    	PointVector.push_back(make_pair(matrix[1][0], matrix[1][1]));
    	
    	PointVector = ClipPolygon(PointVector, "left");
    	PointVector = ClipPolygon(PointVector, "bottom");
    	PointVector = ClipPolygon(PointVector, "right");
    	PointVector = ClipPolygon(PointVector, "top");
    
    	for(int i = 1; i < PointVector.size(); i++){
    		temp = &line_start[num_line];
    		line_color[num_line] = 2;
    		DrawLine(PointVector[i - 1].first, PointVector[i].first, PointVector[i - 1].second, PointVector[i].second);
    		num_line++;
    	}
    #if FILL_ENABLE
    	FillPolygon(PointVector.size(), "square");
    #endif
    #endif
    }
    
    // Clip the Polygon by one side
    vector<pair<int, int>> ClipPolygon(const vector<pair<int, int>>& PointVector, string boundary){
    	pair<int, int> PointS, PointP;
    	vector<pair<int, int>> NewPointVector;
    	
    	// 1-st pass
    	if(boundary == "left"){
    		for(int i = 1; i < PointVector.size(); i++){
    			PointS = PointVector[i - 1];
    			PointP = PointVector[i];
    			// Rule 1
    			if(PointS.first >= Frame[0] && PointP.first >= Frame[0]){
    				NewPointVector.push_back(PointP);
    			}
    			// Rule 2
    			else if(PointS.first >= Frame[0] && PointP.first < Frame[0]){
    				int left_y = (int)((PointS.second - PointP.second)*1.0 / (PointS.first - PointP.first)*(Frame[0] - PointP.first) + PointP.second);
    				NewPointVector.push_back(make_pair(Frame[0], left_y));
    			}
    			// Rule 4
    			else if(PointS.first < Frame[0] && PointP.first >= Frame[0]){
    				int left_y = (int)((PointS.second - PointP.second)*1.0 / (PointS.first - PointP.first)*(Frame[0] - PointP.first) + PointP.second);
    				NewPointVector.push_back(make_pair(Frame[0], left_y));
    				NewPointVector.push_back(PointP);
    			}
    		}
    		if(!NewPointVector.empty())
    			NewPointVector.push_back(NewPointVector[0]);
    	}
    	// 2-nd pass
    	else if(boundary == "bottom"){
    		for(int i = 1; i < PointVector.size(); i++){
    			PointS = PointVector[i - 1];
    			PointP = PointVector[i];
    			// Rule 1
    			if(PointS.second >= Frame[2] && PointP.second >= Frame[2]){
    				NewPointVector.push_back(PointP);
    			}
    			// Rule 2
    			else if(PointS.second >= Frame[2] && PointP.second < Frame[2]){
    				int bottom_x = (int)((PointS.first - PointP.first)*1.0 / (PointS.second - PointP.second)*(Frame[2] - PointP.second) + PointP.first);
    				NewPointVector.push_back(make_pair(bottom_x, Frame[2]));
    			}
    			// Rule 4
    			else if(PointS.second < Frame[2] && PointP.second >= Frame[2]){
    				int bottom_x = (int)((PointS.first - PointP.first)*1.0 / (PointS.second - PointP.second)*(Frame[2] - PointP.second) + PointP.first);
    				NewPointVector.push_back(make_pair(bottom_x, Frame[2]));
    				NewPointVector.push_back(PointP);
    			}
    		}
    		if(!NewPointVector.empty())
    			NewPointVector.push_back(NewPointVector[0]);
    	}
    	// 3-rd pass
    	else if(boundary == "right"){
    		for(int i = 1; i < PointVector.size(); i++){
    			PointS = PointVector[i - 1];
    			PointP = PointVector[i];
    			// Rule 1
    			if(PointS.first <= Frame[1] && PointP.first <= Frame[1]){
    				NewPointVector.push_back(PointP);
    			}
    			// Rule 2
    			else if(PointS.first <= Frame[1] && PointP.first > Frame[1]){
    				int right_y = (int)((PointS.second - PointP.second)*1.0 / (PointS.first - PointP.first)*(Frame[1] - PointP.first) + PointP.second);
    				NewPointVector.push_back(make_pair(Frame[1], right_y));
    			}
    			// Rule 4
    			else if(PointS.first > Frame[1] && PointP.first <= Frame[1]){
    				int right_y = (int)((PointS.second - PointP.second)*1.0 / (PointS.first - PointP.first)*(Frame[1] - PointP.first) + PointP.second);
    				NewPointVector.push_back(make_pair(Frame[1], right_y));
    				NewPointVector.push_back(PointP);
    			}
    		}
    		if(!NewPointVector.empty())
    			NewPointVector.push_back(NewPointVector[0]);
    	}
    	// 4-th pass
    	else if(boundary == "top"){
    		for(int i = 1; i < PointVector.size(); i++){
    			PointS = PointVector[i - 1];
    			PointP = PointVector[i];
    			// Rule 1
    			if(PointS.second <= Frame[3] && PointP.second <= Frame[3]){
    				NewPointVector.push_back(PointP);
    			}
    			// Rule 2
    			else if(PointS.second <= Frame[3] && PointP.second > Frame[3]){
    				int top_x = (int)((PointS.first - PointP.first)*1.0 / (PointS.second - PointP.second)*(Frame[3] - PointP.second) + PointP.first);
    				NewPointVector.push_back(make_pair(top_x, Frame[3]));
    			}
    			// Rule 4
    			else if(PointS.second > Frame[3] && PointP.second <= Frame[3]){
    				int top_x = (int)((PointS.first - PointP.first)*1.0 / (PointS.second - PointP.second)*(Frame[3] - PointP.second) + PointP.first);
    				NewPointVector.push_back(make_pair(top_x, Frame[3]));
    				NewPointVector.push_back(PointP);
    			}
    		}
    		if(!NewPointVector.empty())
    			NewPointVector.push_back(NewPointVector[0]);
    	}
    
    	return NewPointVector;
    }
    
    // Draw a square
    void DrawSquareByindex(int index){
    	temp = &line_start[num_line];
    	DrawLine(SquareStore[index].left_up.x, SquareStore[index].right_up.x, 
    			 SquareStore[index].left_up.y, SquareStore[index].right_up.y);
    	num_line++;
    
    	temp = &line_start[num_line];
    	DrawLine(SquareStore[index].right_up.x, SquareStore[index].right_down.x,
    			SquareStore[index].right_up.y, SquareStore[index].right_down.y);
    	num_line++;
    
    	temp = &line_start[num_line];
    	DrawLine(SquareStore[index].right_down.x, SquareStore[index].left_down.x,
    			SquareStore[index].right_down.y, SquareStore[index].left_down.y);
    	num_line++;
    
    	temp = &line_start[num_line];
    	DrawLine(SquareStore[index].left_down.x, SquareStore[index].left_up.x,
    			SquareStore[index].left_down.y, SquareStore[index].left_up.y);
    	num_line++;
    }
    
    // Draw a triangle
    void DrawTriangleDirect(int matrix[][CTM_SIZE]){
    #if CLIP_METHOD
    	temp = &line_start[num_line];
    	line_color[num_line] = 1;
    	DrawLine(matrix[0][0], matrix[1][0], matrix[0][1], matrix[1][1]);
    	num_line++;
    
    	temp = &line_start[num_line];
    	line_color[num_line] = 1;
    	DrawLine(matrix[1][0], matrix[2][0], matrix[1][1], matrix[2][1]);
    	num_line++;
    
    	temp = &line_start[num_line];
    	line_color[num_line] = 1;
    	DrawLine(matrix[2][0], matrix[0][0], matrix[2][1], matrix[0][1]);
    	num_line++;
    #else
    	vector<pair<int, int>> PointVector;
    	PointVector.push_back(make_pair(matrix[0][0], matrix[0][1]));
    	PointVector.push_back(make_pair(matrix[1][0], matrix[1][1]));
    	PointVector.push_back(make_pair(matrix[2][0], matrix[2][1]));
    	PointVector.push_back(make_pair(matrix[0][0], matrix[0][1]));
    
    	PointVector = ClipPolygon(PointVector, "left");
    	PointVector = ClipPolygon(PointVector, "bottom");
    	PointVector = ClipPolygon(PointVector, "right");
    	PointVector = ClipPolygon(PointVector, "top");
    
    	for(int i = 1; i < PointVector.size(); i++){
    		temp = &line_start[num_line];
    		line_color[num_line] = 1;
    		DrawLine(PointVector[i - 1].first, PointVector[i].first, PointVector[i - 1].second, PointVector[i].second);
    		num_line++;
    	}
    #if FILL_ENABLE
    	FillPolygon(PointVector.size(), "triangle");
    #endif
    #endif
    }
    
    // Judge wheather to draw dot
    bool DotToDraw(const int& x, const int& y){
    	if (x >= Frame[0] && x <= Frame[1] && y >= Frame[2] && y <= Frame[3]){
    		return true;
    	}
    	return false;
    }
    
    // draw a dot at location with integer coordinates (x,y)
    void drawDot(int x, int y){
    	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);
    	glVertex2i(x, y);
    
    	glEnd();
    }
    
    // Draw a line in any direction
    void DrawLine(int x0, int x1, int y0, int y1) {
    	int max_dis = abs(x1 - x0);
    	max_dis = max_dis > abs(y0 - y1) ? max_dis : abs(y0 - y1);
    	lcp = temp;
    	if (max_dis != 0) {
    		for (int i = 0; i < max_dis; ++i) {
    			int new_p_x = x0 + i * (x1 - x0) / max_dis;
    			int new_p_y = y0 + i * (y1 - y0) / max_dis;
    #if CLIP_METHOD
    			if (DotToDraw(new_p_x, new_p_y)){
    				drawDot(new_p_x, new_p_y);
    				lcp->next = new line_data(new_p_x, new_p_y);
    				lcp = lcp->next;
    			}
    #else
    			drawDot(new_p_x, new_p_y);
    			lcp->next = new line_data(new_p_x, new_p_y);
    			lcp = lcp->next;
    #endif
    		}
    	}
    	glFlush();
    	return;
    }
    
    // Judge to call which drawLine function to draw a line
    void drawLine0(int x0, int x1, int y0, int y1){
    	int dx = x1 - x0;
    	int dy = y1 - y0;
    	if(dx >= 0 && dy > 0 && abs(dx) < abs(dy)){
    		drawLine1(line[num_line].x0, line[num_line].x1, line[num_line].y0, line[num_line].y1, false);
    	}
    	else if(dx > 0 && dy >= 0 && abs(dx) >= abs(dy)){
    		drawLine2(line[num_line].x0, line[num_line].x1, line[num_line].y0, line[num_line].y1, false);
    	}
    	else if(dx > 0 && dy <= 0 && abs(dx) > abs(dy)){
    		drawLine3(line[num_line].x0, line[num_line].x1, line[num_line].y0, line[num_line].y1, false);
    	}
    	else if(dx >= 0 && dy < 0 && abs(dx) <= abs(dy)){
    		drawLine4(line[num_line].x0, line[num_line].x1, line[num_line].y0, line[num_line].y1, false);
    	}
    	else if(dx <= 0 && dy < 0 && abs(dx) < abs(dy)){
    		drawLine1(line[num_line].x0, line[num_line].x1, line[num_line].y0, line[num_line].y1, true);
    	}
    	else if(dx < 0 && dy <= 0 && abs(dx) >= abs(dy)){
    		drawLine2(line[num_line].x0, line[num_line].x1, line[num_line].y0, line[num_line].y1, true);
    	}
    	else if(dx < 0 && dy >= 0 && abs(dx) > abs(dy)){
    		drawLine3(line[num_line].x0, line[num_line].x1, line[num_line].y0, line[num_line].y1, true);
    	}
    	else{
    		drawLine4(line[num_line].x0, line[num_line].x1, line[num_line].y0, line[num_line].y1, true);
    	}
    	num_line++;
    }
    
    // Draw line for dx>0 and dy>0
    void drawLine1(int x0, int x1, int y0, int y1, bool xy_interchange){
    	if(xy_interchange){
    		int change = x0;	x0 = x1;	x1 = change;
    		change = y0;	y0 = y1;	y1 = change;
    	}
    	int x = x1;
    	int y = y1;
    	int a = y1 - y0;
    	int b = -(x1 - x0);
    	int d = -a - 2 * b;
    	int IncE = -2 * b;
    	int IncNE = -2 * a - 2 * b;
    	line_start[num_line] = line_data(x, y);
    	lcp = &line_start[num_line];
    	while(y >= y0){
    		lcp->next = new line_data(x, y);
    		lcp = lcp->next;
    		drawDot(x, y);
    		if(d <= 0){
    			y--;
    			d += IncE;
    		}
    		else{
    			x--;
    			y--;
    			d += IncNE;
    		}
    	}
    	glFlush();
    	return;
    }
    
    // Draw line for dx>0 and dy<0
    void drawLine2(int x0, int x1, int y0, int y1, bool xy_interchange){
    	if(xy_interchange){
    		int change = x0;	x0 = x1;	x1 = change;
    		change = y0;	y0 = y1;	y1 = change;
    	}
    	int x = x0;
    	int y = y0;
    	int a = y1 - y0;
    	int b = -(x1 - x0);
    	int d = 2 * a + b;
    	int IncE = 2 * a;
    	int IncNE = 2 * a + 2 * b;
    	line_start[num_line] = line_data(x, y);
    	lcp = &line_start[num_line];
    	while(x <= x1){
    		lcp->next = new line_data(x, y);
    		lcp = lcp->next;
    		drawDot(x, y);
    		if(d <= 0){
    			x++;
    			d += IncE;
    		}
    		else{
    			x++;
    			y++;
    			d += IncNE;
    		}
    	}
    	glFlush();
    	return;
    }
    
    // Draw line for dx<0 and dy>0
    void drawLine3(int x0, int x1, int y0, int y1, bool xy_interchange){
    	if(xy_interchange){
    		int change = x0;	x0 = x1;	x1 = change;
    		change = y0;	y0 = y1;	y1 = change;
    	}
    	int x = x0;
    	int y = y0;
    	int a = y0 - y1;
    	int b = -(x1 - x0);
    	int d = 2 * a + b;
    	int IncE = 2 * a;
    	int IncNE = 2 * a + 2 * b;
    	line_start[num_line] = line_data(x, y);
    	lcp = &line_start[num_line];
    	while(x <= x1){
    		lcp->next = new line_data(x, y);
    		lcp = lcp->next;
    		drawDot(x, y);
    		if(d <= 0){
    			x++;
    			d += IncE;
    		}
    		else{
    			x++;
    			y--;
    			d += IncNE;
    		}
    	}
    	glFlush();
    	return;
    }
    
    // Draw line for dx<0 and dy<0
    void drawLine4(int x0, int x1, int y0, int y1, bool xy_interchange){
    	if(xy_interchange){
    		int change = x0;	x0 = x1;	x1 = change;
    		change = y0;	y0 = y1;	y1 = change;
    	}
    	int x = x0;
    	int y = y0;
    	int a = y1 - y0;
    	int b = -(x1 - x0);
    	int d = a - 2 * b;
    	int IncE = -2 * b;
    	int IncNE = 2 * a - 2 * b;
    	line_start[num_line] = line_data(x, y);
    	lcp = &line_start[num_line];
    	while(y >= y1){
    		lcp->next = new line_data(x, y);
    		lcp = lcp->next;
    		drawDot(x, y);
    		if(d <= 0){
    			y--;
    			d += IncE;
    		}
    		else{
    			x++;
    			y--;
    			d += IncNE;
    		}
    	}
    	glFlush();
    	return;
    }
    
    // Draw a horizontal line
    void DrawHorizontalLine(int x0, int x1, int y){
    	for(int x = x0; x <= x1; x++){
    		drawDot(x, y);
    	}
    	glFlush();
    	return;
    }
    
    // Get matrix from SquareStore
    void GetFromSquareStore(int index, float destination[][CTM_SIZE]){
    	destination[0][0] = SquareStore[index].right_up.x;
    	destination[0][1] = SquareStore[index].right_up.y;
    	destination[0][2] = SquareStore[index].right_up.z;
    
    	destination[1][0] = SquareStore[index].left_up.x;
    	destination[1][1] = SquareStore[index].left_up.y;
    	destination[1][2] = SquareStore[index].left_up.z;
    
    	destination[2][0] = SquareStore[index].left_down.x;
    	destination[2][1] = SquareStore[index].left_down.y;
    	destination[2][2] = SquareStore[index].left_down.z;
    
    	destination[3][0] = SquareStore[index].right_down.x;
    	destination[3][1] = SquareStore[index].right_down.y;
    	destination[3][2] = SquareStore[index].right_down.z;
    }
    
    // update the WVM matrix
    void update_WVM(int sx, int sy, int tx, int ty){
    	WVM[0][0] = sx;
    	WVM[1][1] = sy;
    	WVM[0][2] = tx;
    	WVM[1][2] = ty;
    	WVM[2][2] = 1;
    	WVM[0][1] = WVM[1][0] = WVM[2][0] = WVM[2][1] = 0;
    }
    
    // Draw a triangle and Save it
    void triangle(){
    	float org_triangle[3][CTM_SIZE]
    		= { { 0,  1,  1 },
    			{ -1, -1, 1 },
    			{ 1,  -1, 1 } };
    
    	float WorldCoord_square[3][CTM_SIZE];
    
    	float multi_sum = 0;
    	for (int i = 0; i < 3; i++){
    		for (int j = 0; j < CTM_SIZE; j++){
    			multi_sum = 0;
    			for (int k = 0; k < CTM_SIZE; k++){
    				multi_sum += org_triangle[i][k] * current_matrix[j][k];
    			}
    			WorldCoord_square[i][j] = multi_sum;
    		}
    	}
    
    	AddtoTriangleStore(WorldCoord_square);
    	num_triangle++;
    
    	printMatrix(WorldCoord_square, 3, 3, "WorldCoord_square");
    }
    
    // Add a new triangle to TriangleStore
    void AddtoTriangleStore(float matrix[][CTM_SIZE]){
    	TriangleStore[num_triangle].first.x = matrix[0][0];
    	TriangleStore[num_triangle].first.y = matrix[0][1];
    	TriangleStore[num_triangle].first.z = matrix[0][2];
    
    	TriangleStore[num_triangle].second.x = matrix[1][0];
    	TriangleStore[num_triangle].second.y = matrix[1][1];
    	TriangleStore[num_triangle].second.z = matrix[1][2];
    
    	TriangleStore[num_triangle].third.x = matrix[2][0];
    	TriangleStore[num_triangle].third.y = matrix[2][1];
    	TriangleStore[num_triangle].third.z = matrix[2][2];
    
    }
    
    // Get a triangle data from TriangleStore
    void GetFromTriangleStore(int index, float destination[][CTM_SIZE]){
    	destination[0][0] = TriangleStore[index].first.x;
    	destination[0][1] = TriangleStore[index].first.y;
    	destination[0][2] = TriangleStore[index].first.z;
    
    	destination[1][0] = TriangleStore[index].second.x;
    	destination[1][1] = TriangleStore[index].second.y;
    	destination[1][2] = TriangleStore[index].second.z;
    
    	destination[2][0] = TriangleStore[index].third.x;
    	destination[2][1] = TriangleStore[index].third.y;
    	destination[2][2] = TriangleStore[index].third.z;
    }
    
    // Clear all the objects in store
    void clearData(){
    	for(int i = 0; i < num_line; i++){
    		if(line_start[i].next != NULL){
    			lcp = line_start[i].next;
    			while(lcp != NULL){
    				temp = lcp;
    				lcp = lcp->next;
    				delete(temp);
    			}
    		}
    	}
    	num_line = 0;
    	num_square = 0;
    	num_triangle = 0;
    	num_fill_line = 0;
    	fill_line.clear();
    	fill_line_color.clear();
    	frame_store.clear();
    	return;
    }
    
    // Clear the screen
    void clearScreen(){
    	glClearColor(default_r, default_g, default_b, alpha);
    	glClear(GL_COLOR_BUFFER_BIT);
    	glFlush();
    }
    
    // Redraw all objects stored 
    void redraw(){
    	r = 0;		g = 1.0;	b = 1.0;
    	int i;
    	line_data* rd_line;
    
    	for (i = 0; i < num_line; i++){
    		rd_line = &line_start[i];
    		r = Color[line_color[i]].r;
    		g = Color[line_color[i]].g;
    		b = Color[line_color[i]].b;
    		while (rd_line != NULL){
    			drawDot(rd_line->x, rd_line->y);
    			rd_line = rd_line->next;
    		}
    	}
    
    	for(i = 0; i < fill_line.size(); i++){
    		r = Color[fill_line_color[i]].r;
    		g = Color[fill_line_color[i]].g;
    		b = Color[fill_line_color[i]].b;
    		DrawHorizontalLine(fill_line[i].x0, fill_line[i].x1, fill_line[i].y);
    	}
    
    	r = 0.0;	g = 0.0;	b = 0.0;
    	for(i = 0; i < frame_store.size(); i++){
    		DrawLine(frame_store[i].vxl, frame_store[i].vxr, frame_store[i].vyb, frame_store[i].vyb);
    		DrawLine(frame_store[i].vxr, frame_store[i].vxr, frame_store[i].vyb, frame_store[i].vyt);
    		DrawLine(frame_store[i].vxr, frame_store[i].vxl, frame_store[i].vyt, frame_store[i].vyt);
    		DrawLine(frame_store[i].vxl, frame_store[i].vxl, frame_store[i].vyt, frame_store[i].vyb);
    	}
    
    	glFlush();
    }
    
    // Read the command from std
    void ReadInput(bool& IsExit){
    	float sx, sy, degree, tx, ty, wxl, wxr, wyb, wyt, vxl, vxr, vyt, vyb;
    	string command, comment;
    	cin >> command;
    	if (command == "scale"){
    		cin >> sx;
    		cin >> sy;
    		scale(sx, sy);
    		cout << command << endl;
    	}
    	else if (command == "rotate"){
    		cin >> degree;
    		rotate(degree);
    		cout << command << endl;
    	}
    	else if (command == "translate"){
    		cin >> tx;
    		cin >> 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"){
    		cin >> 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;
    		exit(0);
    	}
    	else if (command == "#"){
    		getline(cin, comment);
    	}
    }
    
    // Read the command from file
    void ReadFile(bool& IsExit){
    #if READ_MULTI_FILE
    	ifstream fin(file_list[cur_file]);
    #else
    	ifstream fin("myhw2.in");
    #endif
    	if (fin.is_open()){
    		cout << "open the file successfully" << endl;
    	}
    	float sx, sy, degree, tx, ty, wxl, wxr, wyb, wyt, vxl, vxr, vyt, vyb;
    	string command, comment;
    	while (!fin.eof()){
    		fin >> command;
    		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;
    			fin.close();
    			return;
    		}
    		else if (command == "#"){
    			getline(fin, comment);
    		}
    	}
    }
    
    // Display function
    void displayFunc(void){
    	// clear the entire window to the background color
    	glClear(GL_COLOR_BUFFER_BIT);
    	while (!IsExit){
    		glClearColor(default_r, default_g, default_b, alpha);
    #if READ_MULTI_FILE
    		if(cur_file < MAX_FILE){
    			clearScreen();
    			clearData();
    			//ReadInput(IsExit);
    			ReadFile(IsExit);
    			glFlush();
    			cout << "Enter any key to run next: ";
    			cur_file++;
    		}
    		else if(cur_file == MAX_FILE){
    			exit(0);
    		}
    #else
    		ReadFile(IsExit);
    #endif
    		return;
    	}
    
    	if (IsExit){
    		redraw();
    	}
    	//cout << "enter any key to exit: "; getchar();
    	//exit(0);
    	return;
    }
    
    // Print some formation and Set the parameter
    void initial(){
    	cout << "Welcome GLUT painter" << endl;
    	cout << "Here are command key: (case insensitive)" << endl;
    	cout << "	reset - reset matrix to identity" << endl;
    	cout << "	scale - scale the matrix" << endl;
    	cout << "	rotate - totate the matrix" << endl;
    	cout << "	translate - translate the matrix" << endl;
    	cout << "	square - create a square" << endl;
    	cout << "	triangle - create a triangle" << endl;
    	cout << "	view - draw all the objects" << endl;
    	cout << "	clearData - clear up data" << endl;
    	cout << "	clearScreen - clear the screen" << endl;
    	cout << "	end - Quit" << endl;
    }
    
    // Return the order of pair->x
    bool cmp_pair(const pair<int, int>& a, const pair<int, int>& b){
    	return (a.first < b.first);
    }
    
    // Fill the Polygon
    void FillPolygon(int PointVectorSize, string object){
    	vector<pair<int, int>> Intersections;
    	ScanFlag flag = even;
    	int cur_num_line = num_line;
    
    	if(object == "triangle"){
    		r = Color[1].r;
    		g = Color[1].g;
    		b = Color[1].b;
    	}
    	else if(object == "square"){
    		r = Color[color_index].r;
    		g = Color[color_index].g;
    		b = Color[color_index].b;
    	}
    
    	for(int y = Frame[3]; y >= Frame[2]; y--){
    		flag = even;
    		Intersections.clear();
    		for(int x = Frame[0]; x <= Frame[1]; x++){
    			for(int k = PointVectorSize - 1; k > 0; k--){
    				lcp = &line_start[cur_num_line - k];
    				while(lcp){
    					if(lcp->x == x && lcp->y == y){
    						Intersections.push_back(make_pair(x, y));
    						break;
    					}
    					lcp = lcp->next;
    				}
    			}
    		}
    		//sort(Intersections.begin(), Intersections.end(), cmp_pair);
    		int SIZE = Intersections.size();
    		if(SIZE >= 2){
    			if(object == "triangle")
    				fill_line_color.push_back(1);
    			else
    				fill_line_color.push_back(color_index);
    			fill_line.push_back(fill_line_struct(Intersections[0].first, Intersections[SIZE - 1].first, y));
    			DrawHorizontalLine(Intersections[0].first, Intersections[SIZE - 1].first, y);
    		}
    	}
    
    	color_index = (color_index + 1 == MAX_COLOR) ? 2 : color_index + 1;
    
    	return;
    }
    
    // call for the keyboard
    void myKeyboard(unsigned char key, int x, int y){
    	IsExit = false;
    	displayFunc();
    	return;
    }
    
    #pragma endregion
    
    // Main
    void main(int argc, char** argv) {
    	int winSizeX, winSizeY;
    	string name;
    	initial();
    	if (argc == 3) {
    		winSizeX = atoi(argv[1]);
    		winSizeY = atoi(argv[2]);
    		//		cout<<"Done";
    	}
    	else { // default window size
    		winSizeX = 800;
    		winSizeY = 600;
    
    	}
    
    	width = winSizeX;
    	height = winSizeY;
    
    	// initialize OpenGL utility toolkit (glut)
    	glutInit(&argc, argv);
    
    	// single disply and RGB color mapping
    	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
    	glutInitWindowSize(winSizeX, winSizeY);      // set window size
    	glutInitWindowPosition(500, 100);                // set window position on screen
    	glutCreateWindow("Lab2 Window");       // set window title
    
    #if READ_MULTI_FILE
    	// set up the mouse and keyboard callback functions
    	glutKeyboardFunc(myKeyboard); // register the keyboard action function
    	//glutMouseFunc(Mymouse);
    #endif
    
    	// 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(default_r, default_g, default_b, alpha);     // set the background to white
    	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();
    }
    

    hw2A.in文件

    # Computer Graphics Hw2 Test Input A
    # copy file content to "hw2.in" and run "CG_Hw2_Sample.exe"
    
    # create a square and its transformation
    reset
    scale 2.0 2.0
    rotate 45.0
    translate 10.0 10.0
    square
    
    view 0.0 20.0 0.0 20.0 100 400 100 400
    
    end
    

    hw2B.in文件

    # Computer Graphics Hw2 Test Input B
    # copy file content to "hw2.in" and run "CG_Hw2_Sample.exe"
    
    # create 4 triangles and place them such that
    # the assembly looks like a 4-winged fan
    
    reset
    translate 0.0 -1.0
    scale 0.5 1.0
    rotate 0.0
    triangle
    
    rotate 90.0
    triangle
    
    rotate 90.0
    triangle
    
    rotate 90.0
    triangle
    
    view -3.0 3.0 -3.0 3.0 0.0 400.0 0.0 400.0
    
    end
    

    hw2C.in文件

    # Computer Graphics Hw2 Test Input C
    # copy file content to "hw2.in" and run "CG_Hw2_Sample.exe"
    
    reset
    scale 0.9 0.9 
    rotate 15.0 
    translate 0.0 0.0
    square
    
    view -3.0 3.0 -3.0 3.0 20 220 20 220
    
    reset
    scale 0.9 0.9 
    rotate 15.0 
    translate 0.0 0.0
    square
    
    view -3.0 3.0 -3.0 3.0 240 440 20 220
    
    reset
    scale 0.8 0.8 
    rotate 30.0 
    translate 0.0 0.0
    square
    
    view -3.0 3.0 -3.0 3.0 460 680 20 220
    
    reset
    scale 0.7 0.7 
    rotate 45.0 
    translate 0.0 0.0
    square
    
    view -3.0 3.0 -3.0 3.0 20 220 240 440
    
    reset
    scale 0.6 0.6 
    rotate 60.0 
    translate 0.0 0.0
    square
    
    view -3.0 3.0 -3.0 3.0 240 440 240 440
    
    reset
    scale 0.5 0.5 
    rotate 75.0 
    translate 0.0 0.0
    square
    
    view -3.0 3.0 -3.0 3.0 460 660 240 440
    
    end
    

    hw2D.in

    # Computer Graphics Hw2 Test Input D
    # copy file content to "hw2.in" and run "CG_Hw2_Sample.exe"
    
    reset
    scale 0.5 0.5 
    rotate 0.0 
    translate -.3 -1.0
    square
    
    reset
    scale 1.5 1.5
    rotate 45.0 
    translate 0.6 -0.2
    square
    
    reset
    scale 0.5 0.5
    rotate 0.0
    translate -0.2 0.2
    square
    
    view -2.0 2.0 -2.0 2.0 100 400 100 400
    
    view 0.0 2.0 0.0 2.0 420 450 100 500
    
    view 0.0 2.0 0.0 2.0 600 650 200 300
    
    view -2.0 0.0 0.0 2.0 550 600 200 300
    
    view -2.0 0.0 -2.0 0.0 550 600 100 200
    
    view 0.0 2.0 -2.0 0.0 600 650 100 200
    
    end
    

    hw2E.in

    # Computer Graphics Hw2 Test Input E
    # copy file content to "hw2.in" and run "CG_Hw2_Sample.exe"
    
    # HOUSE
    reset
    scale 4 2
    rotate 0 
    translate 4.0 2.0
    square
    
    # GROUND
    reset
    scale 20 0.5
    rotate 0
    translate -10  -0.5
    square
    
    # DOOR
    reset
    scale 0.24 1.0
    rotate 0
    translate 4.0 1.25
    square
    
    # WINDOW
    reset
    scale 0.25 0.5
    rotate 0
    translate 2.0 2.5
    square
    
    # WINDOW
    reset
    scale 0.25 0.5
    rotate 0
    translate 6.0 2.5
    square
    
    # ROOF
    reset
    scale 5.0 1.0
    rotate 0
    translate 4.0 5.0
    triangle
    
    # SUPPORT
    reset
    scale 0.25 3.0
    rotate 0
    translate -4.0 3.0
    triangle
    
    # BLADE
    reset
    scale 0.25 3.5
    rotate -45
    translate -4 5.75
    square
    
    # BLADE
    reset
    scale 0.25 3.5
    rotate 45
    translate -4 5.75
    square
    
    # VIEW SCENE
    view -10.0 10.0 -2.0 10.0 20 220 20 140
    
    # VIEW SCENE
    view -5.0 5.0 -2.0 10.0 270 500 20 140
    
    # VIEW SCENE
    view -10.0 10.0 1.0  4.0 20 320 160 580
    
    # VIEW SCENE
    view -10.0 10.0 1.0  4.0 340 740 220 340
    
    end
    

    hw2F.in

    # Computer Graphics Hw2 Test Input F
    # copy file content to "hw2.in" and run "CG_Hw2_Sample.exe"
    
    reset
    scale 5.0 4.0 
    rotate 0 
    translate 0.0 0.0
    square
    
    reset
    scale 8.5 0.5 
    rotate 45
    translate 0.5 5.5
    square
    
    reset
    scale 8.5 0.5 
    rotate -45
    translate 0.5 5.5
    square
    
    reset
    scale 8.5 0.5 
    rotate -135
    translate 0.5 5.5
    square
    
    reset
    scale 8.5 0.5 
    rotate 135
    translate 0.5 5.5
    square
    
    # VIEW SCENE
    view -10.0 10.0 0.0  10.0 500 700 20 140
    
    end
    
  • 相关阅读:
    Swift
    ios高质量博客
    Swift
    UML建模
    Swift
    Swift
    IIS建立.net framework4 应用程序池HTTP 错误 500.21
    zz entity framework vs linq to sql
    zz部署wcf iis
    zzIIS站点中部署WCF项目
  • 原文地址:https://www.cnblogs.com/wsine/p/4639105.html
Copyright © 2020-2023  润新知