《计算机图形学》实验5实验报告实验题目:多边形裁剪与填充实验内容:1 阅读理解提供的参考资料。
2编写并调通一个多边形裁剪的java程序。
3编写并调通一个多边形填充的java程序。
参考资料:1 fillpolygon.java 2 clipsc2.java2变换与剪裁.ppt3多边形的填充.ppt 基本概念:(详细叙述自己对实验内容的理解)多边形的裁剪:选择显示的内容--图形在窗口内的部分被显示出来,窗口外的部分被裁剪掉。
图形中每个基本元素都要经过裁剪,因此裁剪直接影响整个图形系统的效率。
多边形的填充:多边形填充就是把多边形的顶点表示转换为点阵表示,即从多边形的给定边界出发,求出位于其内部的各个像素,并将帧缓冲器内的各个对应元素设置相应的灰度或颜色。
实际上,也就是多边形内的区域的着色过程。
算法设计:(详细叙述自己设计的的算法)多边形的裁剪:1、算法的的基本思想:对于每条线段p1p2分为三种情况处理。
(1)若p1p2完全在窗口内,则显示该线段p1p2简称“取”之。
(2)若p1p2明显在窗口外,则丢弃该线段,简称“弃”之。
(3)若线段既不满足“取”的条件,也不满足“弃”的条件,则在交点处把线段分为两段。
其中一段完全在窗口外,可弃之。
然后对另一段重复上述处理。
2、sutherland–cohen算法分成两部分:第一步是判定:1) 完全在窗口内的直线段,称为完全可见的线段;2) 完全在窗口外的线段,称为完全不可见线段。
第二步处理不能断定为完全可见或完全不可见的线段。
这时需要计算出直线段和窗口边界的一个交点,这个交点把直线分成两段,其中一条为完全不可见的线段,被抛弃。
对余下部分再作第一步的判断,重复上述过程,直到直线段余下的部分可用第一步的判断得出肯定的结论为止。
多边形的填充:1、多边形填充的扫描线算法:1:计算扫描线与多边形各边的交点,设交点个数为n;2:把所有的交点按x值递增的顺序进行排列;3:将排序后的第1个与第2个交点,第3个与第4个交点,??第n-1个与第n个交点配对,每对交点就代表扫描;线与多边形的一个相交区间;4:把相交区间内的像素置成多边形的颜色,相交区间外的像素置成背景色。
2、边缘填充算法:对多边形p的每一非水平边上的各像素做向右求反运算即可3、边界标志算法:1:以值为boundary-color 的特殊颜色勾画多边形p的边界。
设多边形顶点为pi= (xi,yi),0≤i≤n, xi, yi均为整数;置pn+1=p0。
每一条扫描线上着上这种特殊颜色的点的个数必定是偶数(包括零)。
2:设interior_point 是一布尔变量。
对每一条扫描线从左到右进行搜索,如果当前是像素位于多边形p内,则interior_point=true,需要填上值为polygon_color的颜色;否则该像素在多边形p外,需要填上值为background_color的颜色。
4、扫描线种子填充算法:1:(初始化)将算法设置的堆栈置为空。
将给定的种子点(x, y)压入堆栈 2:(出栈)如果堆栈为空,算法结束;否则取栈顶元素(x, y)作为种子点3:(区段填充)从种子点(x, y)开始,沿纵坐标为y的当前扫描线向左右两个方向逐个像素用新的颜色值进行填充,直到边界为止即象素颜色等于边界色。
设区间两边界的横坐标分别为xleft 和xright。
4:在与当前扫描线相邻的上下两条扫描线上,以区间[xleft, xright]为搜索范围,求出需要填充的各小区间,把各小区间中最右边的点并作为种子点压入堆栈,转到步骤2。
代码:(给出编写的两个java程序和注解)package last; //applet程序演示//sutherland–cohen裁剪算法import java.awt.*;import java.applet.applet; public class clipsc2 extends applet { int xl=100,xr=200,yb=100,yt=200; public void paint(graphics g){ setbackground(color.gray); graphics2d g2=(graphics2d)g;g2.setpaint(color.green); //画一绿色的矩形g2.drawline((int)xl,(int)yb,(int)xl,(int)yt);g2.drawline((int)xl,(int)yb,(int)xr,(int)yb);g2.drawline((int)xl,(int)yt,(int)xr,(int)yt);g2.drawline((int)xr,(int)yb,(int)xr,(int)yt); g2.setpaint(color.blue); //蓝色的长斜线//g2.drawline(50,50,280,280); g2.drawline(50,150,250,150);g2.setpaint(color.red); //调用裁减算法,矩形内的部分改画红线//sutherland_cohen(g2,50,50,280,280); sutherland_cohen(g2,50,150,250,150); } //窗口的四条边把整个平面分成九个区域,每一个区域采用四位编码表示: //对要被裁剪的线段的两个端点,如果其所在的区域的编码均是 0000,则这条线段完全可见; publicint code(float x,float y) { } int c=0; if(x<xl)c=c|1; elseif(x>xr)c=c|2; if(y<yb)c=c|4; else if(y>yt)c=c|8; return c; //二进制分别为 0 1 10 100 1000 //如果两个编码的逻辑与不为0000,则这条线段完全不可见。
其它则部分可见//sutherland_cohen裁减算法public void sutherland_cohen(graphics g,float x0,float y0,float x2,float y2) { int c1,c2,c; float x,y,wx,wy; boolean accept=false,done=false;c1=code(x0,y0); c2=code(x2,y2); if ((c1|c2)==0)//两个编码都为0,表明在窗口内 { accept=true; done=true; }else if((c1&c2)!=0)done=true;//两个编码的某一位为1,则必然在外侧显然在窗口外else { c=c1; if(c==0)c=c2; wx=x2-x0;if ((c&8)==8) //求交点{ x=x0+wx*(yt-y0)/wy;y=yt; } else if ((c&4)==4) { x=x0+wx*(yb-y0)/wy;y=yb; } do { wy=y2-y0; } { y=y0+wy*(xl-x0)/wx; x=xl; }else//即(c&2)==2{ y=y0+wy*(xr-x0)/wx; x=xr; } if (c==c1) //表明c1!=0,起始点不在窗口内,将交点作为新的起点重复判断步骤; { x0=x;y0=y; c1=code(x0,y0); }else //终点不在窗口内,交点作为新的终点{ x2=x; y2=y;c2=code(x2,y2); } }//else } while (done==false);if(accept)g.drawline((int)x0,(int)y0,(int)x2,(int)y2); } package last; //fillpolygon.java//多边形的填充//交互式,用鼠标点击形成多边形import java.util.*;import java.awt.*; //利用java向量类 //利用awt绘图//利用java图像包//利用鼠标事件响应 import java.awt.image.*; import java.awt.event.*; import java.applet.applet; //applet程序import pakage1_4.mycanvas;//引入自制包中的类mycanvas //***定义多边形边结点类activeedgelistentryclass activeedgelistentry { } //***定义多边形单链表类activeedgelist class activeedgelist { activeedgelistentry header=null; //链表头指针 activeedgelistentry tailer=null;//链表尾指针 //构造方法 public activeedgelist(activeedgelistentry element) { } //把新结点插入有序排列的多边形单链表 public void insert(activeedgelistentry element){ activeedgelistentry sentinel; //当前结点指针 //新结点异常或者链表空//出错,抛出异常 if(element==null || this.header==null) header=tailer=element; //指向第一个边结点 int name; //索引 int topx; int topy; int botx; int boty; //存放y坐标最大点的x坐标 //存放y坐标最大点的y坐标 //存放y坐标最小点的x坐标 //存放y坐标最小点的y坐标 //定义为-(botx-topx)/(boty-topy) double delta; double x; //当前行的x坐标 boolean ishorizontal; //水平边标志 activeedgelistentry next; //单链表的指针域//结束多边形边结点类throw new nullpointerexception();sentinel=this.header; //当前指针指向表头结点 int xt=element.topx; //新结点的topxint xtold=sentinel.topx; double olddelta=sentinel.delta; doublenewdelta=element.delta; /* 排序第一关键字结点的topx,第二关键字结点的delta *//* 两个关键字由小到大*/ //当前结点的delta篇二:实验5报告格式上海电力学院j2me实验报告(2013/2014 学年第1学期)课程编号 252200801 课程名称 j2me 院(系)计算机科学与技术学院专业班级学号姓名实验名称实验五 j2me数据库编程设计任课老师张挺实验五 j2me数据库编程设计1【实验目的】掌握数据存储方法。