计算机图形学实验1报告.doc_第1页
计算机图形学实验1报告.doc_第2页
计算机图形学实验1报告.doc_第3页
计算机图形学实验1报告.doc_第4页
计算机图形学实验1报告.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

设计和实现一个图形函数库一、实验要求设计和实现一个图形函数库,具有绘制直线段、任意圆弧、椭圆弧、多边形区域的阴影填充和颜色填充等功能。(仅调用画点函数)Windows API: setpixel(hdc,x,y,color)二、实验平台 编程环境:Visual Studio 2008 编程语言:C# 操作系统:Windows 7三、实验目的 在理解画直线段,圆弧,椭圆,多边形的画法,以及阴影填充和颜色填充算法的基础上,编程实现出一个简单的画图工具,加深对个算法的理解。四、算法基本原理1、画直线段(1)算法思想本程序采用Bresenham直线算法,基本思想为:(以斜率在01之间的直线段为例)这种情况下, 选择X方向为计长方向,即增量dx=1。如图3.2所示,设Pi (xi,yi)是已选定的离直线最近的像素, 现在要决定Pi+1是T还是S。显然, 若d=0.5, 则应选T。(m= y/x)令e=d-0.5(初值为-0.5), 即有:e =0时, 选Pi+1(xi+1, yi+1), 更新e=e+m-1;(2)算法流程(3)实现效果2、画圆弧(1)算法思想本程序采用Bresenham圆弧算法,基本思想为:与Bresenham直线生成算法一样, 其基本方法是从一个起点出发, 利用判别式选择下一个显示点。判别式的值通过简单计算获得, 其符号用作判断。此算法在每一步都选择一个离开理想圆周最近的点Pi(xi, yi), 使其误差项|D(Pi)|=|xi2+yi2-R2|在每一步都是极小值。设Pi-1(xi-1, yi-1)已被选定为最靠近圆弧的点,下一步x=x i-1+1时, 要决定T还是S更接近理想的圆弧,令D(S)=(xi-1+1)2 + (yi-1)2 -R2D(T)=(xi-1+1)2 + (yi-1-1)2-R2显然, |D(S)|=|D(T)|时, 应该取T点; 反之则取S点(2)算法流程(3)实现效果3、画椭圆弧(1)算法思想椭圆生成算法与圆形生成算法类似,都是先生成八分之一圆弧,然后根据对称原则生成图形,所不同的是椭圆有长轴和短轴之分,故需要提前求出45方向椭圆焦点的坐标。然后再根据公式进行画点。(2)程序流程(3)实现效果4、画多边形(1)算法思想多边形画法是基于直线画法实现的,第一次点击确定第一个点,第二次点击画出第一条直线,之后每次点击都已上一次点击为起点这次点击为终点画线,直到结束。(2)程序流程(3)实现效果5、颜色填充(1)算法思想本程序可以由用户选择填充颜色,可对闭合图形内部进行填充,采用漫水法,进行递归画点。漫水法基本原理:Procedure flood-fill-4(x,y,old-color,new-color:integer)beginif getpixel(framebuffer,x,y)=old-colorthen beginsetpixel(framebuffer,x,y,newcolor);flood-fill-4(x,y+1,old-color,new-color);flood-fill-4(x,y-1,old-color,new-color);flood-fill-4(x-1,y,old-color,new-color);flood-fill-4(x-1,y-1,old-color,new-color);endend(2)实现效果6、阴影填充(1)算法思想本程序使用的填充线的斜率为-1,在任意闭合图形内点击,程序先填充点击点左下部分,后填充点击点右上部分。(2)实现效果五、实验总结通过本次实验,我对基本图形的画法有了一定的了解,将课上的算法真正实践出来。并对算法进行了一定的修改和补充。在实验的同时,熟悉了C#的编程思想,通过上网查资料和与同学讨论,使我的编程水平有了一定的提高。六、源程序清单using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace 简单画图板 public partial class Form1 : Form private Bitmap bitmap; private Pen pen = new Pen(Color.Black); private int choice = 0; private SolidBrush sBrush; private int x1, y1, x2, y2; private int count = 0; public Form1() InitializeComponent(); private void Form1_Load(object sender, EventArgs e) bitmap = new Bitmap(panel1.Width, panel1.Height);/新建位图 private void radioButton1_CheckedChanged(object sender, EventArgs e) choice = 0; count = 0; private void radioButton2_CheckedChanged(object sender, EventArgs e) choice = 1; private void radioButton3_CheckedChanged(object sender, EventArgs e) choice = 2; private void radioButton4_CheckedChanged(object sender, EventArgs e) choice = 3; private void radioButton5_CheckedChanged(object sender, EventArgs e) choice = 4; private void radioButton6_CheckedChanged(object sender, EventArgs e) choice = 5; private void pictureBox1_Click(object sender, EventArgs e) ColorDialog colorDialog = new ColorDialog(); colorDialog.AllowFullOpen = true; colorDialog.FullOpen = false; if (colorDialog.ShowDialog() = DialogResult.OK) pen = new Pen(colorDialog.Color); sBrush = new SolidBrush(colorDialog.Color); pictureBox1.BackColor = colorDialog.Color; private void panel1_MouseDown(object sender, MouseEventArgs e) pen.Color = pictureBox1.BackColor; switch (choice) case 0:/画直线 count+; if (count % 2 != 0) x1 = e.X; y1 = e.Y; else x2 = e.X; y2 = e.Y; line(x1, y1, x2, y2); break; case 1:/画圆弧 x1 = e.X; y1 = e.Y; circular(x1, y1, Convert.ToInt32(textBox1.Text); break; case 2:/画椭圆 x1 = e.X; y1 = e.Y; ellipse(x1, y1, Convert.ToInt32(textBox2.Text), Convert.ToInt32(textBox3.Text); break; case 3:/画多边形 count+; if (count = 1) x2 = e.X; y2 = e.Y; else x1 = x2; y1 = y2; x2 = e.X; y2 = e.Y; line(x1, y1, x2, y2);/直接调用画直线的算法 break; case 4:/颜色填充 x1 = e.X; y1 = e.Y; Color old_color = getpixel(x1, y1); Color new_color = pictureBox1.BackColor; flood_fill_4(x1, y1, old_color, new_color,0); break; case 5:/阴影填充 x1 = e.X; y1 = e.Y; old_color = getpixel(x1, y1); new_color = pictureBox1.BackColor; shade(x1, y1, old_color, new_color); break; private void panel1_MouseLeave(object sender, EventArgs e) count = 0;/鼠标离开画图区,count清零 private void clr_img_Click(object sender, EventArgs e)/清除图像 panel1.Refresh();/刷新panel bitmap = new Bitmap(panel1.Width, panel1.Height);/重绘bitmap /*重绘位图*/ private void draw() Graphics g = panel1.CreateGraphics(); g.DrawImage(bitmap, 0, 0); /*设置像素颜色*/ private void drawpixel(int x, int y, Pen pen) if (x 0 & x 0 & y 0 & x 0 & y = dy) e = -dx; x = x1; y = y1; for (int i = 0; i dx; i+) drawpixel(x, y, pen); if (x1 = 0) if (y1 = y2) y+; else y-; e = e - 2 * dx; else e = -dy; x = x1; y = y1; for (int i = 0; i dy; i+) drawpixel(x, y, pen); if (y1 = 0) if (x1 = x2) x+; else x-; e = e - 2 * dy; draw(); /*画圆弧Bresenham算法*/ public void circular(int x1, int y1, int r) int x, y, d; x = 0; y = r; d = 3 - 2 * r; while (x y) /*画对称点*/ drawpixel(x1 + x, y1 + y, pen); drawpixel(x1 + y, y1 + x, pen); drawpixel(x1 + x, y1 - y, pen); drawpixel(x1 + y, y1 - x, pen); drawpixel(x1 - x, y1 + y, pen); drawpixel(x1 - y, y1 + x, pen); drawpixel(x1 - x, y1 - y, pen); drawpixel(x1 - y, y1 - x, pen); if (d 0) d = d + 4 * x + 6; else d = d + 4 * (x - y) + 10; y-; x+; if (x = y) /*画对称点*/ drawpixel(x1 + x, y1 + y, pen); drawpixel(x1 + y, y1 + x, pen); drawpixel(x1 + x, y1 - y, pen); drawpixel(x1 + y, y1 - x, pen); drawpixel(x1 - x, y1 + y, pen); drawpixel(x1 - y, y1 + x, pen); drawpixel(x1 - x, y1 - y, pen); drawpixel(x1 - y, y1 - x, pen); draw(); /*画椭圆*/ public void ellipse(int x1, int y1, int a, int b) /* 椭圆中心在(x1,y1),长半轴为a,短半轴为b */ int x, y, d, P_x, P_y, S_a, S_b; S_a = a * a; S_b = b * b; P_x = (int)(0.5 + (float)S_a / Math.Sqrt(float)(S_a + S_b); P_y = (int)(0.5 + (float)S_b / Math.Sqrt(float)(S_a + S_b); /* 生成第一象限内的上半部分椭圆弧 */ x = 0; y = b; d = 4 * (S_b - b * S_a) + S_a; /*画对称点*/ drawpixel(x1 + x, y1 + y, pen); drawpixel(x1 + x, y1 - y, pen); drawpixel(x1 - x, y1 + y, pen); drawpixel(x1 - x, y1 - y, pen); while (x = P_x) if (d = 0) d += 4 * S_b * (2 * x + 3); else d += 4 * S_b * (2 * x + 3) - 8 * S_a * (y - 1); y-; x+; /*画对称点*/ drawpixel(x1 + x, y1 + y, pen); drawpixel(x1 + x, y1 - y, pen); drawpixel(x1 - x, y1 + y, pen); drawpixel(x1 - x, y1 - y, pen); /* 生成第一象限内的上半部分椭圆弧 */ x = a; y = 0; d = 4 * (S_a - a * S_b) + S_b; /*画对称点*/ drawpixel(x1 + x, y1 + y, pen); drawpixel(x1 + x, y1 - y, pen); drawpixel(x1 - x, y1 + y, pen); drawpixel(x1 - x, y1 - y, pen); while (y P_y) if (d = 0) d += 4 * S_a * (2 * y + 3); else d += 4 * S_a * (2 * y + 3) - 8 * S_b * (x - 1); x-; y+; /*画对称点*/ drawpixel(x1 + x, y1 + y, pen); drawpixel(x1 + x, y1 - y, pen); drawpixel(x1 - x, y1 + y, pen); drawpixel(x1 - x, y1 - y, pen); draw(); /*颜色填充*/ private void flood_fill_4(int x, int y, Color old_color, Color new_color,int depth) if (getpixel(x, y) = old_color) drawpixel(x, y, pen); flood_fill_4(x, y + 1, old_color, new_color,depth+1); flood_fill_4(x, y - 1, old_color, new_color,depth+1); flood_fill_4(x + 1, y, old_color, new_color,depth+1); flood_fill_4(x - 1, y, old_color, new_color,depth+1); if(depth = 0) draw(); /*阴影填充*/ private void shade(int x, int y,Color old_color,Color new_color) int x1, x2, y1, y2,t_x,t_y; t_x = x; t_y = y; /*填充点击点左下部*/ while (getpixel(x + 1, y - 1) = old_color & getpixel(x, y) = old_color & getpixel(x, y - 1) = old_color & getpixel(x+1, y) = old_color) x1 = x; y1 = y; x2 = x; y2 = y; while (getpix

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论