计算机图形学 二维变换 实验代码
- 格式:doc
- 大小:33.50 KB
- 文档页数:4
实验一、直线的生成实验目的:1、掌握DDA直线画法、中点画线法和Bresenham画线法2、掌握VC++简单程序设计方法实验内容:根据提供的程序框架,修改部分代码,完成画一条直线的功能(中点画线法或者Bresenham画线法任选一),只要求实现在第一象限内的直线。
实验步骤和方法:首先启动Visual C++ 6.0(注意,其它版本程序无法正确编译),文件(file)→打开工作空间(open workspace)。
打开实验12用基本图形生成\基本图形生成.dsw。
在fileview窗口,source file下,双击直线生成view.cpp,或者classview窗口下,cmyview类下相应的函数,按注释改写下列函数:void CMyView::OnDdaline() (此为DDA生成直线)void CMyView::OnBresenhamline()(此为Bresenham画直线)void CMYView::OnMidPointLine()(此为中点画线法)程序代码说明:1、直线的两个端点,由对话框输入,给定程序已经完成输入代码。
2、SetPixel的用法:COLORREF SetPixel(int x, int y, COLORREF crColor);//x,y为坐标点。
COLORREF SetPixel(POINT point, COLORREF crColor);//point为坐标点。
3、本实验事先提供DDA话直线的函数示范(红色部分是重点,其它部分可以不看)中点画直线函数和BresenHam画直线函数由同学们参照dda直线的示例函数自己完成。
//以下为DDA画直线的源程序float x,y,dx,dy,k;dx=(float)(xb-xa);dy=(float)(yb-ya);k=dy/dx;x=xa;y=ya;if(abs(k)<1){for (x=xa;x<=xb;x++){pdc->SetPixel(x, int(y+0.5),COLOR);y=y+k;}}if(abs(k)>=1){for(y=ya;y<=yb;y++){pdc->SetPixel(int(x+0.5),y,COLOR);x=x+1/k;}}//DDA画直线结束//以下为中点画直线的源程序float a,b,d1,d2,d,x,y;a=ya-yb,b=xb-xa,d=2*a+b;d1=2*a,d2=2*(a+b);x=xa,y=ya;pdc->SetPixel(x,y,COLOR);while(x<xb){ if(d<0){x++,y++,d+=d2;}else {x++,d+=d1;}pdc->SetPixel(x,y,COLOR);}//中点画直线结束//以下为Bresenham画直线的源程序int i,s1,s2,interchange;float f,x,y,deltax,deltay,temp; x=xa;y=ya;deltax=abs(xb-xa);deltay=abs(yb-ya);if(xb-xa>=0)s1=1;else s1=-1;if(yb-ya>=0)s2=1;else s2=-1;if(deltay>deltax){ temp=deltax;deltax=deltay;deltay=temp;interchange=1;}else interchange=0;f=2*deltay-deltax;pdc->SetPixel(x,y,COLOR);for(i=1;i<=deltax;i++){ if(f>=0){if(interchange==1) x+=s1;else y+=s2;pdc->SetPixel(x,y,COLOR);f=f-2*deltax;}else {if(interchange==1) y+=s2;else x+=s1;f=f+2*deltay;}}}//Bresenham画直线结束实验二、圆的生成(中点和Bresenham法)实验目的:1、掌握bresenham画圆的算法。
// 二维几何图形变换.cpp : 定义应用程序的类行为。
//#include "stdafx.h"#include "二维几何图形变换.h"#include "MainFrm.h"#include "二维几何图形变换Doc.h"#include "二维几何图形变换View.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// CMyAppBEGIN_MESSAGE_MAP(CMyApp, CWinApp)ON_COMMAND(ID_APP_ABOUT, OnAppAbout)// 基于文件的标准文档命令ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)// 标准打印设置命令ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP()// CMyApp 构造CMyApp::CMyApp(){// TODO: 在此处添加构造代码,// 将所有重要的初始化放置在InitInstance 中}// 唯一的一个CMyApp 对象CMyApp theApp;// CMyApp 初始化BOOL CMyApp::InitInstance(){// 如果一个运行在Windows XP 上的应用程序清单指定要// 使用ComCtl32.dll 版本6 或更高版本来启用可视化方式,//则需要InitCommonControls()。
否则,将无法创建窗口。
InitCommonControls();CWinApp::InitInstance();// 初始化OLE 库if (!AfxOleInit()){AfxMessageBox(IDP_OLE_INIT_FAILED);return FALSE;}AfxEnableControlContainer();// 标准初始化// 如果未使用这些功能并希望减小// 最终可执行文件的大小,则应移除下列// 不需要的特定初始化例程// 更改用于存储设置的注册表项// TODO: 应适当修改该字符串,// 例如修改为公司或组织名SetRegistryKey(_T("应用程序向导生成的本地应用程序"));LoadStdProfileSettings(4); // 加载标准INI 文件选项(包括MRU)// 注册应用程序的文档模板。
实验三图形的二维几何变换一、实验目的了解齐次坐标规范化及矩阵的乘法运算熟悉掌握平移,比例,旋转,错切变换的齐次坐标矩阵掌握基于 Win32、Visual C++环境MFC绘制图形配置过程制过程二、实验原理及思想1.基本几何变换2.齐次坐标给定2D 坐标 (x, y), 引入第3维:[x, y, 1]通常, 一个 2D 坐标点的齐次坐标有如下形式:[x, y, W]两个齐次坐标点 [x, y, W] and [x’, y’, W’] 相同 if x = kx’eg: [2, 3, 6] = [4, 6, 12]y = ky’for some k ≠ 0 where k=2W = kW’因此,任意 [x, y, W] 可归一化:[x/W, y/W, 1]3.三、实验关键代码void C2DChangeView::ClearMatrix(double A[3][3])//清除变换矩阵{for(int i=0;i<3;i++){for(int j=0;j<3;j++)A[i][j]=0;}}void C2DChangeView::Draw(double D[][3],int n)//绘制图形{RedrawWindow();CClientDC dc(this);CPen pen,*pOldpen;pen.CreatePen(PS_SOLID,2,RGB(0,0,0));pOldpen=dc.SelectObject(&pen);for(int i=0;i<n;i++){if(i==0)dc.MoveTo(ROUND(MaxX/2+D[i][0]),ROUND(MaxY/2-D[i][1]));elsedc.LineTo(ROUND(MaxX/2+D[i][0]),ROUND(MaxY/2-D[i][1]));}dc.LineTo(ROUND(MaxX/2+D[0][0]),ROUND(MaxY/2-D[0][1]));dc.SelectObject(pOldpen);pen.DeleteObject();}void C2DChangeView::Calculate(double P0[][3],double T[][3])//两个矩阵相乘{double Ptemp[4][3];KeepMatrix(P,Ptemp);for(int i=0;i<4;i++)for(int j=0;j<3;j++)P[i][j]=Ptemp[i][0]*T[0][j]+Ptemp[i][1]*T[1][j]+Ptemp[i][2]*T[ 2][j];}void C2DChangeView::OnMENUleft()//向左平移{// TODO: Add your command handler code hereTmove(-10,0);}void C2DChangeView::OnMENUright()//向右平移{// TODO: Add your command handler code hereTmove(10,0);}void C2DChangeView::OnMENUup() //向上平移{// TODO: Add your command handler code hereTmove(0,10);}void C2DChangeView::OnMENUdown()//向下平移{// TODO: Add your command handler code hereTmove(0,-10);}void C2DChangeView::OnMENUClockwise()//顺时针旋转{// TODO: Add your command handler code hereTrotate(30);}void C2DChangeView::OnMENUAnticlockwise()//逆时针旋转{// TODO: Add your command handler code hereTrotate(-30);}void C2DChangeView::OnMENUIncrease()//放大比例{// TODO: Add your command handler code hereTscale(2,2);}void C2DChangeView::OnMENUDecrease()//缩小比例{// TODO: Add your command handler code hereTscale(0.5,0.5);}void C2DChangeView::OnMENUXdirectionplus()//X正向错切{// TODO: Add your command handler code hereTreform(0,1);}void C2DChangeView::OnMENUXdirectionneg()//X负向错切{// TODO: Add your command handler code hereTreform(0,-1);}void C2DChangeView::OnMENUITYdirectionplus()//Y正向错切{// TODO: Add your command handler code hereTreform(1,0);}void C2DChangeView::OnMENUYdirectionneg()//Y负向错切{// TODO: Add your command handler code hereTreform(-1,0);}void C2DChangeView::OnMENUReset() //复位{// TODO: Add your command handler code hereif(p3==4){KeepMatrix(OSquare,P);}if(p3==3){KeepMatrix(OTriangle,P);}if(p3==2){KeepMatrix(OLine,P);}Draw(P,p3);}void C2DChangeView::Tmove(double Tx,double Ty)//平移变换矩阵{ClearMatrix(TM);RedrawWindow();TM[0][0]=1;TM[1][1]=1;TM[2][0]=Tx;TM[2][1]=Ty;TM[2][2]=1;Calculate(P,TM);AfxGetMainWnd()->SetWindowText("二维几何变换-平移变换");Draw(P,p3);}void C2DChangeView::Tscale(double Sx,double Sy)//比例变换矩阵{ClearMatrix(TS);RedrawWindow();TS[0][0]=Sx;TS[1][1]=Sy;TS[2][2]=1;Calculate(P,TS);AfxGetMainWnd()->SetWindowText("二维几何变换-比例变换");Draw(P,p3);}void C2DChangeView::Trotate(double thta)//旋转变换矩阵{ClearMatrix(TR);RedrawWindow();TR[0][0]=cos(thta*PI/180);TR[0][1]=sin(thta*PI/180);TR[1][0]=-sin(thta*PI/180);TR[1][1]=cos(thta*PI/180);TR[2][2]=1;Calculate(P,TR);AfxGetMainWnd()->SetWindowText("二维几何变换-旋转变换");Draw(P,p3);}void C2DChangeView::Treflect(double Fx,double Fy)//反射变换矩阵{ClearMatrix(TF);RedrawWindow();TF[0][0]=Fx;TF[1][1]=Fy;TF[2][2]=1;Calculate(P,TF);AfxGetMainWnd()->SetWindowText("二维几何变换-反射变换");Draw(P,p3);}void C2DChangeView::Treform(double b,double c)//错切变换矩阵{ClearMatrix(TC);RedrawWindow();TC[0][0]=1;TC[0][1]=b;TC[1][0]=c;TC[1][1]=1;TC[2][2]=1;Calculate(P,TC);AfxGetMainWnd()->SetWindowText("二维几何变换-错切变换");Draw(P,p3);}void C2DChangeView::KeepMatrix(double Orig[][3],double Dest[][3]){int i,j;for(i=0;i<4;i++)for(j=0;j<3;j++)Dest[i][j]=Orig[i][j];}四、实验结果1. 初始图2 --平移(左移)2 --平移(下移)3 、缩放-——放大3 、缩放-——缩小4 、旋转5 、错切——X负向错切5 、错切——Y正向错切五、心得体会通过这次MFC对计算机图形的编程,进一步掌握了MFC的菜单的实现及其响应函数的实现。
宁夏师范学院数学与计算机科学学院《计算机图形学》实验报告实验序号:7 实验项目名称:二维图形变换菜单菜单项ID值图形变换(&T)缩放(&Z)ID_TRANSFORM_SCALE图形变换(&T)旋转(&R)ID_TRANSFORM_ROTATE图形变换(&T)对称(&S)ID_TRANSFORM_SYMMETRY 4、在CTransView视图类中添加消息映射函数;对象消息函数ID_TRANSFORM_SCALE COMMAND OnFigureCirleID_TRANSFORM_ROTATE COMMAND OnFigureEllipseID_TRANSFORM_SYMMETRY COMMAND OnTransformSymmetry5、添加自定义的成员变量:CPoint Pt[3]; //三角形定点数组float dAngle; //每一次旋转的角度在视图类CPP文件的构造函数中初始化成员变量Pt[0].x = 540; Pt[0].y = 220;Pt[1].x = 670; Pt[1].y = 130;Pt[2].x = 560; Pt[2].y = 120;dAngle = 0;6、在视图类的OnDraw()函数中加入下列代码,实现视图绘图。
void CTransView::OnDraw(CDC* pDC){CTransDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data here//绘出以以(540,220)、(670,130)、(560,120)为顶点的三角形。
pDC->MoveTo(Pt[0]);pDC->LineTo(Pt[1]);三、运行结果变换前:对称变换:缩放变换:旋转变换:五、教师评语成绩签名:日期:年月日。
四、实验结果抓图与分析1、目标的平移的源程序2、绕任意点旋转的源程序实验一、直线的生成一、实验内容根据提供的程序框架,修改部分代码,完成画一条直线的功能(中点画线法或者Bresenham画线法任选一),只要求实现在第一象限内的直线。
二、算法原理介绍双击直线生成.dsw打开给定的程序,或者先启动VC++,文件(file)→打开工作空间(open workspace)。
打开直线生成view.cpp,按注释改写下列函数:1.void CMyView::OnDdaline() (此为DDA生成直线)2.void CMyView::OnBresenhamline()(此为Bresenham画直线)3.void CMYView::OnMidPointLine()(此为中点画线法)三、程序源代码1.DDA生成直线画法程序:float x,y,dx,dy,k;dx=(float)(xb-xa);dy=(float)(yb-ya);k=dy/dx;x=xa;y=ya;if(abs(k)<1){for (x=xa;x<=xb;x++){pdc->SetPixel(x, int(y+0.5),COLOR);y=y+k;}}if(abs(k)>=1){for(y=ya;y<=yb;y++){pdc->SetPixel(int(x+0.5),y,COLOR);x=x+1/k;}}//DDA画直线结束}2.Bresenham画直线源程序:float b,d,xi,yi;int i;float k;k=(yb-ya)/(xb-xa);b=(ya*xb-yb*xa)/(xb-xa);if(k>0&&k<=1)for(i=0;i<abs(xb-xa);i++){ d=ya+0.5-k*(xa+1)-b;if(d>=0){ xi=xa+1;yi=ya;xa++;ya=ya+0.5;}if(d<0){ xi=xa+1;yi=ya+1;xa++;ya=ya+1.5;}pdc->SetPixel(xi,yi,COLOR); }//BresenHam画直线结束}3.中点画线法源程序:float b,d,xi,yi;int i;float k;k=(yb-ya)/(xb-xa);b=(ya*xb-yb*xa)/(xb-xa);if(k>0&&k<=1)for(i=0;i<abs(xb-xa);i++){ d=ya+0.5-k*(xa+1)-b;if(d>=0){ xi=xa+1;yi=ya;xa++;ya=ya+0.5;}if(d<0){ xi=xa+1;yi=ya+1;xa++;ya=ya+1.5;}pdc->SetPixel(xi,yi,COLOR); }//BresenHam画直线结束}四、实验结果抓图与分析1、DDA生成直线2、Bresenham画直线3、中点画线法实验二、bresenham画圆一、实验内容根据提供的程序框架,修改部分代码,用Bresenham画法画一段圆弧或者画圆。
实验四二维几何变换一、实验学时:1学时二、实验类型:验证型实验三、实验目的和要求:1、掌握二维图形的基本几何变换,如平移、旋转、缩放、对称变换等;2、掌握OpenGL中模型变换函数,实现简单的动画技术。
四、实验内容:1、下面的代码采用GLUT库,实现了一个矩形在窗口中转动,请修改代码,实现矩形在窗口内的其它变换,如沿水平线平移。
#include <windows.h>#include <GL/glut.h>static GLfloat spin = 0.0; //旋转角度static GLfloat offsetX = 0.0; //平移量static GLfloat offsetY = 0.0;void display(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f (0.0, 0.0, 1.0); //使用蓝色绘制图元glMatrixMode (GL_MODELVIEW); //使用模型视图变换矩阵实现几何变换,矩阵大小为4x4 glLoadIdentity ( ); //使当前变换矩阵为单位矩阵glRotatef(spin, 0.0, 0.0, 1.0); //设置旋转参数.绕z轴旋转glRectf(-10.0, -10.0, 10.0, 10.0); //绘制矩形glutSwapBuffers(); //交换显示缓冲区,因为使用了双缓存}void spinDisplay(void) //计算旋转角度,每次增加10度{spin = spin + 10.0;if (spin > 360.0)spin = spin - 360.0;//发出重绘请求。
该请求发出后,系统调用glutDisplayFunc中//注册的回调函数,在该例中,相当于重新调用display函数glutPostRedisplay();}void init(void){glClearColor (0.0, 0.0, 0.0, 0.0);glShadeModel (GL_FLAT);//OpenGL中存在多种矩阵变换,这里设定当前使用的矩阵为投影矩阵glMatrixMode(GL_PROJECTION);//投影矩阵为2D正交投影,在2D观察变换中相//当于给出了投影参数//该函数常用于在2D变换中指定裁剪窗口的位置(在世界坐标系下)gluOrtho2D(-50.0, 50.0, -50.0, 50.0);}//鼠标响应函数,控制当鼠标接收到不同的用户操作时将要执行的后续命令。
实验1 直线的绘制实验目的1、通过实验,进一步理解和掌握DDA和Bresenham算法;2、掌握以上算法生成直线段的基本过程;3、通过编程,会在TC环境下完成用DDA或中点算法实现直线段的绘制。
实验环境计算机、Turbo C或其他C语言程序设计环境实验学时2学时,必做实验。
实验内容用DDA算法或Besenham算法实现斜率k在0和1之间的直线段的绘制。
实验步骤1、算法、原理清晰,有详细的设计步骤;2、依据算法、步骤或程序流程图,用C语言编写源程序;3、编辑源程序并进行调试;4、进行运行测试,并结合情况进行调整;5、对运行结果进行保存与分析;6、把源程序以文件的形式提交;7、按格式书写实验报告。
实验代码:DDA:# include <graphics.h># include <math.h>void DDALine(int x0,int y0,int x1,int y1,int color){int dx,dy,epsl,k;float x,y,xIncre,yIncre;dx=x1-x0;dy=y1-y0;x=x0;y=y0;if(abs(dx)>abs(dy))epsl=abs(dx);elseepsl=abs(dy);xIncre=(float)dx/(float)epsl;yIncre=(float)dy/(float)epsl;for(k=0;k<=epsl;k++){putpixel((int)(x+0.5),(int)(y+0.5),4);x+=xIncre;y+=yIncre;}}main(){int gdriver ,gmode ;gdriver = DETECT;initgraph(&gdriver , &gmode ,"C:\\TC20\\BGI");DDALine(0,0,35,26,4);getch ( );closegraph ( );}Bresenham:#include<graphics.h>#include<math.h>void BresenhamLine(int x0,int y0,int x1,int y1,int color) {int x,y,dx,dy,e;dx=x1-x0;dy=y1-y0;e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y,color);x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}main(){int gdriver ,gmode ;gdriver = DETECT;initgraph(&gdriver , &gmode ,"c:\\TC20\\BGI");BresenhamLine(0, 0 , 120, 200,5 );getch ( );closegraph ( );}实验2 圆和椭圆的绘制实验目的1、通过实验,进一步理解和掌握中点算法;2、掌握以上算法生成椭圆或圆的基本过程;3、通过编程,会在TC环境下完成用中点算法实现椭圆或圆的绘制。
贵州大学实验报告学院:计算机科学与信息学院专业:计算机科学与技术班级:101姓名学号实验组 6 实验时间2013.5.9 指导教师吴云成绩实验项目名称二维图形的几何变换实验目的掌握二维图形的基本几何变换:位置改变(平移、旋转)和变形(缩放、错切,反射、投影等)以及复合变换。
实验要求1、在VS2010环境下利用C#编程实现画二维图形的几何变换。
2、给出代码。
3、附上结果截图。
实验原理标准齐次坐标(x,y,1) 二维变换的矩阵表示平移变换旋转变换放缩变换平移变换只改变图形的位置,不改变图形的大小。
旋转变换不改变图形的形状放缩变换引起图形形状的变化。
复合变换结果与变换的顺序有关(矩阵乘法不可交换)例:对一矩形先缩放S(2,0.5),再旋转R(p/6)。
对称变换关于x轴的对称变换:关于y轴的对称变换:实验环境VS2010(C#)实验步骤1. 掌握算法原理;2. 依据算法,编写源程序并进行调试;下面缩放变化的算法实现:private void TriangleChange()//缩?小?{Pen pen = new Pen(Color.Gray, 2);int x, y;x = point.X + 50;y = point.Y - 100;Point[] points ={new Point(x,y),new Point((x+point.X+10)/2,(y+point.Y-20)/2),new Point((x+point.X+80)/2,(y+point.Y-50)/2) };graphics.DrawPolygon(pen, points);}下面是旋转变化的算法实现:实验内容1.设有一三角形ABC,其中三个顶点为A(5,10),B(1,2),C(8,5),如三角形的顶点A不变,将AB和AC边缩小一倍后,求缩小后的三角形对于直线-2x+4y+3=0的对称变换后的结果图。
2.将一四边形以原点为中心,以15°为间隔旋转。
实验一、直线的生成实验目的:1、掌握DDA直线画法、中点画线法和Bresenham画线法2、掌握VC++简单程序设计方法实验内容:根据提供的程序框架,修改部分代码,完成画一条直线的功能(中点画线法或者Bresenham画线法任选一),只要求实现在第一象限内的直线。
实验步骤和方法:首先启动Visual C++ (注意,其它版本程序无法正确编译),文件(file)→打开工作空间(open workspace)。
打开实验12用基本图形生成\基本图形生成.dsw。
在fileview窗口,source file下,双击直线生成,或者classview 窗口下,cmyview类下相应的函数,按注释改写下列函数:void CMyView::OnDdaline() (此为DDA生成直线)void CMyView::OnBresenhamline()(此为Bresenham画直线)void CMYView::OnMidPointLine()(此为中点画线法)程序代码说明:1、直线的两个端点,由对话框输入,给定程序已经完成输入代码。
2、SetPixel的用法:1、COLORREF SetPixel(int x, int y, COLORREFcrColor);sw2、改写二维变换里的void CMyView::OnMove()函数(需要改写的地方已经做了说明)。
3、生成直线的函数采用VC里的函数。
4、函数的主要任务是计算出平移后的坐标。
程序代码说明:绘制一条直线需要两个函数。
pdc->MoveTo(int x, int y); 将当前点移动至(x ,y)坐标pdc->LineTo(int x, int y); 从当前点绘制一条直线至(x,y)坐标,并将当前点移动至(x,y)。
比如,要绘制一条直线,起点(x0, y0),终点(x1, y1):pdc->MoveTo(x0,y0);pdc->LineTo(x1,y1);1、sw2、改写二维变换里的void CMyView::OnRotate()函数(需要改写的地方我已经做了说明)。
实验五图形几何变换的实现班级 08信计2班学号 20080502057 姓名冯双捷分数一.实验目的和要求1.掌握二维、三维图形基本变换的变换原理;2.利用TurboC实现二维、三维图形的基本变换和符合变换3.屏幕显示变换过程和变换结果。
二.实验内容1.原程序实现二维图形(直线)的平移变换;=±(1)沿x轴的平移公式:'x x r=±(2)沿y轴的平移公式:'y y s2.源程序实现三维图形(立方体)的旋转变换和比例变换。
(1)旋转变换即图形围绕圆心逆时针旋转一定的角度;(2)比例变换即对象距圆点的距离按照一定比例进行变换。
三.实验结果分析1.二维平移程序代码#include <stdio.h>#include <graphics.h>#include <conio.h>int initjuzhen(m)int m[3][3];{int i,j;for(i=0;i<3;i++)for(j=0;j<3;j++)m[i][j]=0;for(i=0;i<3;i++)m[i][i]=1;}main(){int x0,y0,x1,y1,i,j;int a[3][3];char key;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode," ");cleardevice();setcolor(2);x0=250;y0=120;x1=350;y1=220;line(x0,y0,x1,y1);for(;;){outtextxy(100,400,"<-:left ->:right^:up v:down Esc->exit");key=getch();initjuzhen(a);switch(key){case 75:a[2][0]=-10;break;case 77:a[2][0]=10;break;case 72:a[2][1]=-10;break;case 80:a[2][1]=10;break;case 27:exit();break;}x0=x0*a[0][0]+y0*a[1][0]+a[2][0];y0=x0*a[0][1]+y0*a[1][1]+a[2][1];x1=x1*a[0][0]+y1*a[1][0]+a[2][0];y1=x1*a[0][1]+y1*a[1][1]+a[2][1];clearviewport();line(x0,y0,x1,y1);}closegraph();}运行结果见文件夹:ERWEI2.三维图形旋转转换,比例变换程序代码:#include <stdio.h>#include <math.h>#include <graphics.h>#include <conio.h>#include <time.h>#include <ctype.h>#define ZOOM_IN 0.9#define ZOOM_OUT 1.1int turn1[3];typedef struct{float x;float y;float z;}point;typedef struct{float x;float y;}point2d;typedef struct{float x;float y;float h;point biao[8];}fanti;void make_box(float x,float y,float h,fanti *p) {p->x=x;p->y=y;p->h=h;p->biao[0].x=x/2;p->biao[0].y=y/2;p->biao[0].z=h/2;p->biao[1].x=-x/2;p->biao[1].y=y/2;p->biao[1].z=h/2;p->biao[2].x=-x/2;p->biao[2].y=-y/2;p->biao[2].z=h/2;p->biao[3].x=x/2;p->biao[3].y=-y/2;p->biao[3].z=h/2;p->biao[4].x=x/2;p->biao[4].y=y/2;p->biao[4].z=-h/2;p->biao[5].x=-x/2;p->biao[5].y=y/2;p->biao[5].z=-h/2;p->biao[6].x=-x/2;p->biao[6].y=-y/2;p->biao[6].z=-h/2;p->biao[7].x=x/2;p->biao[7].y=-y/2;p->biao[7].z=-h/2;}void turn2d(point *p,point2d *q){q->x=p->x+p->z*cos(0.25);q->y=p->y+p->z*sin(0.25);}void initm(float mat[][4]){int count;for(count=0;count<4;count++){mat[count][0]=0.;mat[count][1]=0.;mat[count][2]=0.;mat[count][3]=0.;mat[count][count]=1.;}return;}void transform(point *p,point *q,float tm[][4]){float xu,yv,zw,h;xu=tm[0][0]*p->x+tm[1][0]*p->y+tm[2][0]*p->z+tm[3][0];yv=tm[0][1]*p->x+tm[1][1]*p->y+tm[2][1]*p->z+tm[3][1];zw=tm[0][2]*p->x+tm[1][2]*p->y+tm[2][2]*p->z+tm[3][2];p->x=xu;p->y=yv;p->z=zw;return;}void rotationx(point *p,float alfa,float tm[][4]){float rad=0.0174532925;initm(tm);tm[1][1]=cos(rad*alfa);tm[1][2]=sin(rad*alfa);tm[2][1]=-tm[1][2];tm[2][2]=tm[1][1];return;}void rotationz(point *p,float alfa,float tm[][4]){float rad=0.0174532925;initm(tm);tm[0][0]=cos(rad*alfa);tm[0][1]=sin(rad*alfa);tm[1][0]=-tm[0][1];tm[1][1]=tm[0][0];return;}void rotationy(point *p,float alfa,float tm[][4]) {float rad=0.0174532925;initm(tm);tm[0][0]=cos(rad*alfa);tm[2][0]=sin(rad*alfa);tm[0][2]=-tm[2][0];tm[2][2]=tm[0][0];return;}void adjust(point *p,point *q){float t[4][4];switch(turn1[0]){case 1:rotationy(p,2,t);transform(p,q,t);break;case -1:rotationy(p,-2,t);transform(p,q,t);break;default:break;}switch(turn1[1]){case 1:rotationz(p,2,t);transform(p,q,t);break;case -1:rotationz(p,-2,t);transform(p,q,t);break;default:break;}switch(turn1[2]){case 1:q->x=ZOOM_IN*p->x;q->y=ZOOM_IN*p->y;q->z=ZOOM_IN*p->z;break;case -1:q->x=ZOOM_OUT*p->x;q->y=ZOOM_OUT*p->y;q->z=ZOOM_OUT*p->z;break;default:break;}}void drawbox(fanti *p){point2d fan2d[8];int i;for(i=0;i<=7;i++){adjust(&p->biao[i],&p->biao[i]);turn2d(&p->biao[i],&fan2d[i]);fan2d[i].x+=300;fan2d[i].y+=200;}clearviewport();setcolor(2);outtext("\n ->:right\n <-:left\n ^:up\n v:down");moveto(0,10);outtext("\n page up:zoom in\n page down:zoom out\n space:Redraw\n Esc:exit");for(i=0;i<=3;i++){if(i==3){line(fan2d[i].x,fan2d[i].y,fan2d[0].x,fan2d[0].y);line(fan2d[i+4].x,fan2d[i+4].y,fan2d[4].x,fan2d[4].y);}else{line(fan2d[i].x,fan2d[i].y,fan2d[i+1].x,fan2d[i+1].y);line(fan2d[i+4].x,fan2d[i+4].y,fan2d[i+5].x,fan2d[i+5].y);}line(fan2d[i].x,fan2d[i].y,fan2d[i+4].x,fan2d[i+4].y);}}void main(){int gd=DETECT,gm,i,j;char key;float x,y,h;fanti a1;x=100;y=100;h=100;initgraph(&gd,&gm," ");make_box(x,y,h,&a1);drawbox(&a1);for(;;){turn1[0]=0;turn1[1]=0;turn1[2]=0;key=getch();switch(key){case 77:turn1[0]=1;break;case 75:turn1[0]=-1;break;case 72:turn1[0]=1;break;case 80:turn1[0]=-1;break;case 73:turn1[2]=1;break;case 81:turn1[2]=-1;break;case 32:make_box(x,y,h,&a1);break;case 27:exit();break;default:key=0;break;}if(key!=0)drawbox(&a1);}closegrapg();}运行结果见文件夹:SANWEI3.分析使用矩阵保存图形的坐标位置的方法,二维图形的平移就是一个坐标位置移到另一个坐标位置的重定位过程;对于三维的图形的旋转变换就是图形相应的矩阵进行角度的初等变换,而比例变换即是图形矩阵的相应比例变换。
#include "stdio.h"#include "conio.h"#include"graphics.h"#include "math.h"struct point{int x;int y;}triangle[3];void ini(){ triangle[0].x = 20;triangle[0].y = 70;triangle[1].x = 20;triangle[1].y = 100;triangle[2].x = 120;triangle[2].y = 70;setcolor(WHITE);line(triangle[0].x,triangle[0].y,triangle[1].x,triangle[1].y);line(triangle[0].x,triangle[0].y,triangle[2].x,triangle[2].y);line(triangle[1].x,triangle[1].y,triangle[2].x,triangle[2].y);}void move(int dx, int dy){int i;for(i = 0; i < 3; i++){line((triangle[i].x+dx),(triangle[i].y+dy),(triangle[(i+1)%3].x+dx),(triangle[(i+1)%3].y+dy));}getch();setcolor(0);for(i = 0; i < 3; i++){line((triangle[i].x+dx),(triangle[i].y+dy),(triangle[(i+1)%3].x+dx),(triangle[(i+1)%3].y+dy));}}void zoom(int sx,int sy){int yy[3];int i;for(i = 0; i < 3; i++){xx[i]=(triangle[i].x-triangle[0].x)*sx+triangle[0].x;yy[i]=(triangle[i].y-triangle[0].y)*sy+triangle[0].y;}for(i = 0; i < 3; i++){line(xx[i]+120,yy[i],xx[(i+1)%3]+120,yy[(i+1)%3]);}getch();setcolor(0);for(i = 0; i < 3; i++){line(xx[i]+120,yy[i],xx[(i+1)%3]+120,yy[(i+1)%3]);}}void turn(int x, int y, int a){int i;int xx[3];int yy[3];for(i = 0; i < 3; i++){xx[i]=(triangle[i].x-x)*cos(a)-(triangle[i].y-y)*sin(a)+x;yy[i]=(triangle[i].x-x)*sin(a)+(triangle[i].y-y)*cos(a)+y;}for(i = 0; i < 3; i++){line(xx[i],yy[i],xx[(i+1)%3],yy[(i+1)%3]);}getch();setcolor(0);for(i = 0; i < 3; i++){line(xx[i],yy[i],xx[(i+1)%3],yy[(i+1)%3]);}}void symmetrical(int a, int b, int d, int e){int i;int yy[3];for(i = 0; i < 3; i++){xx[i]=(a*triangle[i].x)+(b*triangle[i].y);yy[i]=(d*triangle[i].x)+(e*triangle[i].y);}for(i = 0; i < 3; i++){line(xx[i]+120+420,yy[i],xx[(i+1)%3]+120+420,yy[(i+1)%3]);}getch();setcolor(0);for(i = 0; i < 3; i++){line(xx[i]+120+420,yy[i],xx[(i+1)%3]+120+420,yy[(i+1)%3]);}}void dislocation(int b, int d){int i;int xx[3];int yy[3];for(i = 0; i < 3; i++){xx[i]=triangle[i].x+(b*triangle[i].y);yy[i]=(d*triangle[i].x)+triangle[i].y;}for(i = 0; i < 3; i++){line(xx[i],yy[i],xx[(i+1)%3],yy[(i+1)%3]);}getch();setcolor(0);for(i = 0; i < 3; i++){line(xx[i],yy[i],xx[(i+1)%3],yy[(i+1)%3]);}}void main(){int graphdriver=VGA,graphmode=VGAHI;initgraph(&graphdriver,&graphmode,"");ini();getch();setcolor(BLUE);move(300,200);ini();setcolor(BLUE);zoom(2,2);ini();setcolor(BLUE);turn(120,70,-1);ini();setcolor(BLUE);symmetrical(-1, 0, 0, 1);ini();setcolor(BLUE);dislocation(0, 2);ini();closegraph();}。
c++二维几何变换在C++中进行二维几何变换通常涉及到对点的操作,比如平移、旋转、缩放等。
以下是一个简单的例子,展示如何在C++中进行二维几何变换:```cpp#include <iostream>#include <cmath>// 定义二维点结构struct Point {double x;double y;// 构造函数Point(double _x, double _y) : x(_x), y(_y) {}// 输出点的坐标void print() const {std::cout << "(" << x << ", " << y << ")";}};// 定义二维几何变换类class GeometricTransformation {public:// 平移变换static Point translate(const Point& p, double dx, double dy) {return Point(p.x + dx, p.y + dy);}// 旋转变换static Point rotate(const Point& p, double angleDegrees) {double angleRadians = angleDegrees * M_PI / 180.0;double newX = p.x * cos(angleRadians) - p.y * sin(angleRadians);double newY = p.x * sin(angleRadians) + p.y * cos(angleRadians);return Point(newX, newY);}// 缩放变换static Point scale(const Point& p, double scaleX, double scaleY) {return Point(p.x * scaleX, p.y * scaleY);}};int main() {// 创建一个点Point originalPoint(1.0, 1.0);// 打印原始点std::cout << "Original Point: ";originalPoint.print();std::cout << std::endl;// 进行平移变换Point translatedPoint = GeometricTransformation::translate(originalPoint, 2.0, 3.0);std::cout << "Translated Point: ";translatedPoint.print();std::cout << std::endl;// 进行旋转变换Point rotatedPoint = GeometricTransformation::rotate(originalPoint, 45.0);std::cout << "Rotated Point: ";rotatedPoint.print();std::cout << std::endl;// 进行缩放变换Point scaledPoint = GeometricTransformation::scale(originalPoint, 1.5, 2.0);std::cout << "Scaled Point: ";scaledPoint.print();std::cout << std::endl;return 0;}```在这个例子中,`Point` 结构表示一个二维点,而`GeometricTransformation` 类包含了静态方法来执行平移、旋转和缩放变换。
实验一:二维图形的绘制和变换一、实验目的掌握基本的图形学算法,熟悉VC下图形学的编程,初步了解并使用OpenGL 绘制图形。
二、实验内容二维图形的绘制和变换,绘制包括直线、三角形、矩形,变换包括平移、旋转、缩放。
三、实验原理二维图形的绘制和变换:在图形系统中,矩阵是实现变换的标准方法。
平移变换、旋转变换和缩放变换的矩阵表示形式如下。
平移变换:P’=P+T。
旋转变换:P’=R*P。
缩放变换:P’=S*P。
引入齐次坐标后,平移、旋转和缩放变换的矩阵表示形式如下所示。
(1)平移变换:[1 0 0][x’, y’, 1] = [x, y, 1] [0 1 0][tx ty 1](2)旋转变换:[cosɵsinɵ0][x’, y’, 1] = [x, y, 1] [-sinɵcosɵ0][0 0 1](3)缩放变换:[s x0 0][x’, y’, 1] = [x, y, 1] [0 s y0][0 0 1]四、实验代码及结果1.编写对一个三角形分别实现平移、缩放、旋转等变化的源码及效果图。
实验核心代码void display(void){glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glLoadIdentity ();glColor3f (1.0, 1.0, 1.0);glTranslatef(-100.0,-50.0,1.0);draw_triangle ();glLoadIdentity ();glTranslatef (0.0, 100.0, 1.0);draw_triangle ();glLoadIdentity ();glRotatef (90.0, 0.0, 0.0, 1.0);draw_triangle ();glLoadIdentity ();glScalef (0.5, 0.5, 1.0);draw_triangle ();glFlush ();}2. 实现如图功能#include<windows.h>#include <GL/glut.h>#include <stdlib.h>void init(void){glClearColor (0.0, 0.0, 0.0, 0.0);glShadeModel (GL_SMOOTH); }void draw_triangle(void){glShadeModel(GL_SMOOTH);glColor3f(0.2,0.7,0.30);glBegin (GL_TRIANGLES);//画出三角形,为混合色填充方式glVertex2f(50.0, 25.0);glColor3f(0.4,0.5,0.60);glVertex2f(150.0, 25.0);glColor3f(0.9,0.7,0.8);glVertex2f(100.0, 100.0);glEnd();}void display(void){glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glLoadIdentity ();glColor3f (1.0, 1.0, 1.0);glTranslatef(-100.0,-50.0,1.0);draw_triangle ();glLoadIdentity ();glTranslatef (0.0, 100.0, 1.0);glRotatef (90.0, 0.0, 0.0, 1.0);glScalef (0.5, 0.5, 1.0);draw_triangle ();//经过三种变换后画出图形glFlush ();}void reshape (int w, int h){glViewport (0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode (GL_PROJECTION);glLoadIdentity ();if (w <= h)gluOrtho2D (-200.0, 250.0, -100.0*(GLfloat)h/(GLfloat)w,200.0*(GLfloat)h/(GLfloat)w);//调整裁剪窗口elsegluOrtho2D (-200.0*(GLfloat)w/(GLfloat)h,250.0*(GLfloat)w/(GLfloat)h, -50.0, 200.0);glMatrixMode(GL_MODELVIEW);int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);glutInitWindowSize (600, 600);glutInitWindowPosition (100, 100);glutCreateWindow (argv[0]);init ();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoop();return 0;}实验二:使用中点扫描算法绘制直线和圆一、实验目的掌握基本的图形学算法,熟悉VC下图形学的编程,初步了解并使用OpenGL 绘制图形。
#include "stdio.h"
#include "conio.h"
#include"graphics.h"
#include "math.h"
struct point
{
int x;
int y;
}triangle[3];
void ini()
{ triangle[0].x = 20;
triangle[0].y = 70;
triangle[1].x = 20;
triangle[1].y = 100;
triangle[2].x = 120;
triangle[2].y = 70;
setcolor(WHITE);
line(triangle[0].x,triangle[0].y,triangle[1].x,triangle[1].y);
line(triangle[0].x,triangle[0].y,triangle[2].x,triangle[2].y);
line(triangle[1].x,triangle[1].y,triangle[2].x,triangle[2].y);
}
void move(int dx, int dy)
{
int i;
for(i = 0; i < 3; i++)
{
line((triangle[i].x+dx),(triangle[i].y+dy),(triangle[(i+1)%3].x+dx),(triangle[(i+1)%3].y+dy));
}
getch();
setcolor(0);
for(i = 0; i < 3; i++)
{
line((triangle[i].x+dx),(triangle[i].y+dy),(triangle[(i+1)%3].x+dx),(triangle[(i+1)%3].y+dy));
}
}
void zoom(int sx,int sy)
{
int yy[3];
int i;
for(i = 0; i < 3; i++)
{
xx[i]=(triangle[i].x-triangle[0].x)*sx+triangle[0].x;
yy[i]=(triangle[i].y-triangle[0].y)*sy+triangle[0].y;
}
for(i = 0; i < 3; i++)
{
line(xx[i]+120,yy[i],xx[(i+1)%3]+120,yy[(i+1)%3]);
}
getch();
setcolor(0);
for(i = 0; i < 3; i++)
{
line(xx[i]+120,yy[i],xx[(i+1)%3]+120,yy[(i+1)%3]);
}
}
void turn(int x, int y, int a)
{
int i;
int xx[3];
int yy[3];
for(i = 0; i < 3; i++){
xx[i]=(triangle[i].x-x)*cos(a)-(triangle[i].y-y)*sin(a)+x;
yy[i]=(triangle[i].x-x)*sin(a)+(triangle[i].y-y)*cos(a)+y;
}
for(i = 0; i < 3; i++)
{
line(xx[i],yy[i],xx[(i+1)%3],yy[(i+1)%3]);
}
getch();
setcolor(0);
for(i = 0; i < 3; i++)
{
line(xx[i],yy[i],xx[(i+1)%3],yy[(i+1)%3]);
}
}
void symmetrical(int a, int b, int d, int e)
{
int i;
int yy[3];
for(i = 0; i < 3; i++){
xx[i]=(a*triangle[i].x)+(b*triangle[i].y);
yy[i]=(d*triangle[i].x)+(e*triangle[i].y);
}
for(i = 0; i < 3; i++)
{
line(xx[i]+120+420,yy[i],xx[(i+1)%3]+120+420,yy[(i+1)%3]);
}
getch();
setcolor(0);
for(i = 0; i < 3; i++)
{
line(xx[i]+120+420,yy[i],xx[(i+1)%3]+120+420,yy[(i+1)%3]);
}
}
void dislocation(int b, int d)
{
int i;
int xx[3];
int yy[3];
for(i = 0; i < 3; i++){
xx[i]=triangle[i].x+(b*triangle[i].y);
yy[i]=(d*triangle[i].x)+triangle[i].y;
}
for(i = 0; i < 3; i++)
{
line(xx[i],yy[i],xx[(i+1)%3],yy[(i+1)%3]);
}
getch();
setcolor(0);
for(i = 0; i < 3; i++)
{
line(xx[i],yy[i],xx[(i+1)%3],yy[(i+1)%3]);
}
}
void main()
{
int graphdriver=VGA,graphmode=VGAHI;
initgraph(&graphdriver,&graphmode,"");
ini();
getch();
setcolor(BLUE);
move(300,200);
ini();
setcolor(BLUE);
zoom(2,2);
ini();
setcolor(BLUE);
turn(120,70,-1);
ini();
setcolor(BLUE);
symmetrical(-1, 0, 0, 1);
ini();
setcolor(BLUE);
dislocation(0, 2);
ini();
closegraph();
}。