图形学的变换----四维矩阵算子

//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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值