计算机图形学实验报告 (2)

合集下载

计算机图形学实验报告 (2)

计算机图形学实验报告 (2)

实验一Window图形编程根底一、实验类型:验证型实验二、实验目的1、熟练使用实验主要开发平台VC6.0;2、掌握如何在编译平台下编辑、编译、连接和运行一个简单的Windows图形应用程序;3、掌握Window图形编程的根本方法;4、学会使用根本绘图函数和Window GDI对象;三、实验内容创立基于MFC的Single Document应用程序〔Win32应用程序也可,同学们可根据自己的喜好决定〕,程序可以实现以下要求:1、用户可以通过菜单项选择择绘图颜色;2、用户点击菜单项选择择绘图形状时,能在视图中绘制指定形状的图形;四、实验要求与指导1、建立名为“颜色〞的菜单,该菜单下有四个菜单项:红、绿、蓝、黄。

用户通过点击不同的菜单项,可以选择不同的颜色进行绘图。

2、建立名为“绘图〞的菜单,该菜单下有三个菜单项:直线、曲线、矩形其中“曲线〞项有级联菜单,包括:圆、椭圆。

3、用户通过点击“绘图〞中不同的菜单项,弹出对话框,让用户输入绘图位置,在指定位置进行绘图。

五、实验结果:六、实验主要代码1、画直线:CClientDC *m_pDC;再在OnDraw函数里给变量初始化m_pDC=new CClientDC(this);在OnDraw函数中添加:m_pDC=new CClientDC(this);m_pDC->MoveTo(10,10);m_pDC->LineTo(100,100);m_pDC->SetPixel(100,200,RGB(0,0,0));m_pDC->TextOut(100,100);2、画圆:void CMyCG::LineDDA2(int xa, int ya, int xb, int yb, CDC *pDC){int dx = xb - xa;int dy = yb - ya;int Steps, k;float xIncrement,yIncrement;float x = xa,y= ya;if(abs(dx)>abs(dy))Steps = abs(dx);elseSteps = abs(dy);xIncrement = dx/(float)Steps;yIncrement = dy/(float)Steps;pDC->SetPixel(ROUND(x),ROUND(y),RGB(0,0,0));for(k=0;k<Steps;k++){x +=xIncrement;y +=yIncrement;sleep(10);pDC->SetPixel(ROUND(x),ROUND(y),RGB(0,0,0));}3、画矩形void CRectangleDlg::OnLButtonDown(UINT nFlags, CPoint point){lButtonDownNotUp = TRUE;RECT rect;m_showRectangle. GetClientRect( &rect ) ;if( (point. x<rect. right) && (point. x>rect. left) && (point. y<rect. bottom) && (point. y>rect. top) ){regionLeftTopTemp = point;}CDialog::OnLButtonDown(nFlags, point);}void CRectangleDlg::OnMouseMove(UINT nFlags, CPoint point){RECT rect;m_showRectangle. GetClientRect( &rect );if( ( point.x<rect.right ) && ( point.x>rect.left ) && ( point.y<rect.bottom ) && ( point.y>rect.top ) ){if( ( lButtonDownNotUp == TRUE ){regionRightBottomTemp = point;CDC * pDC = m_showRectangle. GetWindowDC ();pDC -> Rectangle( CRect( regionLeftTopTemp, regionRightBottomTemp ) ) ;}}CDialog::OnMouseMove(nFlags, point);}void CRectangleDlg::OnLButtonUp(UINT nFlags, CPoint point){lButtonDownNotUp=FALSE;CDialog::OnLButtonUp(nFlags, point);}实验二根本图形生成算法一、实验类型:验证型实验二、实验目的1、掌握DDA、Bresenham直线生成算法;2、掌握Bresenham或中点圆生成算法;3、掌握Bresenham或中点椭圆生成算法;三、实验内容1、实现DDA、Bresenham直线生成算法;2、实现Bresenham画圆法或中点画圆法;3、实现Bresenham或中点法椭圆生成算法;4、利用1、2、3实现的直线、圆、椭圆图形生成函数进行图形绘制;四、实验要求与指导1、按照实验指导书1.6节创立一个基于MFC的Single Document应用程序。

实验二:图形填充算法实验报告

实验二:图形填充算法实验报告

《计算机图形学》实验报告(实验二:图形填充算法)一、实验目的及要求用两种方法做图形的填充算法!二、理论基础1.边填充算法对于每一条扫描线和每条多边形的交点(x1,y1),将该扫描线上的交点右方的所有像素取补。

2.种子填充算法利用栈来实现种子填充算法。

种子像素入栈,当栈非空时重复执行如下步骤:将栈顶像素出栈,将出栈像素置成多边形色,按左,上,右,下顺序检查与出栈像素相邻的四个像素,若其中某个像素不再边界且未置成多边形,则把该像素入栈!三、算法设计与分析1、边填充算法void CEdge_mark_fillView::OnDraw(CDC* pDC){CEdge_mark_fillDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);int d[500][500]={0};int inside;int x,y;Bresenham(80,101,100,400,d);Bresenham(100,300,290,400,d);Bresenham(292,400,382,50,d);Bresenham(380,50,202,150,d);Bresenham(200,150,82,101,d);for(y=0;y<500;y++){inside=0;for(x=0;x<500;x++){if(d[x][y]==1)if(d[x+1][y]!=1){inside=!(inside);}if(inside!=0)pDC->SetPixel(x,y,12);}}}2、种子填充int x=299,y=51;COLORREF oldcolor;COLORREF newcolor;oldcolor=RGB(256,256,256);newcolor=RGB(123,123,123);pDC->MoveTo (40,40);pDC->LineTo (80,40);pDC->LineTo (70,80);pDC->LineTo (40,40);FloodFill(51,51,RGB(255,255,255),RGB(0,0,255));pDC->LineTo (40,40);void CMyView::FloodFill(int x,int y,COLORREF oldcolor,COLORREF newcolor) {CDC* pDC;pDC=GetDC();if(pDC->GetPixel(x,y)==oldcolor){pDC->SetPixel(x,y,newcolor);FloodFill(x,y-1,oldcolor,newcolor);FloodFill(x,y+1,oldcolor,newcolor);FloodFill(x-1,y,oldcolor,newcolor);FloodFill(x+1,y,oldcolor,newcolor);}四、程序调试及结果的分析1、2、四、实验心得及建议由于很多不会,所以这次没能按时当堂完成,下来花了不少时间才弄出来,第二种尤其比较麻烦,在同学的帮助下才做出来了。

计算机图形学第二次实验报告

计算机图形学第二次实验报告

计算机图形学实验报告2015-2016学年第一学期班级计自1302 学号姓名一.实验内容与实验步骤1.实验内容实现一个二维或三维裁剪算法,或实现一个Bezier曲线或Bezier曲面算法,并能够实现曲线曲面的形状修改。

2.主要思路每一裁剪窗口边界将二维空间划分成内部和外部的两个半空间。

一旦给所有的的线段端点建立了区域码,就可以快速判断哪条线段完全在裁剪窗口之内,哪条线段完全在窗口之外。

3.部分源代#include"stdafx.h"#include<GL/glut.h>#include<math.h>#include<GL/gl.h>#include<stdio.h>#include<stdlib.h>int flag;void setPixel(GLintx,GLint y){glBegin(GL_POINTS);glVertex2i(x, y);glEnd();}/* Bresenham line-drawing procedure for |m| < 1.0. */void lineBres (float x0, float y0, float xEnd, float yEnd){int dx =fabs(xEnd - x0), dy =fabs(yEnd - y0);int p = 2 * dy - dx;int twoDy = 2 * dy, twoDyMinusDx = 2 * (dy - dx);int x, y;/* Determine which endpoint to use as start position. */if (x0 >xEnd) {x = xEnd;y = yEnd;xEnd = x0;}else {x = x0;y = y0;}setPixel (x, y);while (x <xEnd) {x++;if (p < 0)p += twoDy;else {y++;p += twoDyMinusDx;}setPixel (x, y);}}class wcPt2D {public:GLfloat x, y;};inline GLint round (const GLfloat a) { return GLint (a + 0.5); }/* Define a four-bit code for each of the outside regions of a * rectangular clipping window.*/const GLintwinLeftBitCode = 0x1;const GLintwinRightBitCode = 0x2;const GLintwinBottomBitCode = 0x4;const GLintwinTopBitCode = 0x8;inline GLint inside (GLint code) { return GLint (!code); } inline GLint reject (GLint code1, GLint code2){ return GLint (code1 & code2); }inline GLint accept (GLint code1, GLint code2){ return GLint (!(code1 | code2)); }GLubyte encode (wcPt2D pt, wcPt2D winMin, wcPt2D winMax){GLubyte code = 0x00;if (pt.x<winMin.x)code = code | winLeftBitCode;if (pt.x>winMax.x)code = code | winRightBitCode;if (pt.y<winMin.y)code = code | winBottomBitCode;if (pt.y>winMax.y)code = code | winTopBitCode;return (code);}void swapPts (wcPt2D * p1, wcPt2D * p2){wcPt2Dtmp;tmp = *p1; *p1 = *p2; *p2 = tmp;}void swapCodes (GLubyte * c1, GLubyte * c2){GLubytetmp;tmp = *c1; *c1 = *c2; *c2 = tmp;}void lineClipCohSuth (wcPt2D winMin, wcPt2D winMax, wcPt2D p1, wcPt2D p2) {GLubyte code1, code2;GLint done = false, plotLine = false;GLfloat m;while (!done) {code1 = encode (p1, winMin, winMax);code2 = encode (p2, winMin, winMax);if (accept (code1, code2)) {done = true;plotLine = true;}elseif (reject (code1, code2))done = true;else {/* Label the endpoint outside the display window as p1. */if (inside (code1)) {swapPts (&p1, &p2);swapCodes (&code1, &code2);}/* Use slope m to find line-clipEdge intersection. */if (p2.x != p1.x)m = (p2.y - p1.y) / (p2.x - p1.x);if (code1 &winLeftBitCode) {p1.y += (winMin.x - p1.x) * m;p1.x = winMin.x;}elseif (code1 &winRightBitCode) {p1.y += (winMax.x - p1.x) * m;p1.x = winMax.x;}elseif (code1 &winBottomBitCode) {/* Need to update p1.x for nonvertical lines only. */if (p2.x != p1.x)p1.x += (winMin.y - p1.y) / m;p1.y = winMin.y;}elseif (code1 &winTopBitCode) {if (p2.x != p1.x)p1.x += (winMax.y - p1.y) / m;p1.y = winMax.y;}}}if (plotLine)lineBres (round (p1.x), round (p1.y), round (p2.x), round (p2.y)); void myDisplay(){wcPt2DwinMin , winMax , p1 , p2;winMin.x=100; winMin.y=200;winMax.x=400; winMax.y=400;p1.x=50; p1.y=50;p2.x=450; p2.y=450;glClear(GL_COLOR_BUFFER_BIT);glColor3f (1.0f, 0.0f, 0.0f);glRectf(winMin.x ,winMin.y ,winMax.x,winMax.y);glColor3f (1.0f, 1.0f, 1.0f);if (flag){lineClipCohSuth (winMin, winMax,p1,p2);}else{glBegin(GL_LINES);glVertex2i(p1.x,p1.y);glVertex2i(p2.x,p2.y);glEnd();}glFlush();}void Init(){glClearColor(0.0, 0.0, 0.0, 0.0);glMatrixMode (GL_PROJECTION);gluOrtho2D (0.0, 640.0, 0.0, 480.0);}void Reshape(int w, int h){glViewport(0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);}void keyboard(unsignedchar key, int x, int y) {if (key=='c' || key=='C') flag=true;if (key=='r' || key=='R') flag=false;glutPostRedisplay();}int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(640, 480);glutCreateWindow("Cohen-Sutherland直线裁减算法,C 键裁减,R键复原"); Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutKeyboardFunc(keyboard);glutMainLoop();return 0;}二.实验结果三.实验总结这次实验我的收获主要有两个方面:一是编程水平的提高,还有一个是对计算机图形学理论知识的巩固。

计算机图形学实验报告_2

计算机图形学实验报告_2

计算机图形学实验报告学号:********姓名:班级:计算机 2班指导老师:***2010.6.19实验一、Windows 图形程序设计基础1、实验目的1)学习理解Win32 应用程序设计的基本知识(SDK 编程);2)掌握Win32 应用程序的基本结构(消息循环与消息处理等); 3)学习使用VC++编写Win32 Application 的方法。

