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() - 根据键,以升 ...
随机推荐
- Wordpress 运行缓慢的解决方法
原因为wordpress 3.8之后采用google字体所致. 修改 functions.php //禁用Open Sans class Disable_Google_Fonts { pub ...
- CSS中的文本属性
本文总结一下CSS中关于文字的相关属性,最后给出实例. CSS基础文字属性 文字的基础属性主要包括:字体.颜色和文本.除去颜色color的属性外,字体和文本的相关属性可以权威参考: CSS 文本属性( ...
- 9种CSS3炫酷图片展开预览展示动画特效
详细内容请点击 在线预览立即下载 这是一组共9款CSS3炫酷图片预览展示动画特效插件.css的新特性可以让我们制作出各种炫酷的动画效果.该图片预览展示动画特效就是一个很好的例子,该效果开始时图片堆叠在 ...
- 无需操作系统和虚拟机,直接运行Python代码
Josh Triplett以一个“笑点”开始了他在PyCon 2015上的演讲:移植Python使其无需操作系统运行:他和他的英特尔同事让解释器能够在GRUB引导程序.BIOS或EFI系统上运行.连演 ...
- SQL Server 发布订阅 发布类型详解
MicrosoftSQL Server 提供了三种复制类型. 每种复制类型都适合于不同应用程序的要求. 根据应用程序需要,可以在拓扑中使用一种或多种复制类型: 快照复制 事务复制 合并复制 为了帮助您 ...
- Javascript 日期时间超强正则表达式
var reg = /^([0-9]{4})-((?:0[1-9]|[1-9]|1[1-2]))-((?:(?:0[1-9]|[1-9])|1[0-9]|2[0-9]|3[0-1]))$|^([0-9 ...
- 解决windows端口被占用
1, Cmd输入命令:netstat –ano|findstr “端口号” ,如netstat –ano|findstr “8080” 记下PID,最后一行为PID,这里为396 2,Cmd输 ...
- 苹果系统开发中的混合编程(1):Objective-C和C++的相互调用
首先是OC调用C++的代码. 创建一个Objective-C的项目,并创建c++文件MyCppFile.hpp和MyCppFile.cpp. 把要调用Cpp代码的文件名改成mm后缀名,项目代码 ...
- Swift字符串类型
字符串初始化 1.初始化 let someString = "Some string literalvalue" let wiseWords = ...
- ☆RHEL6创建软raid的使用☆——经典之作
raid主要的种类 1.raid0 扩展卷 raid 0又称Stripee或Striping,中文译为集带工作方式, 有时也可以理解为拼凑. 它是将要存取的数据以条带状的形式尽量平均分配到多个硬 ...