CG实验2nd&3rd:二维几何变换、裁减、动画、三维透视

来源:互联网 发布:企业域名保护 编辑:程序博客网 时间:2024/04/28 05:45

 

实验2

1、放缩与旋转

说明:关键得到变换矩阵,

放缩矩阵:

         doubleb[3][3] = {                   Sx,0, 0,                   0,Sy, 0,                   -xF* Sx + xF, -yF * Sy + yF, 1         };

旋转矩阵:

         doubleb[3][3] = {                   cos(theta),sin(theta), 0,                   -sin(theta),cos(theta), 0,                   xF- xF * cos(theta) + yF * sin(theta), yF - yF * cos(theta) - xF * sin(theta), 1         };

运行结果如图所示:

放缩:


旋转:


源程序:

#include <iostream>#include <cmath>#include "graphics.h"using namespace std; const int NUM = 3;  // 多边形顶点个数 // 矩阵相乘:c = a * b// 带回cvoid MMul(double a[NUM][3], double b[3][3],double c[NUM][3]){         for(int i = 0; i < NUM; ++i)         {                   for(int j = 0; j < 3; ++j)                   {                            intelem = 0;                            for(int k = 0; k < 3; ++k)                            {                                     elem+= a[i][k] * b[k][j];                            }                            c[i][j]= elem;                   }         }       } void Zoom(double a[NUM][3]){                doublexF;         doubleyF;         doubleSx;         doubleSy;                 cout<< "请输入缩放比例:" << endl;         cin>> Sx;         Sy= Sx;             cout<< "请输入缩放参考点:\nx = ";         cin>> xF;         cout<< "y = ";         cin>> yF;         double b[3][3] = {                   Sx,0, 0,                   0,Sy, 0,                   -xF* Sx + xF, -yF * Sy + yF, 1         };               doublec[NUM][3];         MMul(a,b, c);          intgdriver = DETECT;         intgmode = 0;         initgraph(&gdriver,&gmode, "");         moveto(a[NUM- 1][0], a[NUM - 1][1]);         for(int i = 0; i < NUM; ++i)         {                   lineto(a[i][0],a[i][1]);         }         setcolor(YELLOW);         moveto(c[NUM- 1][0], c[NUM - 1][1]);         for(i = 0; i < NUM; ++i)         {                   lineto(c[i][0],c[i][1]);         }         system("pause");         closegraph();  } void Turn(double a[NUM][3]){                doublexF = 200;         doubleyF = 30;         doubletheta = acos(-1) / 2;             cout<< "请输入旋转角度:" << endl;         cin>> theta;         cout<< "请输入旋转中心:\nx = ";         cin>> xF;         cout<< "y = ";         cin>> yF;         double b[3][3] = {                   cos(theta),sin(theta), 0,                   -sin(theta),cos(theta), 0,                   xF- xF * cos(theta) + yF * sin(theta), yF - yF * cos(theta) - xF * sin(theta), 1         };               doublec[NUM][3];         MMul(a,b, c);          intgdriver = DETECT;         intgmode = 0;         initgraph(&gdriver,&gmode, "");         moveto(a[NUM- 1][0], a[NUM - 1][1]);         for(int i = 0; i < NUM; ++i)         {                   lineto(a[i][0],a[i][1]);         }         setcolor(YELLOW);         moveto(c[NUM- 1][0], c[NUM - 1][1]);         for(i = 0; i < NUM; ++i)         {                   lineto(c[i][0],c[i][1]);         }         system("pause");         closegraph();  } int main(int argc, char **argv){         intp[8] = {10, 20, 150, 150, 200, 30, 10, 20};         doublea[NUM][3] = {                   10,20, 1,                            150,150, 1,                            200,30, 1         }; //      Zoom(a);         Turn(a);         return0;}


 

2、裁减

用的是库函数setviewport得到视图窗口。源程序如下:

#include <stdio.h>#include "graphics.h" #define NUM 3 void Cut(int p[]){         intgdriver = DETECT;         intgmode = 0;         initgraph(&gdriver,&gmode, "");          setviewport(10,20, 100, 100, 1);         drawpoly(1+ NUM, p);         getch();         clearviewport();         closegraph();} int main(){         intp[2 * (NUM + 1)] = {10, 20, 150, 150, 200, 30, 10, 20};         Cut(p);         return0;}


 

实验3

1、动画

显示图形的移动,运行结果如下,显示的是椭圆的向右移动:

 

源程序:

