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)
键盘回调函数
运行效果
完整代码
#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 << "\t[ ";
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 << "\treset - reset matrix to identity" << endl;
cout << "\tscale - scale the matrix" << endl;
cout << "\trotate - totate the matrix" << endl;
cout << "\ttranslate - translate the matrix" << endl;
cout << "\tsquare - create a square" << endl;
cout << "\ttriangle - create a triangle" << endl;
cout << "\tview - draw all the objects" << endl;
cout << "\tclearData - clear up data" << endl;
cout << "\tclearScreen - clear the screen" << endl;
cout << "\tend - 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
C++实现数字媒体二维图像变换的更多相关文章
- php 二维数组验证一个值是否存在
php 判断数字在二维数组里 $arr = array( array('a', 'b'), array('c', 'd') ); in_array('a', $arr); // 此时返回的永远都是 f ...
- C++实现数字媒体三维图像变换
C++实现数字媒体三维图像变换 必备环境 glut.h 头文件 glut32.lib 对象文件库 glut32.dll 动态连接库 程序说明 C++实现了用glut画物体对象的功能.并附带放大缩小,旋 ...
- PHP 统计一维数组value同样的元素的个数num,并将其转化为下标为数字,值是value和num的二维数组
近期做一个项目.从数据库查询某个字段得到一个数组key是数字值是channel的一维数组$res,现须要将这个数组变成键是数字值是channel和num(num为同样channel的数量,默觉得0). ...
- javascript使用H5新版媒体接口navigator.mediaDevices.getUserMedia,做扫描二维码,并识别内容
本文代码测试要求,最新的chrome浏览器(手机APP),并且要允许chrome拍照录像权限,必须要HTTPS协议,http不支持. 原理:调用摄像头,将摄像头返回的媒体流渲染到视频标签中,再通过ca ...
- 利用 Python django 框架 输入汉字,数字,字符,等。。转成二维码!
利用 Python django 框架 输入汉字,数字,字符,等..转成二维码! 模块必备:Python环境 + pillow + qrcode 模块 核心代码import qrcode qr = ...
- 剑指offer1: 组类型——二维数组中的查找(给定一个数字,查找是否在该数组中)
1. 思路: 缩小范围 2. 方法: (1)要查找的数字等于数组中的数字,结束查找过程: (2)要查找的数字小于数组中的数字,去除该数字右边的数字,在剩下的数字里查找: (3)要查找的数字大于数组中的 ...
- 数字信号处理实验(零)—— 一维声音信号处理和二维图像处理
一.在matlab下声音信号的I/O 1.读wav文件函数 •y = wavread('filename') •[y,Fs,bits] = wavread('filename') •[...] = w ...
- c语言数字图像处理(六):二维离散傅里叶变换
基础知识 复数表示 C = R + jI 极坐标:C = |C|(cosθ + jsinθ) 欧拉公式:C = |C|ejθ 有关更多的时域与复频域的知识可以学习复变函数与积分变换,本篇文章只给出DF ...
- PHP一维数组和二维数字排序整理
<?php /** 一维数组排序 sort() - 以升序对数组排序 rsort() - 以降序对数组排序 asort() - 根据值,以升序对关联数组进行排序 ksort() - 根据键,以升 ...
随机推荐
- ASP.NET缓存全解析1 转自网络原文作者李天平
有时候总听到网友说网站运行好慢,不知如何是好:有时候也总见到一些朋友写的网站功能看起来非常好,但访问性能却极其的差.没有“勤俭节约”的意识,势必会造成“铺张浪费”.如何应对这种情况,充分利用系统缓存则 ...
- C#_枚举类型
C#中的枚举是名/值对的数据类型,下面是自定义的军衔等级的枚举 //定义枚举 enum MilitaryRank { Commander, ArmyCorpCommander, Military ...
- java识别验证码
所需资源下载链接(资源免费,重在分享) Tesseract:http://download.csdn.net/detail/chenyangqi/9190667 jai_imageio-1.1-alp ...
- 使用SSIS创建同步数据库数据任务
国外相关的文章:http://blog.dxuf.com/sql-tutorial/use-ssis-to-create-the-synchronization-database-data-task. ...
- (转)mongodb常用命令脚本化-自动化运维
mongodb常用命令脚本化-自动化运维 把一些运维中常用到的mongodb命令写成shell脚本,极大的方便了维护 1 设置副本集 #!/bin/bash#mongodb 进入client ...
- 几道hihocoder不会做的题
1.https://hihocoder.com/problemset/problem/1433?sid=970287 boarding passes,不会做,看的别人的代码,现在还不是很理解. 2. ...
- Excel 窗体控件属性
常规 AutoLoad (Excel) 打开工作簿时是否加载控件.(如果是 ActiveX 控件,则忽略.) Enabled(表单) 控件是否可以接收焦点并响应用户生成的事件. Locked( ...
- 使用Hint来优化执行计划
最近看主管优化了一个HINT相关的查询 借此机会学习下HINT 参考Notes: Note 129385 - Database hints in Open SQL http://www.stechno ...
- 控制反转 (inversion of control)
The inversion of control (IoC) pattern is abstract; it says that one should move dependency creation ...
- 使用tortoisegit管理git 和 权限验证
1 安装Git 2 安装Tortoise 3 在git.oschina 或者 github上创建项目 4 Tortoise配置 TortoiseGit 使用扩展名为ppk的密钥,而不是ssh-keyg ...