if(d<0)d=d+4*x*SPACE+6*SPACE;
else{
d=d+4*(x-y)*SPACE+10*SPACE;
y=y-SPACE;
}
x=x+SPACE;}
实
验
原
理
步
骤
(
算
法
流
程
)
坐标点的转换方法:
publicMyCoordinateaxisChanges(intx,inty,intd);
核心代码:
mycoor.setPhysicx(x);
mycoor.setPhysicy(y);
mycoor.setX((x-cir_point_x)/SPACE);
mycoor.setY((cir_point_y-y)/SPACE);
存放了两个坐标点,分别是在面板中的真实坐标和在界面中呈现出的坐标点;
4.添加圆的其它点:
publicvoidaddOtherPoint(intn)
其中n是已经在画的1/8的圆的像素个数;
核心代码如下:
获取半径向量:
x=coor.get(i).getX()-CIRPOINT.x;
y=coor.get(i).getY()-CIRPOINT.y;
logicx=coor.get(i).getPhysicx()-PHSICCIRPOINT.x;
logicy=coor.get(i).getPhysicy()-PHSICCIRPOINT.y;
获取其它各点:
(x+CIRPOINT.x,-y+CIRPOINT.y);
(-x+CIRPOINT.x,-y+CIRPOINT.y);
(-x+CIRPOINT.x,y+CIRPOINT.y);
(y+CIRPOINT.x,x+CIRPOINT.y);
(y+CIRPOINT.x,-x+CIRPOINT.y);
(-y+CIRPOINT.x,x+CIRPOINT.y);
(-y+CIRPOINT.x,-x+CIRPOINT.y);
5.用所存坐标画圆
while(it.hasNext()){
cox=point.getX();//已经是逻辑的坐标点,以space为单位
coy=point.getY();
logicx=point.getPhysicx();
logicy=point.getPhysicy();
g.fillOval(logicx-(int)(SPACE/4)+9,logicy-
(int)(SPACE/4)+32,(int)SPACE/2,(int)SPACE/2);
g.setColor(Color.red);
g.fillRect(logicx+9,logicy+32,SPACE,SPACE);
}
其中程序中的+9+32操作时对边框的修正。
(写不完时,可另加附页。
)
实
验
结
果
及
分
析
1.在输入模式下的弧线显示结果:
结果分析:
1.在输入模式下,对坐标点进行了位置的处理,坐标的原点是左下角,x轴方向是向右的,y轴的方向是向上的,但是这只是在显示上的表现,在画圆弧的过程中还是用的坐标的真实坐标;
2.在只做点击的情况下,设置坐标的半径为5;
3.在显示的过程中由于是在面板上画图,实际坐标的取值还要考虑边框所占用的空间,所以在代码实现时要进行一定的位置修正!
(在代码中有体现。
)
心
得
体
会
在这次实验过程中,对坐标的点进行了相应的改变,设置了坐下角为原点,而且成功的把坐标点物理点和逻辑点分开了,这是比较好的地方吧。
在画圆用的bresenham算法,继续用整数的加减来代替真正的距离来找坐标点,提高了算法的效率和减少了算法的复杂度!
感受到了这个算法的优越性!
实验分项3
线段裁剪
实
验
目
的
用Cohen-SutherLand算法进行线段裁剪
实
验
要
求
1.将象素网格表现出来,建立网格坐标系
2.用橡皮筋的形式输入剪裁线段
3.对于线段裁剪,线段被窗口的四条边裁剪的过程要显示出来
实
验
原
理
步
骤
(
算
法
流
程
)
1.直线的生成:
mouseClicked方法中获取点击点的位置,当点击“确定”的时候把两点取出,并画直线;
g.setColor(Color.BLUE);
g.drawLine(pointX[0],pointY[0],pointX[1],pointY[1]);
2.裁剪框的生成:
使用鼠标的拖拽实现生成裁剪框,代码显示如下:
publicvoidmouseDragged(MouseEvente){
//剪切框的终点坐标
xR=e.getX();
yB=e.getY();
Graphicsg=getGraphics();
paintComponent(g);
g.setColor(Color.black);
g.drawRect(xL,yT,xR-xL,yB-yT);
}
其中起点的坐标xL,yT在mousePressed方法中生成!
3.由于直线的起点,终点都有记录,所以在重新生成裁剪线之前,首先对面板进行清理,用g.clearRect(00,00,380,600)实现
4.利用梁友栋-Barsky算法裁剪直线:
直线的裁剪是在clipline方法中实现的,参数分别是直线的起点和终点坐标;
clipLine(pointX[0],pointY[0],pointX[1],pointY[1]);
(写不完时,可另加附页。
)
实
验
原
理
步
骤
(
算
法
流
程
)
if(clipTest(-dx,x1-xL)){
intw=x1-xL;
if(clipTest(dx,xR-x1)){
inth=xR-x1;
if(clipTest(-dy,y1-yB)){
intl=y1-yB;
if(clipTest(dy,yT-y1)){
x2=(int)(x1+u2*dx);
y2=(int)(y1+u2*dy);
x1=(int)(x1+u1*dx);
y1=(int)(y1+u1*dy);
g.setColor(Color.red);
g.drawLine(x1,y1,x2,y2);
}
其中用到clipTest方法在此方法中主要是判断起点组,终点组以及找到ts和te,这些工作的实现过程是:
publicbooleanclipTest(doubler,floats){
doublet;
if(r<0)
{
t=s/r;
if(t>1)
returnfalse;
elseif(t>0)
u1=t;/*u1取"进入"点的最大参数值*/
elseif(r>0)
{
t=s/r;
if(t<0)
returnfalse;
elseif(t<1)
u2=t;/*u2取"离开"点的最小参数值*/
}
elseif(s<0)/*p=0,且q<0。
平行于边界,而且在界外的线*/
returnfalse;
returntrue;
}
(写不完时,可另加附页。
)
实
验
结
果
及
分
析
1:
在已有的框内化画直线然后剪切的效果:
结果分析:
首先直线是用蓝线生成的,裁剪操作中,首先是把直线进行清除,然后找到裁剪后的起点和终点并用红线画出,边框也是重画的,输入框中显示了直线的裁剪过程;在下面的输出框中显示了直线裁剪的过程!
心
得
体
会
首先在这次实验过程中用到了梁友栋-Barsky算法,这个方法的实质是用到了向量的点乘运算,所以只用了很少的除法运算,这体现了这个算法的优越性;其次在编程过程中由于设计上的问题所以直线的生成是用点击“确定”生成的,这是需要改进的地方!
实验分项1
多边形裁剪
实
验
目
的
用Sutherland-Hodgman算法进行多边形裁剪
实
验
要
求
1.将象素网格表现出来,建立网格坐标系
2.用橡皮筋的形式输入剪裁线段
3.裁剪过程需先输入一多边形,然后用窗口四边裁剪的过程中要显示顶点增删的过程。
实
验
原
理
步
骤
(
算
法
流
程
)
1.面板的初始化及裁剪框的生成:
方法:
publicvoidpaintComponent(Graphicsg)
画裁剪框:
for(intj=0;j<200;){
g.setColor(Color.RED);
g.fillRect(stx+j,sty,5,5);
g.fillRect(edx-j,edy,5,5);
j=j+5;
}
for(intj=0;j<160;){
g.setColor(Color.RED);
g.fillRect(stx,sty+j,5,5);
g.fillRect(edx,edy-j,5,5);
j=j+5;
}
画像素格:
for(inti=1;i<=LINE-1;i++){
g.setColor(Color.BLACK);
g.drawLine(SPACE*(i-1)+X_START,Y_START,SPACE*(i-1)+X_START,SPACE*(LINE-1)+Y_START);
g.drawLine(X_START,SPACE*(i-1)+Y_START,SPACE*(LINE-1)+X_START,SPACE*(i-1)+Y_START);
2.多边形的生成:
mouseClicked方法中获取点击点的位置,当点击“确定”的时候把两点取出,并画直线;
实
验
原
理
步
骤
(
算
法
流
程
)
for(inti=0;ig.fillRect(coor.get(i).getX(),coor.get(i).getY()+35,5,5);g.drawLine(coor.get(i)).getX()+4,coor.get(i)).getY()+35,
coor.get((i+1))).getX()+4,coor.get((i+1)).getY()+35);
Barsky(stx,sty,edx,edy,coor.get(i).getX(),coor.get(i)).getY(),coor.get(i+1).getX(),coor.get(i+1).getY());
}
其中,Barsky方法的功能是:
Barsky是每次找和框架相交得点,就是相似三角相似的原理;而且每一次把得到的点存起来,当全部做完以后就再画出来;
3.裁剪过程:
if(arg0.getSource()==jbtCut){
Graphicsg=getGraphics();
changeLine(dinate,g);
}
所以整个裁剪过程就是调用了publicvoidchangeLine(ArrayListp,Graphicsg)方法;
此方法的功能是:
通过Barsky算法获得交点坐标,这个方法是画那些交点后形成的直线!
while(it.hasNext()){
Coordinatepoint=(Coordinate)it.next();
pointX[j]=point.getX();
pointY[j]=point.getY();
j++;
}
多边形的裁剪结果是通过一下代码实现的:
for(inti=0;ig.drawLine(pointX[i]+8,pointY[i]+36,pointX[(i+1)%p.size()]+8,pointY[(i+1)%p.size()]+36);
g.drawLine(pointX[i]+6,pointY[i]+34,pointX[(i+1)%p.size()]+6,pointY[(i+1)%p.size()]+34);
g.drawLine(pointX[i]+6,pointY[i]+34,pointX[(i+1)%p.size()]+6,pointY[(i+1)%p.size()]+34);
g.drawLine(pointX[i]+4,pointY[i]+32,pointX[(i+1)%p.size()]+4,pointY[(i+1)%p.size()]+32);
g.drawLine(pointX[i]+4,pointY[i]+32,pointX[(i+1)%p.size()]+4,pointY[(i+1)%p.size()]+32);
}
在drawLine方法只能够对坐标点进行了修正!
(写不完时,可另加附页。
)
实
验
结
果
及
分
析
1.剪切框已经给出,画出一个多边形,点击剪切即可看到效果:
结果分析:
在这次实验中,首先是裁剪框是给定的,虽然对整个程序处理上有所帮助,但是这是一个限制的边框,所以这是可以改进的地方,只是代码要变得复杂。
其次直线的生成是经过先确定点,然后一次性画出的,这个方式不是很好,是可以通过每点击一次就重画来改进的;最后为了使多边形的裁剪过程清晰可见,并没有延续上一次的清屏的过程,直接在另一种颜色重新画了裁剪后的多边形;输出框中显示了整个多边形的裁剪过程!
心
得
体
会
这次的实验是对第三次实验直线的裁剪的扩展,而且整体的质量有所提高,首先了解了对多边形图形的裁剪过程,其次对算法有了一定的认识尤其是在通过不同方法的对比中评价算法的优越性!