4)学习MFC 类库的概念与结构;5)学习使用VC++编写Win32 应用的方法(单文档、多文档、对话框);6)学习使用MFC 的图形编程。

2、实验内容1)使用WindowsAPI 编写一个简单的Win32 程序,调用绘图API 函数绘制若干图形。

(可选任务)2 )使用MFC AppWizard 建立一个SDI 程序,窗口内显示"Hello,Thisis my first SDI Application"。

(必选任务)3)利用MFC AppWizard(exe)建立一个SDI 程序,在文档视口内绘制基本图形(直线、圆、椭圆、矩形、多边形、曲线、圆弧、椭圆弧、填充、文字等),练习图形属性的编程(修改线型、线宽、颜色、填充样式、文字样式等)。

定义图形数据结构Point\Line\Circle 等保存一些简单图形数据(在文档类中),并在视图类OnDraw 中绘制。

3、实验过程1)使用MFC AppWizard(exe)建立一个SDI 程序,选择单文档;2)在View类的OnDraw()函数中添加图形绘制代码,说出字符串“Hello,Thisis my first SDI Application”,另外实现各种颜色、各种边框的线、圆、方形、多边形以及圆弧的绘制;3)在类视图中添加图形数据point_pp,pp_circle的类,保存简单图形数据,通过在OnDraw()函数中调用,实现线、圆的绘制。

4、实验结果正确地在指定位置显示了"Hello,This is my first SDI Application"字符串,成功绘制了圆,椭圆,方形,多边形以及曲线圆弧、椭圆弧,同时按指定属性改绘了圆、方形和直线。

计算机图形学实验报告2 - DDA画线

