//namespace def
//{
#define PI 3.1415926
#define N 100
#define M 4
double iMatrix[M][M] = {
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
};
double oMatrix [M][M] = {
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
};
typedef struct Point {
double x;
double y;
double z;
}Point;
Point p[N],q[N];
int mode;//变换模式
double dx,dy,dz; //平移量或缩放量
Point center;
double angle;
Point wlow,wtop; //窗口坐标
Point vlow,vtop; //视区坐标
int n;
//}
void initMatrix(double im[M][M],int n) {
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
im[i][j] = 0;
for( i = 0; i < n; i++)
im[i][i] = 1;
}
void Translate (Point p[],Point q[],int n) {
initMatrix(iMatrix,4);
iMatrix[0][3] = dx;
iMatrix[1][3] = dy;
iMatrix[2][3] = dz;
double a[4],b[4] = {0};
for(int i = 0; i < n; i++) {
a[0] = p[i].x;
a[1] = p[i].y;
a[2] = p[i].z;
a[3] = 1;
memset(b,0,sizeof b);
for(int j = 0; j < 4; j++)
for(int k = 0; k < 4; k++)
{
b[j] += iMatrix[j][k] * a[k];
}
q[i].x = b[0];
q[i].y = b[1];
q[i].z = b[2];
}
}
void Scale (Point p[],Point q[],int n) {
initMatrix(iMatrix,4);
iMatrix[0][0] = dx;
iMatrix[1][1] = dy;
iMatrix[2][2] = dz;
double a[4],b[4] = {0};
for(int i = 0; i < n; i++) {
a[0] = p[i].x;
a[1] = p[i].y;
a[2] = p[i].z;
a[3] = 1;
memset(b,0,sizeof b);
for(int j = 0; j < 4; j++)
for(int k = 0; k < 4; k++)
{
b[j] += iMatrix[j][k] * a[k];
}
q[i].x = b[0];
q[i].y = b[1];
q[i].z = b[2];
}
}
void MulMatrix (double im[][M],double om[][M],int n) { //n*n矩阵 与 n*n 矩阵 的乘积
double *tmp = new double[n];
int j;
for(int i = 0; i < n; i++) {
for( j = 0; j < n; j++)
tmp[j] = 0;
for( j = 0; j < n; j++)
for(int k = 0; k < n; k++)
tmp[j] += om[i][k] * im[k][j];
for( j = 0; j < n; j++)
om[i][j] = tmp[j];
}
}
void Rotate (Point p[],Point q[],int n) {
double arg = PI*angle/180; //转换成弧度
dx = center.x;
dy = center.y;
dz = center.z;
initMatrix(oMatrix,4);
oMatrix[0][3] = dx;
oMatrix[1][3] = dy;
oMatrix[2][3] = dz;
initMatrix(iMatrix,4);
iMatrix[0][0] = cos(arg);
iMatrix[1][1] = cos(arg);
iMatrix[0][1] = -sin(arg);
iMatrix[1][0] = sin(arg);
MulMatrix (iMatrix,oMatrix,4);
initMatrix(iMatrix,4);
iMatrix[0][3] = -dx;
iMatrix[1][3] = -dy;
iMatrix[2][3] = -dz;
MulMatrix (iMatrix,oMatrix,4);
double a[4],b[4] = {0};
for(int i = 0; i < n; i++) {
a[0] = p[i].x;
a[1] = p[i].y;
a[2] = p[i].z;
a[3] = 1;
memset(b,0,sizeof b);
for(int j = 0; j < 4; j++)
for(int k = 0; k < 4; k++)
{
b[j] += oMatrix[j][k] * a[k];
}
q[i].x = b[0];
q[i].y = b[1];
q[i].z = b[2];
}
}
void Viewport (Point p[],Point q[],int m) {
dx = (vtop.x - vlow.x)/(wtop.x - wlow.x);
dy = (vtop.y - vlow.y)/(wtop.y - wlow.y);
dz = (vtop.z - vlow.z)/(wtop.z - wlow.z);
initMatrix(iMatrix,4);
iMatrix[0][0] = dx;
iMatrix[1][1] = dy;
iMatrix[2][2] = dz;
iMatrix[0][3] = -wlow.x*dx + vlow.x;
iMatrix[1][3] = -wlow.y*dy + vlow.y;
iMatrix[2][3] = -wlow.z*dz + vlow.z;
double a[4],b[4] = {0};
for(int i = 0; i < n; i++) {
a[0] = p[i].x;
a[1] = p[i].y;
a[2] = p[i].z;
a[3] = 1;
memset(b,0,sizeof b);
for(int j = 0; j < 4; j++)
for(int k = 0; k < 4; k++)
{
b[j] += iMatrix[j][k] * a[k];
}
q[i].x = b[0];
q[i].y = b[1];
q[i].z = b[2];
}
}
void in(){
int i;
for ( i = 0; i < N; i++) {
p[i].x = p[i].y = p[i].z = 0;
q[i].x = q[i].y = q[i].z = 0;
}
ifstream fin("in.txt");
streambuf *inbuf = cin.rdbuf(fin.rdbuf());
cin>>n;
for ( i = 0; i < n; i++) {
cin>>p[i].x>>p[i].y>>p[i].z;
}
cin>>mode;
switch(mode) {
case 1: //translate
cin>>dx>>dy>>dz;break;
case 2: //Scale
cin>>dx>>dy>>dz;break;
case 3: //Rotate
cin>>center.x>>center.y>>center.z;
cin>>angle;break;
case 4: //Viewport
cin>>wlow.x>>wlow.y>>wlow.z;
cin>>wtop.x>>wtop.y>>wlow.z;
cin>>vlow.x>>vlow.y>>vlow.z;
cin>>vtop.x>>vtop.y>>vtop.z;
break;
default:;
}
cin.rdbuf(inbuf);
}
void Draw() {
gluOrtho2D(0.0, 500.0, 0.0, 500.0);
glClearColor(1.0, 1.0, 1.0, 0.0);
//glMatrixMode(GL_PROJECTION);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 1.0);
int i;
glBegin(GL_LINE_LOOP);
for( i = 0; i < n; i++)
glVertex2f(p[i].x,p[i].y);
glEnd();
glBegin(GL_LINE_LOOP);
for( i = 0; i < n; i++)
glVertex2f(q[i].x,q[i].y);
glEnd();
glFlush();
}
void print() {
for(int i = 0; i < n; i++)
cout << p[i].x <<" "<< p[i].y << endl;
for(int j = 0; j < n; j++)
cout << q[j].x <<" "<< q[j].y << endl;
}
void main(int anglec,char **anglev) {
in();
glutInit(&anglec, anglev);
glutInitDisplayMode (GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize (500,500);
glutInitWindowPosition (0,0);
switch(mode) {
case 1:
glutCreateWindow( "Translation");
Translate(p,q,n);break;//平移
case 2:
glutCreateWindow("Scale");
Scale(p,q,n);break;//伸缩
case 3:
glutCreateWindow("Rotation");
Rotate(p,q,n);break;//旋转
case 4:
glutCreateWindow("Viewport");
Viewport(p,q,n);break;//视景映射
default:;
}
print();
glutDisplayFunc (Draw);
glutMainLoop();
}
Test:
4
200 200 0
400 200 0
400 400 0
200 400 0
1
50 -30 0
4
200 200 0
400 200 0
400 400 0
200 400 0
2
0.8 1.2 2
4
200 200 0
400 200 0
400 400 0
200 400 0
3
300 300 0
45
4
200 200 0
400 200 0
400 400 0
200 400 0
4
100 100 0
450 470 0
100 300 0
300 400 0