#include <iostream>#include "graphics.h"using namespace std; int main(int argc,char**argv){    IMAGEimg;    initgraph(500,500);    ellipse(10,10, 90, 300);    getimage(&img,10, 10, 91, 301);     for(int i = 0; i <500 - (90 - 10); i++)    {       cleardevice();       putimage(i,10, &img);       Sleep(10);    }     system("pause");    closegraph();     return 0;}


 

2、三维透视

显示一个正方体的一点透视投影图。关键是变换矩阵:

    double b[DEMENSION][DEMENSION] = {       1,0, 0, 0,       0,1, 0, 0,       0,0, 0, 1 / d,       l,m, 0, 1 + n / d    };


 

运行结果:

 

原程序

#define _CRT_SECURE_NO_WARNINGS#include <iostream>#include "graphics.h"using namespace std; const int NUM = 8;                     // 多面体顶点个数(这里是正方体)const int DEMENSION = 4;       // 维数(n+1维) // 矩阵相乘:c = a * b, 带回cvoid MMul(double a[NUM][DEMENSION], doubleb[DEMENSION][DEMENSION], double c[NUM][DEMENSION]){         for(int i = 0; i < NUM; ++i)         {                                   for(int j = 0; j < DEMENSION; ++j)                   {                            doubleelem = 0;                            for(int k = 0; k < DEMENSION; ++k)                            {                                     elem+= a[i][k] * b[k][j];                            }                            c[i][j]= elem;                   }         }       } // 规范化齐次坐标void Standard(double c[NUM][DEMENSION]){         for(int i = 0; i < NUM; ++i)         {                   for(int j = 0; j < DEMENSION - 1; ++j)                   {                            c[i][j]= c[i][j] / c[i][DEMENSION - 1];                   }                   c[i][DEMENSION- 1] = 1;         }} // 下面代码只能画正方体,12条边void Draw3D(double array[NUM][DEMENSION]){         //精度转换         intc[NUM][DEMENSION];         for(int i = 0; i < NUM; ++i)         {                  for (int j = 0; j < DEMENSION; ++j)                   {                            c[i][j]= (int)array[i][j];                   }         }         setlinestyle(PS_USERSTYLE,0xF0F0);      // 与c[6]顶点相关联的三条边为虚线         line(c[5][0],c[5][1], c[6][0], c[6][1]);         line(c[6][0],c[6][1], c[7][0], c[7][1]);                 line(c[2][0],c[2][1], c[6][0], c[6][1]);          setlinestyle(PS_SOLID);         line(c[0][0],c[0][1], c[1][0], c[1][1]);         line(c[1][0],c[1][1], c[2][0], c[2][1]);                 line(c[2][0],c[2][1], c[3][0], c[3][1]);         line(c[3][0],c[3][1], c[0][0], c[0][1]);                 line(c[4][0],c[4][1], c[5][0], c[5][1]);         line(c[7][0],c[7][1], c[4][0], c[4][1]);         line(c[0][0],c[0][1], c[4][0], c[4][1]);         line(c[1][0],c[1][1], c[5][0], c[5][1]);         line(c[3][0],c[3][1], c[7][0], c[7][1]);          setlinestyle(PS_SOLID);} void Reflect(double a[NUM][DEMENSION]){         doubled;           // 视点在z轴上的位置(z=-d处)         doublel, m, n; // 将三维形体平移到适当位置l, m, n         cout<< "请输入视点在z轴的位置:" << endl;         cin>> d;         cout<< "请输入要平移到的适当位置:" << endl;         cin>> l >> m >> n;          doubleb[DEMENSION][DEMENSION] = {                   1,0, 0, 0,                   0,1, 0, 0,                   0,0, 0, 1 / d,                   l,m, 0, 1 + n / d         };               doublec[NUM][DEMENSION];         MMul(a,b, c);         Standard(c);          intgdriver = DETECT;         intgmode = 0;         initgraph(&gdriver,&gmode, "");          setcolor(YELLOW);         //      Draw3D(a);         Draw3D(c);          Sleep(10000);         system("pause");         closegraph();} int main(int argc, char **argv){         freopen("cin.txt","r", stdin);         //输入正方形各定点坐标         doublea[NUM][DEMENSION];         for(int i = 0; i < NUM; ++i)         {                   for(int j = 0; j < DEMENSION; ++j)                   {                            cin>> a[i][j];                   }         }          Reflect(a);          return0;} /*cin.txt:0 0 0 1300 0 0 1300 300 0 10 300 0 10 0 300 1300 0 300 1300 300 300 10 300 300 1 25080 160 200*/


原创粉丝点击