计算机图形学实验报告2 - DDA画线
班级R数学111
大连交通大学姓名
实验报告同组人无
课程名称:计算机图形学成绩
实验名称:DDA画线_指导老师任洪海
实验目的:
函数画线
实验要求:
掌握DDA画线算法
实验仪器:
软件:VC++6.0,windows XP
硬件:计算机
实验步骤、内容:
一、新建MFC工程
1.开始所有程序Microsoft Visual C++ 6.0Microsoft Visual C++ 6.0
if(fabs(x2-x1)>fabs(y2-y1))
length=fabs(x2-x1);
else
length=fabs(y2-y1);
deltx=(x2-x1)/length;
delty=(y2-y1)/length;
x=x1;y=y1;k=1;
while(k<=length){
pDC->SetPixel((int)x,(int)y,RGB(255,0,0));
2.文件-->新建-->工程,工程名称填[项目名],左边的类型选择MFC AppWizard [exe],点击确定
3.在“您要创建的应用程序类型是:”,选择“单文档”,点击完成,点击确定。
二、添加菜单
1.左侧视图栏中有三个视图:ClassView、ResourceView、FileView,点击中间的ResourceView
三、创建、编辑函数
1.点击VC++菜单栏中的:查看建立类向导
2.在弹出的MFC ClassWized窗口中,Class name选择C[项目名]view
3.Object IDs选择ID_DDA,Messages选择COMMAND

计算机图形学实验报告

计算机图形学实验报告

计算机图形学实验报告
实验目的:通过本次实验,深入了解并掌握计算机图形学的基本原理和相关技术,培养对图形处理的理解和能力。

实验内容:
1. 图像的基本属性
- 图像的本质及表示方法
- 像素和分辨率的概念
- 灰度图像和彩色图像的区别
2. 图像的处理技术
- 图像的采集和处理
- 图像的变换和增强
- 图像的压缩和存储
3. 计算机图形学的应用
- 图像处理在生活中的应用
- 计算机辅助设计中的图形学应用
- 三维建模和渲染技术
实验步骤和结果:
1. 在计算机图形学实验平台上加载一张测试图像,分析其像素构成
和基本属性。

2. 运用图像处理技术,对测试图像进行模糊、锐化、色彩调整等操作,观察处理后的效果并记录。

3. 学习并掌握计算机图形学中常用的处理算法,如卷积、滤波等,
尝试应用到测试图像上并进行实验验证。

4. 探讨计算机图形学在数字媒体制作、虚拟现实、计算机辅助设计
等领域的应用案例,并总结其在实践中的重要性和价值。

结论:
通过本次实验,我对计算机图形学有了更深入的了解,掌握了图像
处理技术的基本原理和应用方法。

计算机图形学作为一门重要的学科,对多个领域有着广泛的应用前景,有助于提高数字媒体技术、虚拟现
实技术等领域的发展水平。

希望在未来的学习和工作中能进一步深化
对计算机图形学理论和实践的研究,不断提升自己在这一领域的专业
能力和创新意识。

山东大学计算机图形学实验报告实验二

山东大学计算机图形学实验报告实验二
山东大学计算机科学与技术学院 计算机图形学课程实验报告
学号:2420430689 姓名: QQ
班级: 2014 级
实Байду номын сангаас题目:实现二维平面的基本变换
实验学时:4
实验日期: 2017 年 3 月 28 日
实验目的: 1. 掌握配置 OpenGL 环境的方法; 2. 熟悉 OpenGL 应用程序基本架构; 3. 学习 OpenGL 中的 gl、glu、glut 等库函数进行图形学算法编程和实现。
//填充右部 while (!judgeIfBoundary(x, y)) {
glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); glFlush(); x = x + 1; } int xright = x - 1;
//填充左部 x = savex - 1; while (!judgeIfBoundary(x, y)) {
#include <cmath> #include <stack> #include <glut.h>
using namespace std;
struct mypoint {
GLint x; GLint y;
mypoint(GLint _x, GLint _y) :x(_x), y(_y) {}; mypoint() {}; };
x = x + 1; } } } } } 最后效果
结论分析与体会: 这次实验总的来讲比较繁琐,尤其是在计算校徽坐标的时候,当时是从学校官网 上找了一个比较正规的校徽,用 Windows 的画图工具打开,找出点的坐标然后用 数学方法变换的。
return true; else

计算机图形学 有效边表填充算法实验报告

计算机图形学 有效边表填充算法实验报告

实验题目: 实验二有效边表填充算法1.实验目的:设计有效边表结点和边表结点数据结构设计有效边表填充算法编程实现有效边表填充算法2.实验描述:下图 1 所示多边形覆盖了12 条扫描线, 共有7 个顶点和7 条边。

7 个顶点分别为:P0(7, 8), P1(3, 12), P2(1, 7), P3(3, 1), P4(6, 5), P5(8, 1), P6(12, 9)。

在1024×768 的显示分辩率下, 将多边形顶点放大为P0(500,400), P1(350, 600), P2(250, 350), P3(350, 50), P4(500, 250), P5(600, 50), P6(800, 450)。

请使用有效边表算法填充该多边形。

图1示例多边形图2 屏幕显示多边形3.算法设计:(1)建立AET和BUCKET类;(2)初始化桶, 并在建立桶结点时为其表示的扫描线初始化为带头结点的链表;(3)对每个桶结点进行循环, 将桶内每个结点的边表合并为有效边表, 并进行有效边表循环;(4)按照扫描线从小到大的移动顺序, 计算当前扫描线与多边形各边的交点, 然后把这些交点按X值递增的顺序进行排序, 配对, 以确定填充区间;(5)用指定颜色点亮填充区间内的所有像素, 即完成填充工作。

4.源程序:1)//AET.hclass AET{public:AET();virtual ~AET();double x;int yMax;double k;//代替1/kAET *next;};//AET..cppAET::AET(){}AET::~AET(){}2) //Bucket.h#include "AET.h"class Bucket{public:Bucket();virtual ~Bucket();int ScanLine;AET *p;//桶上的边表指针Bucket *next;};// Bucket.cppBucket::Bucket(){}Bucket::~Bucket(){}3)//TestView.h#include "AET.h"//包含有效边表类#include "Bucket.h"//包含桶类#define Number 7//N为闭合多边形顶点数, 顶点存放在整型二维数组Point[N]中class CTestView : public CView{。

《计算机图形学》实验报告

《计算机图形学》实验报告

《计算机图形学》实验报告一、实验目的计算机图形学是一门研究如何利用计算机生成、处理和显示图形的学科。

通过本次实验,旨在深入理解计算机图形学的基本原理和算法,掌握图形的生成、变换、渲染等技术,并能够运用所学知识解决实际问题,提高对图形学的应用能力和编程实践能力。

二、实验环境本次实验使用的编程语言为 Python,使用的图形库为 Pygame。

开发环境为 PyCharm。

三、实验内容1、直线的生成算法DDA 算法(Digital Differential Analyzer)Bresenham 算法DDA 算法是通过计算直线的斜率来确定每个像素点的位置。

它的基本思想是根据直线的斜率和起始点的坐标,逐步计算出直线上的每个像素点的坐标。

Bresenham 算法则是一种基于误差的直线生成算法。

它通过比较误差值来决定下一个像素点的位置,从而减少了计算量,提高了效率。

在实验中,我们分别实现了这两种算法,并比较了它们的性能和效果。

2、圆的生成算法中点画圆算法中点画圆算法的核心思想是通过判断中点的位置来确定圆上的像素点。

通过不断迭代计算中点的位置,逐步生成整个圆。

在实现过程中,需要注意边界条件的处理和误差的计算。

3、图形的变换平移变换旋转变换缩放变换平移变换是将图形在平面上沿着指定的方向移动一定的距离。

旋转变换是围绕一个中心点将图形旋转一定的角度。

缩放变换则是改变图形的大小。

通过矩阵运算来实现这些变换,可以方便地对图形进行各种操作。

4、图形的填充种子填充算法扫描线填充算法种子填充算法是从指定的种子点开始,将相邻的具有相同颜色或属性的像素点填充为指定的颜色。

扫描线填充算法则是通过扫描图形的每一行,确定需要填充的区间,然后进行填充。

在实验中,我们对不同形状的图形进行了填充,并比较了两种算法的适用情况。

四、实验步骤1、直线生成算法的实现定义直线的起点和终点坐标。

根据所选的算法(DDA 或Bresenham)计算直线上的像素点坐标。

计算机图形学实验报告

计算机图形学实验报告

计算机图形学基础实验报告院系:计算机科学学院班级:2012级4班姓名:彭晓学号:21209010434实验二直线生成算法的实现1.实验目的:理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL 实现直线光栅化的DDA算法。

2.实验内容:(1)根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果;(2)指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告;(3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告;(4)了解和使用OpenGL的生成直线的命令,来验证程序运行结果。

3.实验原理:示范代码原理参见教材直线光栅化一节中的DDA算法。

下面介绍下OpenGL画线的一些基础知识和glutReshapeFunc()函数。

(1)数学上的直线没有宽度,但OpenGL的直线则是有宽度的。

同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。

可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。

这里的线由一系列顶点顺次连结而成,有闭合和不闭合两种。

前面的实验已经知道如何绘“点”,那么OpenGL是如何知道拿这些顶点来做什么呢?是一个一个的画出来,还是连成线?或者构成一个多边形?或是做其它事情呢?为了解决这一问题,OpenGL要求:指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。

例如:glBegin(GL_POINTS);glVertex2f(0.0f, 0.0f);glVertex2f(0.5f, 0.0f);glEnd();则这两个点将分别被画出来。

如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点,OpenGL将会画出一条直线。

还可以指定更多的顶点,然后画出更复杂的图形。

计算机图形学实验报告

计算机图形学实验报告

实验结果与结论
• 在本次实验中,我们成功地实现了复杂场景的渲染,得到了具有较高真实感和视觉效果的图像。通过对比 实验前后的效果,我们发现光线追踪和着色器的运用对于提高渲染质量和效率具有重要作用。同时,我们 也发现场景图的构建和渲染脚本的编写对于实现复杂场景的渲染至关重要。此次实验不仅提高了我们对计 算机图形学原理的理解和实践能力,也为我们后续深入研究渲染引擎的实现提供了宝贵经验。
2. 通过属性设置和变换操作,实现了对图形的定 制和调整,加深了对图形属性的理解。
4. 实验的不足之处:由于时间限制,实验只涉及 了基本图形的绘制和变换,未涉及更复杂的图形 处理算法和技术,如光照、纹理映射等。需要在 后续实验中进一步学习和探索。
02
实验二:实现动画效果
实验目的
掌握动画的基本原 理和实现方法
04
实验四:渲染复杂场景
实验目的
掌握渲染复杂场景的基本流程和方法 理解光线追踪和着色器在渲染过程中的作用
熟悉渲染引擎的实现原理和技巧 提高解决实际问题的能力
实验步骤
• 准备场景文件 • 使用3D建模软件(如Blender)创建或导入场景模型,导出为常用的3D格式(如.obj或.fbx)。 • 导入场景文件 • 在渲染引擎(如Unity或Unreal Engine)中导入准备好的场景文件。 • 构建场景图 • 根据场景的层次结构和光照需求,构建场景图(Scene Graph)。 • 设置光照和材质属性 • 为场景中的物体设置光照和材质属性(如漫反射、镜面反射、透明度等)。 • 编写渲染脚本 • 使用编程语言(如C或JavaScript)编写渲染脚本,控制场景中物体的渲染顺序和逻辑。 • 运行渲染程序 • 运行渲染程序,观察渲染结果。根据效果调整光照、材质和渲染逻辑。 • 导出渲染图像 • 将渲染结果导出为图像文件(如JPEG或PNG),进行后续分析和展示。

计算机图形学实验报告2

计算机图形学实验报告2

计算机图形学实验报告2计算机图形学实验报告实验⼆、三维⽹格模型光顺⼀、实验⽬的与基本要求:(1)掌握Obj⽂件的读⼊;(2)利⽤给定的数据结构类,建⽴读⼊⽹格模型数据结构;(3)利⽤OpenGL类库,对三维模型进⾏绘制;(4)利⽤OpenGL类库,增加采⽤⿏标交互⽅式对三维模型进⾏旋转、放缩、平移等操作;(5)实现Laplacian⽅法的三维模型光顺操作,并观察三维模型光顺过程;⼆、实验设备(环境)及要求1. 操作系统:Windows XP 或Windows 72. 编程环境:Microsoft Visual Studio 2010,OpenGL 库函数3. 界⾯框架:Win32,MFC,QT选择其中⼀种三、实验内容与步骤实验分为以下⼏个步骤:(1)掌握Obj⽂件的读⼊顶点和⾯的个数;(2)建⽴数组存储点的坐标及⾯上的点数;(3)存储顶点的邻接⾯数,并记录每个顶点周围的邻接点(4)计算每个⾯的法向利⽤OpenGL类库,增加采⽤⿏标交互⽅式对三维模型进⾏旋转、放缩、平移等操作;(5)利⽤⾯法向及顶点坐标进⾏绘制⼏何体(6)实现⿏标对物体旋转、平移、缩放的算法(7)实现Laplacian⽅法的三维模型光顺操作,并观察三维模型光顺过程;四、实现过程说明及成果展⽰:(1)掌握Obj⽂件的读⼊顶点和⾯的个数;由于obj⽂件的存储形式是v x1 x2 x3;…f v1 v2 v3;…这种形式,所以在记录点和⾯的数量时,只需按⾏读取,然后再判断⾸字母是v/f即可实现代码如下:(2)建⽴数组存储点的坐标及⾯上的点数;数组的⼤⼩由点数和⾯数决定,点数组和⾯数组均由0开始记录,故后⾯再⽤⾯对应点的时候,由于⾯上点是从1开始记录,故需要减1然后使⽤,代码如下:(3)存储顶点的邻接⾯数,并记录每个顶点周围的邻接点记录点邻接⾯的是新建⼀个数组,在读⾯的时候,将该⾯的序号存⼊对应点的数组中,然后再在每个⾯上取⼀点,记录到点的邻接点数组中,在每个⾯上取得的点为向外右⼿⽅向的下⼀个点,实现代码如下:(4)计算每个⾯的法向计算⾯的法向⽅式为⾯上右⼿⽅向上的两向量的叉乘得到,即所⽤代码为:(8)利⽤⾯法向及顶点坐标进⾏绘制⼏何体⽤法向绘制的⽅式是先⽤glNormal3fv(v)指出⾯的法向;再⽤glVertex3f传⼊⾯上点的坐标;由于我将glNormal3fv(v)中写在算法向所以我直接对此直接调⽤即可,代码如下:(9)实现⿏标对物体旋转、平移、缩放的算法平移:利⽤Transform函数和键盘事件来改变参数,w,s,a,d分别控制绘制的kitty猫的上下左右的移动:实现代码如下:旋转:利⽤gllookat();函数设定了观察⾓度,并⽤⿏标事件改变参数,⽤实现观察视⾓的变化实现物体的旋转,代码如下:缩放:运⽤glScalef⽅法和键盘事件改变参数,实现物体的放⼤和缩⼩,代码如下:(10)实现Laplacian⽅法的三维模型光顺操作,并观察三维模型光顺过程;Laplacian⽅法的原理是利⽤⽬标点与其所有邻接点平均后的点的差向量,对⽬标点的坐标进⾏变换的过程,具体⽅法是:①建⽴每个点的邻接顶点数组,存储每个点的邻接点②对每个顶点的邻接点进⾏求平均,即将邻接点的坐标求和后除以邻接点个数,从⽽得到邻接平均点③得到优化向量优化向量= 邻接平均点-⽬标点④设定优化度参数λ,得到优化后的新坐标新坐标= ⽬标点+ λ*优化向量在程序中,对于第num个顶点,我设定的变量为邻接平均点v0优化向量l新坐标数组vNewArr具体代码如下:五、结果展⽰及说明计算⾯法向后直接绘制(未光顺):光顺进⾏⼀次后光顺多次后利⽤点绘制结果为旋转后缩放后平移后六、⼼得体会(1)计算⾯法向时法向量的⽅向没有运⽤右⼿⽅向,导致有的⾯法向向⾥,从⽽出现雪花(2)在运⽤Laplacian算法进⾏求邻接平均点时未初始化邻接平均点数组,导致平均点的累加从⽽出现越光顺越粗糙的现象(3)在obj⽂件中⾯对应顶点数和顶点数组的标号相差1.在运⽤的时候需减1,⾯从1开始记顶点,顶点数组从0开始记顶点七、实验代码#define GLUT_DISABLE_ATEXIT_HACK#include#include#include#include#include#include#include#includeusing namespace std;int v_num = 0; //记录点的数量int f_num = 0; //记录⾯的数量int vn_num = 0;//记录法向量的数量int vt_num = 0;GLfloat **vArr; //存放点的⼆维数组GLfloat **vNewArr;//存放点的⼆维数组int **fvArr; //存放⾯顶点的⼆维数组GLfloat **fnArr;//存放⾯法向量的⼆维数组int **ftArr;int **vfArr;//存放顶点临接的⾯数的数组int **nextVArr;//存放下⼀个临界顶点的数组GLfloat **vnArr;//存放点法向量的⼆维数组string s1, s2, s3, s4;GLfloat f2, f3, f4;int num1, num2, num3;typedef GLfloat point3[3];point3 x, y,l;//平⾯上的两个向量x,y和拉普拉斯向量lstatic GLfloat theta[] = { 0.0,0.0,0.0 };static GLint axis = 2;static GLdouble viewer[] = { 0.0, 0.0, 5.0 }; /* initial viewer location */ static GLdouble Tran[] = { 0.0,0.0,0.0 }; static GLdouble sca = 1.0;void getLineNum(string addrstr) //获取点和⾯的数量{ifstream infile(addrstr.c_str()); //打开指定⽂件if (!infile) {cout <<"open error!"<< endl;}string sline;//每⼀⾏int i = 0, j = 0;while (getline(infile, sline)) //从指定⽂件逐⾏读取{if (sline[0] == 'v'){v_num++;}if (sline[0] == 'f'){f_num++;}}}int readfile(string addrstr) //将⽂件内容读到数组中去{//getLineNum(addrstr);//new⼆维数组vArr = new GLfloat*[v_num];for (int i = 0; i < v_num; i++) {vArr[i] = new GLfloat[3];}vNewArr = new GLfloat*[v_num];for (int i = 0; i < v_num; i++) {vNewArr[i] = new GLfloat[3]; }vnArr = new GLfloat*[vn_num];for (int i = 0; i < vn_num; i++) {vnArr[i] = new GLfloat[3];}vfArr = new int*[v_num];for (int i = 0; i < v_num; i++) {vfArr[i] = new int[10];for (int j = 0; j < 10; j++) { vfArr[i][j] = -1;}}nextVArr = new int*[v_num];for (int i = 0; i < v_num; i++) {nextVArr[i] = new int[10];for (int j = 0; j < 10; j++) { nextVArr[i][j] = -1; }}fvArr = new int*[f_num];fnArr = new GLfloat*[f_num];ftArr = new int*[f_num];for (int i = 0; i < f_num; i++) {fvArr[i] = new int[3];fnArr[i] = new GLfloat[3];ftArr[i] = new int[10];}ifstream infile(addrstr.c_str()); if (!infile) { cout <<"open error!"<< endl;exit(1);}string sline;//每⼀⾏int ii = 0, jj = 0, kk = 0, mm = 0;while (getline(infile, sline)){if (sline[0] == 'v')//存储点{istringstream sin(sline);sin >> s1 >> f2 >> f3 >> f4;vArr[ii][0] = f2;vArr[ii][1] = f3;vArr[ii][2] = f4;ii++;}if (sline[0] == 'f') //存储⾯{istringstream in(sline);GLfloat a;in >> s1>>num1>>num2>>num3;//去掉f fvArr[kk][0] = num1;fvArr[kk][1] = num2;fvArr[kk][2] = num3;for (int i = 0; i < 10; i++) {if (vfArr[num1-1][i] == -1) {vfArr[num1-1][i] = kk;nextVArr[num1-1][i] = num2;break;}}for (int j = 0; j < 10; j++) {if (vfArr[num2-1][j] == -1) {vfArr[num2-1][j] = kk;nextVArr[num2-1][j] = num3;break;}}for (int i = 0; i < 10; i++) {if (vfArr[num3-1][i] == -1) {vfArr[num3-1][i] = kk;nextVArr[num3-1][i] = num1;break;}}kk++;}}return 0;}//计算⾯法向void nomal(point3p) {/*⽮量的归⼀化*///double sqrt();float d = 0.0;int i;for (i = 0; i < 3; i++)d += p[i] * p[i];d = sqrt(d);if (d > 0.0)for (i = 0; i < 3; i++)p[i] /= d;}void getFaceNormal(point3A, point3B, point3C) { x[0] = C[0] - A[0]; x[1] = C[1] - A[1];x[2] = C[2] - A[2];y[0] = A[0] - B[0];y[1] = A[1] - B[1];y[2] = A[2] - B[2];point3 v;v[0] = x[1] * y[2] - x[2] * y[1];v[1] = x[2] * y[0] - x[0] * y[2];v[2] = x[0] * y[1] - x[1] * y[0];nomal(v);glNormal3fv(v);}void Laplacian() {for (int num = 0; num < v_num; num++) {int m = 0;//求得点的邻接⾯数for (int i = 0; i < 10; i++) {if (nextVArr[num][i] != -1) {m++;}else {break;}}point3 v0;for (int i = 0; i < 3; i++) {v0[i] = 0;}for (int i = 0; i < m; i++) {v0[0] += vArr[nextVArr[num][i] - 1][0];v0[1] += vArr[nextVArr[num][i] - 1][1];v0[2] += vArr[nextVArr[num][i] - 1][2];}if (m != 0) {for (int i = 0; i < 3; i++)v0[i] /= m;}l[0] = v0[0] - vArr[num][0];l[1] = v0[1] - vArr[num][1];l[2] = v0[2] - vArr[num][2];vNewArr[num][0] = vArr[num][0] + l[0] * 0.3;vNewArr[num][1] = vArr[num][1] + l[1] * 0.3;vNewArr[num][2] = vArr[num][2] + l[2] * 0.3;}for (int i = 0; i < v_num; i++) {vArr[i][0] = vNewArr[i][0];vArr[i][1] = vNewArr[i][1];vArr[i][2] = vNewArr[i][2];}}void init(void){getLineNum("H:\\kitten_noisy.obj");readfile("H:\\kitten_noisy.obj");double viewer[] = { 0.0, 0.0, 8.0 }; /* initial viewer location */GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat mat_shininess[] = { 50.0 };//材料的镜⾯指数,其值越⼤越精细GLfloat light_position[] = { 1.0, 1.0f, 1.0, 0.0 };GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat lmodel_ambient[] = { 0.1, 0.1, 0.1, 1.0 };glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_SMOOTH);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);glLightfv(GL_LIGHT0, GL_POSITION, light_position);//光源位置glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);//漫反射光源glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);//镜⾯反射光源glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);//环境光源// glEnable(glMaterialf);glEnable(GL_LIGHTING);//启动光照glEnable(GL_LIGHT0);//启⽤0度光源glEnable(GL_DEPTH_TEST);//启动深度测试/*glShadeModel(GL_SMOOTH); // Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f); // ⿊⾊背景glClearDepth(1.0f);// 深度缓冲区设置glEnable(GL_DEPTH_TEST); // 允许深度测试glDepthFunc(GL_LEQUAL);// 定义深度测试类型glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculation */}。

图形学实验报告2分解

图形学实验报告2分解
#endif
/////////////////////////////////////////////////////////////////////////////
// CTransformView
IMPLEMENT_DYNCREATE(CTransformView, CView)
BEGIN_MESSAGE_MAP(CTransformView, CView)
}
/////////////////////////////////////////////////////////////////////////////
// CTransformView printing
BOOL CTransformView::OnPreparePrinting(CPrintInfo* pInfo)
//{{AFX_MSG_MAP(CTransformView)
ON_COMMAND(ID_MENU_TRANSFORM_TRANSLATE, OnMenuTransformTranslate)
ON_COMMAND(ID_MENU_TRANSFORM_SCALE, OnMenuTransformScale)
#include "TransformDoc.h"
#include "TransformView.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
{
// default preparation
return DoPreparePrinting(pInfo);

计算机图形学实验报告

计算机图形学实验报告

计算机图形学实验报告计算机图形学实验报告引言计算机图形学是研究计算机生成和处理图像的学科,它在现代科技和娱乐产业中扮演着重要的角色。

本实验报告旨在总结和分享我在计算机图形学实验中的经验和收获。

一、实验背景计算机图形学实验是计算机科学与技术专业的一门重要课程,通过实践操作和编程,学生可以深入了解图形学的基本原理和算法。

本次实验主要涉及三维图形的建模、渲染和动画。

二、实验内容1. 三维图形建模在实验中,我们学习了三维图形的表示和建模方法。

通过使用OpenGL或其他图形库,我们可以创建基本的几何体,如立方体、球体和圆柱体,并进行变换操作,如平移、旋转和缩放。

这些基本操作为后续的图形处理和渲染打下了基础。

2. 光照和着色光照和着色是图形学中重要的概念。

我们学习了不同的光照模型,如环境光、漫反射和镜面反射,并了解了如何在三维场景中模拟光照效果。

通过设置材质属性和光源参数,我们可以实现逼真的光照效果,使物体看起来更加真实。

3. 纹理映射纹理映射是一种将二维图像映射到三维物体表面的技术。

通过将纹理图像与物体的顶点坐标相对应,我们可以实现更加细致的渲染效果。

在实验中,我们学习了纹理坐标的计算和纹理映射的应用,使物体表面呈现出具有纹理和细节的效果。

4. 动画和交互动画和交互是计算机图形学的重要应用领域。

在实验中,我们学习了基本的动画原理和算法,如关键帧动画和插值技术。

通过设置动画参数和交互控制,我们可以实现物体的平滑移动和变形效果,提升用户体验。

三、实验过程在实验过程中,我们首先熟悉了图形库的使用和基本的编程技巧。

然后,我们按照实验指导书的要求,逐步完成了三维图形建模、光照和着色、纹理映射以及动画和交互等任务。

在实验过程中,我们遇到了许多挑战和问题,但通过不断的尝试和调试,最终成功实现了预期的效果。

四、实验结果通过实验,我们成功实现了三维图形的建模、渲染和动画效果。

我们可以通过键盘和鼠标控制物体的移动和变形,同时观察到真实的光照效果和纹理映射效果。

计算机图形学实验二报告

计算机图形学实验二报告

计算机科学与通信工程学院实验报告课程计算机图形学实验题目曲线拟合学生姓名学号专业班级指导教师日期成绩评定表曲线拟合1. 实验内容1. 绘制三次Bezier曲线(1)给定四个已知点P1—P4,以此作为控制顶点绘制一段三次Bezier曲线。

(2)给定四个已知点P1—P4,以此作为曲线上的点绘制一段三次Bezier曲线。

2. 绘制三次B样条曲线给定六个已知点P1—P6,以此作为控制顶点绘制一条三次B样条曲线。

2. 实验环境软硬件运行环境:Windows XP开发工具:visual studio 20083. 问题分析1. 绘制三次Bezier曲线Bezier曲线是用N+1个顶点(控制点)所构成的N根折线来定义一根N阶曲线。

本次实验中的三次Bezier曲线有4个顶点,设它们分别为P0,P1,P2,P3,那么对于曲线上各个点Pi(x,y)满足下列关系:P(t)=[(-P0+3P1-3P2+3P3)t3+(3P0-6P1+3P2)t2+(-3P0+3P2)t+(P0+4P1+P2)]/6X(t)=[(-X0+3X1-3X2+3X3)t3+(3X0-6X1+3X2)t2+(-3X0+3X2)t+(X0+4X1+X2)]/6Y(t)=[(-Y0+3Y1-3Y2+3Y3)t3+(3Y0-6Y1+3Y2)t2+(-3Y0+3Y2)t+(Y0+4Y1+Y2)]/6其中P0、P1、P2、P3为四个已知的点,坐标分别为(X0、Y0)、(X1、Y1)、(X1、Y2) 、(X3、Y3)。

所以只要确定控制点的坐标,该曲线可通过编程即可绘制出来。

2. 绘制三次B样条曲线三次B样条函数绘制曲线的光滑连接条件为:对于6个顶点,取P1、P2、P3、P4 4个顶点绘制在第一段三次样条曲线,再取P2、P3、P4、P5 这4个顶点绘制在第二段三次样条曲线,总计可绘制3段光滑连接的三次样条曲线。

4. 算法设计程序框架//DiamondView.hclass CDiamondView : public CView{ ……public://参数输入和提示对话框CDlgBezier dlgBezier;//Bezier曲线绘制中的参数输入对话框CDlgB dlgB;//B样条曲线绘制中的参数输入对话框//绘图函数,需要实现void DrawBezier1(POINT p[4]);//已知点作为控制点绘制Bezier曲线void DrawBezier2(POINT p[4]);//已知点作为曲线上的点绘制Bezier曲线void DrawBCurve(POINT p[6]);//绘制B样条曲线//DiamondView.cppvoid CDiamondView::OnMenuDiamond(){IsCutting = FALSE;if(dlgDiamond.DoModal()==IDOK)DrawDiamond(dlgDiamond.m_nVertex,dlgDiamond.m_nRadius,100);//调用绘制金刚石的函数} void CDiamondView::OnMenuBezier1(){IsCutting = FALSE;if(dlgBezier.DoModal() == IDOK)DrawBezier1(dlgBezier.m_nPoint);//调用已知点作为控制点绘制Bezier曲线的函数} //以已知的四个点为控制点绘制Bezier曲线//p:已知的四个控制点void CDiamondView::DrawBezier1(POINT p[4]){ }void CDiamondView::OnMenuBezier2(){IsCutting = FALSE;if(dlgBezier.DoModal() == IDOK)DrawBezier2(dlgBezier.m_nPoint);//调用已知点作为曲线上的点绘制Bezier曲线的函数}//以已知的四个点为Bezier曲线上的点来绘制Bezier曲线//p:已知的四个点void CDiamondView::DrawBezier2(POINT p[4]){ }void CDiamondView::OnMenuB(){IsCutting = FALSE;if(dlgB.DoModal() == IDOK)DrawBCurve(dlgB.m_nPoint);//调用绘制B样条曲线的函数} //以已知的六个点为控制点来绘制B样条曲线//p:已知的六个控制点void CDiamondView::DrawBCurve(POINT p[6]){ }5. 源代码//以已知的四个点为控制点绘制Bezier曲线//p:已知的四个控制点void CDiamondView::DrawBezier1(POINT p[4]){CDC *pDC = GetDC();CPen newPen,*oldPen;newPen.CreatePen(PS_SOLID,2,RGB(255,0,0));oldPen = pDC->SelectObject(&newPen);pDC->Polyline(p, 4);pDC->SelectObject(oldPen);newPen.DeleteObject();newPen.CreatePen(PS_SOLID,2,RGB(0,0,255));oldPen = pDC->SelectObject(&newPen);int x0=p[0].x;int y0=p[0].y;int x1=p[1].x;int y1=p[1].y;int x2=p[2].x;int y2=p[2].y;int x3=p[3].x;int y3=p[3].y;double x,y;int ax,ay,bx,by,cx,cy,dx,dy;int rate=1000;ax=-x0+3*x1-3*x2+x3;ay=-y0+3*y1-3*y2+y3;bx=3*x0-6*x1+3*x2;by=3*y0-6*y1+3*y2;cx=-3*x0+3*x1;cy=-3*y0+3*y1;dx=x0;dy=y0;pDC->MoveTo(x0,y0);for(double t=0;t<=1;t+=1.0/rate){x=ax*pow(t,3)+bx*pow(t,2)+cx*t+dx;y=ay*pow(t,3)+by*pow(t,2)+cy*t+dy;pDC->LineTo(Round(x),Round(y));Sleep(10);}pDC->SelectObject(oldPen);}//以已知的四个点为Bezier曲线上的点来绘制Bezier曲线//p:已知的四个点void CDiamondView::DrawBezier2(POINT p[4]){ InvalidateRgn(NULL);UpdateWindow();CDC *pDC = GetDC();CPen newPen,*oldPen;newPen.CreatePen(PS_DASH,1,RGB(0,0,0));oldPen=pDC->SelectObject(&newPen);CBrush newBrush,*oldBrush;newBrush.CreateSolidBrush(RGB(0,0,0));oldBrush=pDC->SelectObject(&newBrush);for(int i=0;i<=3;i++){pDC->Ellipse(p[i].x-3,p[i].y-3,p[i].x+3,p[i].y+3);} pDC->SelectObject(oldPen);pDC->SelectObject(oldBrush);Sleep(50);POINT q[4];q[0].x=p[0].x;q[0].y=p[0].y;q[1].x=(-5*p[0].x+18*p[1].x-9*p[2].x+2*p[3].x)/6;q[1].y=(-5*p[0].y+18*p[1].y-9*p[2].y+2*p[3].y)/6;q[2].x=(2*p[0].x-9*p[1].x+18*p[2].x-5*p[3].x)/6;q[2].y=(2*p[0].y-9*p[1].y+18*p[2].y-5*p[3].y)/6;q[3].x=p[3].x;q[3].y=p[3].y;DrawBezier1(q);}//以已知的六个点为控制点来绘制B样条曲线//p:已知的六个控制点void CDiamondView::DrawBCurve(POINT p[6]){InvalidateRgn(NULL);UpdateWindow();CDC *pDC = GetDC();CPen newPen,*oldPen;newPen.CreatePen(PS_SOLID,2,RGB(255,0,0)); oldPen = pDC->SelectObject(&newPen);int rate=1000;int ax,ay,bx,by,cx,cy,dx,dy;double x,y;pDC->Polyline(p, 6);pDC->SelectObject(oldPen);newPen.DeleteObject();newPen.CreatePen(PS_SOLID,3,RGB(0,0,255)); oldPen = pDC->SelectObject(&newPen);for(int i=0;i<3;i++){ax=-(p[i].x-3*p[i+1].x+3*p[i+2].x-p[i+3].x)/6;bx=(p[i].x-2*p[i+1].x+p[i+2].x)/2;cx=-(p[i].x-p[i+2].x)/2;dx=(p[i].x+4*p[i+1].x+p[i+2].x)/6;ay=-(p[i].y-3*p[i+1].y+3*p[i+2].y-p[i+3].y)/6;by=(p[i].y-2*p[i+1].y+p[i+2].y)/2;cy=-(p[i].y-p[i+2].y)/2;dy=(p[i].y+4*p[i+1].y+p[i+2].y)/6;for(double t=0;t<=1;t+=1.0/rate){x=ax*pow(t,3)+bx*pow(t,2)+cx*t+dx;y=ay*pow(t,3)+by*pow(t,2)+cy*t+dy;pDC->MoveTo(Round(x),Round(y));pDC->LineTo(Round(x),Round(y));Sleep(2); }}pDC->SelectObject(oldPen);}6. 程序运行结果图1 控制顶点一段三次Bezier曲线绘制图2 控制顶点一段三次Bezier曲线绘制图3 曲线上的点一段三次Bezier曲线的绘制—图4 控制顶点一条三次B样条曲线的绘制图5 控制顶点一条三次B样条曲线的绘制7. 总结通过这次实验,我对Bezier曲线有了一定的了解,同时也懂得了Bezier曲线和B样条曲线的参数表示法。

《计算机图形学》实验2实验报告

《计算机图形学》实验2实验报告

《计算机图形学》实验2实验报告《计算机图形学》实验2实验报告实验题目:多视图绘图程序实验内容:掌握多视图绘图的概念,掌握二维统计图的绘制方法。

调用实验1中自己编写的基本包,绘制自己所设计的统计图形(饼图、直方图以及折线)。

编写程序调用验证之。

基本概念:(详细叙述自己对实验内容的理解)多视图:就是将多个绘制好的图形按照一定的规则组成一个具有特定意义的图形,在同一个视图中显示出来,如下面绘制的几种统计图形(饼图、直方图以及折线)。

饼图:可以清楚的表示出各个部分所占的比例;直方图:可以清楚地的显示各部分的数量的多少;折线:可以清楚地反应各个部分的变化趋势。

算法设计:(详细叙述自己设计的多视图统计图以及程序的功能、算法及实现)public abstract void drawLine(int x1, int y1, int x2, int y2)使用当前颜色,在点(x1, y1) 和(x2, y2) 之间画线。

public abstract void drawOval(int x, int y, int width, int height) 画椭圆。

public abstract void fillOval(int x, int y, int width, int height)画实心椭圆。

public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)画x和y坐标定义的多边形。

public void drawRect(int x, int y, int width, int height)画矩形。

public void drawRect(int x, int y, int width, int height)画实心矩形。

public abstract void drawRoundRect(int x, int y, int width, intheight, int arcWidth, int arcHeight) 使用当前颜色画圆角矩形。

计算机图形学实验报告

计算机图形学实验报告

计算机图形学实验报告一、实验目的本次计算机图形学实验旨在深入了解和掌握计算机图形学的基本原理、算法和技术,通过实际操作和编程实现,提高对图形生成、处理和显示的能力,培养解决实际图形问题的思维和实践能力。

二、实验环境本次实验使用的编程语言为 Python,借助了相关的图形库如Pygame 或 matplotlib 等。

开发环境为 PyCharm 或 Jupyter Notebook。

三、实验内容(一)二维图形的绘制1、直线的绘制使用 DDA(Digital Differential Analyzer)算法或 Bresenham 算法实现直线的绘制。

通过给定直线的起点和终点坐标,在屏幕或图像上绘制出直线。

比较两种算法的效率和准确性,分析其优缺点。

2、圆的绘制采用中点画圆算法或 Bresenham 画圆算法绘制圆。

给定圆心坐标和半径,生成圆的图形。

研究不同半径大小对绘制效果和计算复杂度的影响。

(二)图形的填充1、多边形填充实现扫描线填充算法,对任意多边形进行填充。

处理多边形的顶点排序、交点计算和填充颜色的设置。

测试不同形状和复杂度的多边形填充效果。

2、图案填充设计自定义的填充图案,如纹理、条纹等,并将其应用于图形填充。

探索如何通过改变填充图案的参数来实现不同的视觉效果。

(三)图形的变换1、平移、旋转和缩放对已绘制的图形(如矩形、三角形等)进行平移、旋转和缩放操作。

通过矩阵运算实现这些变换。

观察变换前后图形的位置、形状和方向的变化。

2、组合变换将多个变换组合应用于图形,如先旋转再平移,或先缩放再旋转等。

分析组合变换的顺序对最终图形效果的影响。

(四)三维图形的表示与绘制1、三维坐标变换学习三维空间中的平移、旋转和缩放变换矩阵,并将其应用于三维点的坐标变换。

理解如何将三维坐标映射到二维屏幕上显示。

2、简单三维图形绘制尝试绘制简单的三维图形,如立方体、球体等,使用线框模型或表面模型。

探讨不同的绘制方法和视角对三维图形显示的影响。

计算机图形学实验报告

计算机图形学实验报告

《计算机图形学》实验报告姓名:郭子玉学号:班级:计算机12-2班实验地点:逸夫楼507实验时间:实验一1 实验目的和要求理解直线生成的原理;掌握典型直线生成算法;掌握步处理、分析实验数据的能力;编程实现DDA 算法、Bresenham 中点算法;对于给定起点和终点的直线,分别调用DDA 算法和Bresenham 中点算法进行批量绘制,并记录两种算法的绘制时间;利用excel 等数据分析软件,将试验结果编制成表格,并绘制折线图比较两种算法的性能。

2 实验环境和工具开发环境:Visual C++ 6.0实验平台:Experiment_Frame_One (自制平台)3 实验结果3.1 程序流程图(1)DDA 算法是 否否 是 是 (2)Mid_Bresenham 算法是 否否开始计算k ,b K<=1 x=x+1;y=y+k; 绘点 x<=X1y<=Y1 绘点 y=y+1;x=x+1/k;结束 开始计算dx,dydx>dy D=dx-2*dy x<X1; D=dy-2*dx y<Y1;是 是是 否 是 否3.2 程序代码 //-------------------------算法实现------------------------------// //绘制像素的函数DrawPixel(x, y); (1)DDA 算法void CExperiment_Frame_OneView::DDA(int X0, int Y0, int X1, int Y1){//----------请实现DDA 算法------------//float k, b;float d; k = float(Y1 - Y0)/float(X1 - X0);b = float(X1*Y0 - X0*Y1)/float(X1 - X0);if(fabs(k)<= 1){if(X0 > X1){int temp = X0; X0 = X1;绘点 D<0 y=y+1;D = D + 2*dx - 2*dy; x=x+1; D = D - 2*dy; x=x+1; 绘点D<0 D = D - 2*dx; y=y+1; x=x+1;D = D + 2*dy - 2*dx;y=y+1; 结束X1 = temp;}int x;float y;x = (int)X0;y = (float)Y0;while(x <= X1){DrawPixel(x, round(y));x ++;y = y + k;}}else{if(Y0 > Y1){int temp = Y0;Y0 = Y1;Y1 = temp;}float x;int y;x = (float)X0;y = (int)Y0;while(y <= Y1){DrawPixel(round(x), y);y ++;x = x + 1/k;}}return;}(2)Mid_Bresenham算法void CExperiment_Frame_OneView::Mid_Bresenham(int X0, int Y0, int X1, int Y1){//-------请实现Mid_Bresenham算法-------//int D;int dx, dy;int x, y;dx = X1 - X0;dy = Y1 - Y0;x = X0;y = Y0;if(dx > dy){while(x <= X1){DrawPixel(x, y);if(D < 0){y = y +1;D = D + 2*dx - 2*dy;}else{D = D - 2*dy;}x++;}}else{D = dy - 2*dx;while(y <= Y1){DrawPixel(x, y);if(D < 0){D = D + 2*dy - 2*dx;}else{D = D - 2*dx;}y++;}}return;}3.3运行结果(1)DDA算法(2)Mid_Bresenham算法3.4运行结果分析DDA算法直观,实现简单。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3.实验过程:
1)建立一个控制台应用程序,在RenderScene()函数中调用不同的系统函数分别绘制不同属性的点、线、折线、多边形、扇形等;
2)建立一个SDI程序,按照所给资料设置OpenGL图形绘制环境,并照敲老师所给实列,观看结果,查看关键代码区;
3)仿照所给列子,改写代码,绘制彩色的正方体;
2、掌握Bresenham或中点圆生成算法;
3、掌握Bresenham或中点椭圆生成算法;
三、
1、实现DDA、Bresenham直线生成算法;
2、实现Bresenham画圆法或中点画圆法;
3、实现Bresenham或中点法椭圆生成算法;
4、利用1、2、3实现的直线、圆、椭圆图形生成函数进行图形绘制;
中南大学信息科学与工程学院
实验报告
实 验 名 称
实 验 地 点科技楼四楼
实 验 日 期2014年6月
指 导 教 师
学 生 班 级
学 生 姓 名
学 生 学 号
提 交 日 期2014年6月
实验一
一、
二、
1、熟练使用实验主要开发平台VC6.0;
2、掌握如何在编译平台下编辑、编译、连接和运行一个简单的Windows图形应用程序;
if( ( point.x<rect.right ) && ( point.x>rect.left ) && ( point.y<rect.bottom ) && ( point.y>rect.top ) )
{
if( ( lButtonDownNotUp == TRUE )
{
regionRightBottomTemp = point;
float x = xa,y= ya;
if(abs(dx)>abs(dy))
Steps = abs(dx);
else
Steps = abs(dy);
xIncrement = dx/(float)Steps;
yIncrement = dy/(float)Steps;
pDC->SetPixel(ROUND(x),ROUND(y),RGB(255,0,0));
m_pDC->SetPixel(100,200,RGB(0,0,0));
m_pDC->TextOut(100,100);
2、画圆:
void CMyCG::LineDDA2(int xa, int ya, int xb, int yb, CDC *pDC)
{Hale Waihona Puke int dx = xb - xa;
int dy = yb - ya;
三.实验结果
基本图形显示正确
基本图形截图:
三棱柱截图:
实验四、二维图形变换程序设计
一.实验目的:
1)掌握图形变换实现原理,基本几何变换,复合变换等;
2)学习使用Visual C++开发菜单,对话框等交互界面的设计;
3)学习使用MFC单文档程序,实现二维图形的基本几何变换。
二.实验内容:
使用Visual C++建立一个单文档程序,采用实验二中定义的基本图形类。在程序中增加图形变换菜单(各基本变换对应菜单项),各图形变换的参数通过对话框提供(设计提供变换参数的对话框,如平移,旋转,比例等),实现二维图形的变换。(提示:在各个图形类中增加相应的成员函数实现平移;菜单选择变换弹出对应变换的参数对话框,对话框中提供参数后取出参数传递给图形对象,通过调用图形变换成员函数实现图形对象的变换)。要求实现直线段、圆、多边形等基本图形的几何变换。
三.实验过程:
(1).根据实验要求,新建菜单,增加二维图形变换子菜单,然后在菜单上添加平移,比例,对称,旋转以及错切选项。
(2).对菜单中的每一项方法构造响应函数,并给几个需要弹出对话框的选项添加对话框响应函数。
(3).在弹出的对话框输入参数,获取输入的参数,调用相应的变换函数,实现图形的变换。
四.实验结果:
int Steps, k;
float xIncrement,yIncrement;
float x = xa,y= ya;
if(abs(dx)>abs(dy))
Steps = abs(dx);
else
Steps = abs(dy);
xIncrement = dx/(float)Steps;
yIncrement = dy/(float)Steps;
3、掌握Window图形编程的基本方法;
4、学会使用基本绘图函数和Window GDI对象;
三、
创建基于MFC的Single Document应用程序(Win32应用程序也可,同学们可根据自己的喜好决定),程序可以实现以下要求:
1、用户可以通过菜单选择绘图颜色;
2、用户点击菜单选择绘图形状时,能在视图中绘制指定形状的图形;
void Scale(double,double);//比例变换矩阵
void Scale(double,double,CP2);//相对于任意点的比例变换矩阵
3、所有图形的绘制算法都必须封装在CMyGL类中,如下图。
4、在View类中实例化一个CMyGL类的对象,比如m_gl,进行绘图操作。如下图所示:
5、用户通过点击“图形绘制”中不同的菜单项,在指定位置进行绘图。
五、
六、
1、画直线:
void CDraw::DDALine(CDC* pDC, int x1, int y1, int x2, int y2, COLORREF color)
pDC->SetPixel(-x+x0,-y+y0,color);
if(p>=0)
{
p+=4*aa*(1-y)+bb*(4*x+6);
y--;
}
else
{
p+= bb*(4*x+6);
}
x++;
}
x=a;y=0; p=2*aa+bb*(1-2*a);
while (bb*x>aa*y)
{
pDC->SetPixel(x+x0,y+y0,color);
结果正确。
平移xy(100, 0)
五、实验主要代码
class CTransform//二维几何变换
{
public:
CTransform();
virtual ~CTransform();
void SetMat(CP2 *,int);
void Identity();
void Translate(double,double);//平移变换矩阵
{
int x,y,p;
int aa=a*a,bb=b*b;
x=0;y=b; p=2*bb+aa*(1-2*b);
while (bb*x<=aa*y)
{
pDC->SetPixel(x+x0,y+y0,color);
pDC->SetPixel(-x+x0,y+y0,color);
pDC->SetPixel(x+x0,-y+y0,color);
{
regionLeftTopTemp = point;
}
CDialog::OnLButtonDown(nFlags, point);
}
void CRectangleDlg::OnMouseMove(UINT nFlags, CPoint point)
{
RECT rect;
m_showRectangle. GetClientRect( &rect );
}
y++;
}
}
实验三、OpenGL图形程序设计基础
一.实验目的
1)了解OpenGL图形库的功能和结构;
2)学习使用Visual C++开发基于控制台的图形程序;
3)学习使用Visual C++开发基于单文档(GUI界面)的图形程序。
4)学习使用OpenGL生成基本图形;
5)学习使用OpenGL实现图形变换;
x+=dx;
y+=dy;
}
}
2、画圆:
void CMyCG::LineDDA2(int xa, int ya, int xb, int yb, CDC *pDC)
{
int dx = xb - xa;
int dy = yb - ya;
int Steps, k;
float xIncrement,yIncrement;
pDC->SetPixel(ROUND(x),ROUND(y),RGB(0,0,0));
for(k=0;k<Steps;k++)
{
x +=xIncrement;
y +=yIncrement;
sleep(10);
pDC->SetPixel(ROUND(x),ROUND(y),RGB(0,0,0));
}
{
double dx,dy,e,x,y;
dx = x2 -x1;
dy = y2- y1;
e = (fabs(dx) > fabs(dy)) ? fabs(dx):fabs(dy);
dx/=e;
dy/=e;
x = x1;
y = y1;
for (int i=1;i<=e;i++)
{
pDC->SetPixel((int)(x+0.5),(int)(y+0.5),color);
相关文档
最新文档