图形学实验三.docx

上传人:b****5 文档编号:6343477 上传时间:2023-01-05 格式:DOCX 页数:20 大小:166.05KB
下载 相关 举报
图形学实验三.docx_第1页
第1页 / 共20页
图形学实验三.docx_第2页
第2页 / 共20页
图形学实验三.docx_第3页
第3页 / 共20页
图形学实验三.docx_第4页
第4页 / 共20页
图形学实验三.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

图形学实验三.docx

《图形学实验三.docx》由会员分享,可在线阅读,更多相关《图形学实验三.docx(20页珍藏版)》请在冰豆网上搜索。

图形学实验三.docx

图形学实验三

图形学实验三

Bezier曲线

040930301陈圣楠

一、程序实现环境、硬件配置、操作系统、编程语言

1.程序实现环境

本程序在eclipse-indigo通过,使用jdk1.6

2.硬件配置

处理器:

Intel(R)Core™i3CPUM3502.27GHz

安装内存(RAM):

2.00GB

3.操作系统

Windows7旗舰版32位操作系统

4.编程语言

java

二、算法思想阐述

Bezier曲线的定义是给定空间n+1个点的位置矢量,则Bezier曲线可定义为:

Ø算法推导

设是一条抛物线上顺序三个不同的点。

过和点的两切线交于点,在点的切线交和于和,则如下比例成立

当固定,引入参数t,令上述比值为,即有:

 

t从0变到1,第一、二式就分别表示控制二边形的第一、二条边,它们是两条一次Bezier曲线。

将一、二式代入第三式得:

当t从0变到1时,它表示了由三顶点三点定义的一条二次Bezier曲线。

并且表明:

这二次Bezier曲线可以定义为分别由前两个顶点和后两个顶点决定的一次Bezier曲线的线性组合。

依次类推,由四个控制点定义的三次Bezier曲线可被定义为分别由和确定的二条二次Bezier曲线的线性组合,由(n+1)个控制点定义的n次Bezier曲线可被定义为分别由前、后n个控制点定义的两条(n-1)次Bezier曲线与的线性组合。

由此得到Bezier曲线的递推计算公式

三、怎样使用

本程序实现了编程实现绘制一段三次Bezier曲线和实现两段三次Bezier曲线的拼接。

双击空白可添加顶点,添加两个顶点时,两点之间自动生成直线,添加第三个顶点时,根据Bezier公式,可产生一条曲线,继续添加顶点,每三个连续的顶点之间将产生一条曲线。

其他功能包括:

双击一个顶点,可将该顶点删除,拖动一个顶点可改变顶点位置,双击右键清屏。

图1初始化程序

图2选中一个顶点

四、实验结果(图示)

ØBezier曲线

图3选中两点的结果

图4Bezier曲线

图5Bezier曲线

(2)

五、测试用例(合法用例、非法用例)

1.合法用例

在画板灰色区域鼠绘即可,如上图4和图5。

2.非法用例

本程序采用鼠标点击,无非法用例,所以在此不提供非法用例及处理。

六、实验程序适用范围

本程序可作为画板、word等其他需要绘制曲线的程序的一部分,也可用于photoshop和flash中处理图像。

[源代码]

工程名:

csn0423Proj3

包名:

test3

类名:

Bezier.java

 

packagetest3;

importjavax.swing.*;

importjava.awt.*;

publicclassBezier

{

booleanpackFrame=false;

publicBezier()

{

Drawframe=newDraw();

if(packFrame)

{

frame.pack();

}

else

{

frame.validate();

}

DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize();

DimensionframeSize=frame.getSize();

if(frameSize.height>screenSize.height)

{

frameSize.height=screenSize.height;

}

if(frameSize.width>screenSize.width)

{

frameSize.width=screenSize.width;

}

frame.setLocation((screenSize.width-frameSize.width)/2,(screenSize.height-frameSize.height)/2);

frame.setVisible(true);

}

publicstaticvoidmain(String[]args)

{

try

{

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

}

catch(Exceptione)

{

e.printStackTrace();

}

newBezier();

}

}

工程名:

csn0423Proj3

包名:

test3

类名:

BezierPanel.java

 

packagetest3;

importjava.awt.*;

importjavax.swing.*;

importjava.util.ArrayList;

classVertex

{

staticfinalColorVEXCOLOR=Color.pink;

staticfinaldoubleRADII=4;

privatedoublex,y;

publicVertex(doublexx,doubleyy)

{

x=xx;

y=yy;

}

publicdoublegetX()

{

returnx;

}

publicdoublegetY()

{

returny;

}

publicvoidsetX(doublexx)

{

x=xx;

}

publicvoidsetY(doubleyy)

{

y=yy;

}

/**判断所给坐标是否在该顶点内*/

publicbooleanisIn(doubledx,doubledy)

{

doublelen;

len=Math.sqrt(Math.pow(dy-y,2)+Math.pow(dx-x,2));

if(len<=RADII)returntrue;elsereturnfalse;

}

publicStringtoString()

{

return"("+x+","+y+")";

}

}

publicclassBezierPanelextendsJPanel

{

privatestaticfinalStringINS1="双击空白地方添加顶点";

privatestaticfinalStringINS2="双击一个顶点删除该顶点";

privatestaticfinalStringINS3="拖动一个顶点改变该顶点的位置";

privatestaticfinalStringINS4="双击右键清屏";

privatestaticfinalColorVEXLINK=Color.red;//顶点间连线的颜色

staticfinalColorBEZIERCOLOR=Color.blue;//

privateArrayListvexs;//顶点

privateint[]bim;//伯恩斯坦多项式系数

publicBezierPanel()

{

super();

vexs=newArrayList();

}

/**取得原点横坐标*/

privateintgetX0()

{

return10;

}

/**取得原点纵坐标*/

privateintgetY0()

{

returnthis.getHeight()-10;

}

/**实数横坐标转象素横坐标*/

publicinttoPelsX(doubledx)

{

returngetX0()+(int)dx;

}

/**实数纵坐标转象素纵坐标*/

publicinttoPelsY(doubledy)

{

returngetY0()-(int)dy;

}

/**象素横坐标转实数横坐标*/

publicdoubletoRealX(intpx)

{

return(double)px-(double)getX0();

}

/**象素纵坐标转实数纵坐标*/

publicdoubletoRealY(intpy)

{

return(double)getY0()-(double)py;

}

/**求杨辉三角的底边

*@paramn阶次

*@returnint[]

*/

privateint[]yangHui(intn)

{

inti,j1,j2;

int[]c,tc;

c=newint[1];

c[0]=1;

for(i=2;i<=n;i++)

{

tc=c;

c=newint[i];

c[0]=1;

for(j2=0,j1=1;j1

c[j1]=1;

}

returnc;

}

/**增加一个顶点

*@parampx象素横坐标

*@parampy象素纵坐标

*/

publicvoidaddVex(intpx,intpy)

{

vexs.add(newVertex(toRealX(px),toRealY(py)));//加入顶点

bim=yangHui(vexs.size());//修改伯恩斯坦多项式系数

this.repaint();//重画

}

/**删除一个顶点

*@paramindex顶点序号

*/

publicvoidremoveVex(intindex)

{

vexs.remove(index);//删除

bim=yangHui(vexs.size());//修改伯恩斯坦多项式系数

this.repaint();//重画

}

/**删除所有顶点*/

publicvoidclear()

{

vexs.clear();

this.repaint();//重画

}

/**设置某个顶点的坐标

*@paramindex序号

*@paramdx象素横坐标

*@paramdy象素纵坐标

*/

publicvoidsetLocation(intindex,intdx,intdy)

{

Vertexvex;

if(index==-1)return;

vex=(Vertex)vexs.get(index);

vex.setX(toRealX(dx));

vex.setY(toRealY(dy));

this.repaint();

}

/**取得贝塞尔线的横坐标

*@paramt参数

*@returndouble

*/

publicdoublegetBezierX(doublet)

{

inti;

doublebx=0;

for(i=0;i

{

bx+=((Vertex)vexs.get(i)).getX()*bim[i]*Math.pow(t,i)*Math.pow(1-t,vexs.size()-1-i);

}

returnbx;

}

/**取得贝塞尔线的纵坐标

*@paramt参数

*@returndouble

*/

publicdoublegetBezierY(doublet)

{

inti;

doubleby=0;

for(i=0;i

{

by+=((Vertex)vexs.get(i)).getY()*bim[i]*Math.pow(t,i)*Math.pow(1-t,vexs.size()-1-i);

}

returnby;

}

/**取得选中的顶点序号

*@parampx鼠标横坐标

*@parampy鼠标纵坐标

*@return若没选中则返回-1

*/

publicintgetSelectexVexIndex(intpx,intpy)

{

inti;

doubledx,dy;

dx=toRealX(px);

dy=toRealY(py);

for(i=0;i

return-1;

}

/**画坐标系*/

publicvoiddrawCoordinate(Graphicsg)

{

Coloroldcolor;

oldcolor=g.getColor();

//坐标轴

g.drawLine(getX0(),getY0(),this.getWidth()-10,getY0());

g.drawLine(getX0(),getY0(),getX0(),10);

g.drawString("0",getX0()-7,getY0()+10);

g.drawString("x",this.getWidth()-10,getY0()+10);

g.drawString("y",getX0()-7,10);

//说明文字

g.drawString(INS1,15,20);

g.drawString(INS2,15,32);

g.drawString(INS3,15,44);

g.drawString(INS4,15,56);

g.setColor(oldcolor);

}

/**画顶点极其连线*/

publicvoiddrawVexList(Graphicsg)

{

inti,dia;

Vertexvex1,vex2;

Coloroldcolor;

if(vexs.size()==0)return;//没有顶点则返回

oldcolor=g.getColor();//保存原来的颜色

g.setColor(Vertex.VEXCOLOR);//顶点色

dia=(int)Vertex.RADII*2;//直径

vex1=(Vertex)vexs.get(0);//第一个顶点

//fillOval()的坐标参数为左上角坐标,不是原点坐标

g.fillOval(toPelsX(vex1.getX())-(int)Vertex.RADII,toPelsY(vex1.getY())-(int)Vertex.RADII,dia,dia);//画第一个顶点

for(i=1;i

{

vex2=vex1;

vex1=(Vertex)vexs.get(i);//取新顶点

g.fillOval(toPelsX(vex1.getX())-(int)Vertex.RADII,toPelsY(vex1.getY())-(int)Vertex.RADII,dia,dia);//画新顶点

g.drawLine(toPelsX(vex2.getX()),toPelsY(vex2.getY()),toPelsX(vex1.getX()),toPelsY(vex1.getY()));//画连线

}

g.setColor(oldcolor);//还原旧颜色

}

publicvoidpaintComponent(Graphicsg)

{

doubledx1,dy1,dx2,dy2,t,dt=0.01;

super.paintComponent(g);

drawCoordinate(g);

//g.drawString(INS,10,10);

drawVexList(g);

//当两个以上顶点时画曲线

if(vexs.size()>=2)

{

g.setColor(BEZIERCOLOR);

dx1=getBezierX(0);

dy1=getBezierY(0);

for(t=0;t<=1;t+=dt)

{

dx2=dx1;

dy2=dy1;

dx1=getBezierX(t);

dy1=getBezierY(t);

g.drawLine(toPelsX(dx2),toPelsY(dy2),toPelsX(dx1),toPelsY(dy1));

}

}

}

}

工程名:

csn0423Proj3

包名:

test3

类名:

Draw.java

 

packagetest3;

importjava.awt.*;

importjava.awt.event.*;

importjavax.swing.*;

importjavax.swing.border.*;

publicclassDrawextendsJFrame

{

JPaneljPanel;

JMenuBarjMenuBar1=newJMenuBar();

JMenujMenuFile=newJMenu();

BorderLayoutborderLayout1=newBorderLayout();

privateJPaneljpboard=newJPanel();

privateTitledBordertitledBorder1;

privateBezierPanelboard=newBezierPanel();

privateBorderLayoutborderLayout2=newBorderLayout();

privateJLabeljlloc=newJLabel();

privateintindex;//选中的顶点

publicDraw()

{

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try

{

jbInit();

}

catch(Exceptione)

{

e.printStackTrace();

}

index=-1;

}

//Componentinitialization

privatevoidjbInit()throwsException

{

jPanel=(JPanel)this.getContentPane();

titledBorder1=newTitledBorder(BorderFactory.createEtchedBorder(Color.white,newColor(165,163,151)),"bezierboard:

");

jPanel.setLayout(borderLayout1);

this.setSize(newDimension(538,417));

this.setTitle("Bezier");

jpboard.setBorder(titledBorder1);

jpboard.setLayout(borderLayout2);

board.addMouseListener(newDraw_MouseAdapter(this));

jlloc.setHorizontalAlignment(SwingConstants.RIGHT);

jlloc.setText("");

board.addMouseMotionListener(newGUI_board_mouseMotionAdapter(this));

jpboard.add(board,BorderLayout.CENTER);

jPanel.add(jpboard,BorderLayout.CENTER);

jPanel.add(jlloc,BorderLayout.SOUTH);

this.setJMenuBar(jMenuBar1);

}

/**鼠标点击*/

voidboard_mouseClicked(MouseEvente)

{

intindex;

if(e.getClickCount()!

=2)

{

return;//双击事件

}

if(e.getButton()==MouseEvent.BUTTON3)

{

board.clear();//右键双击删除所有顶点

}

elseif(e.getButton()==MouseEvent.BUTTON1)//左键双击

{

index=board.getSelectexVexIndex(e.getX(),e.getY());//取得顶点序号

if(index==-1)

{

board.addVex(e.getX(),e.getY());//若点击空白则加入顶点

}

else

{

board.removeVex(index);//删除顶点

}

}

}

/**鼠标移动*/

voidboard_mouseMoved(MouseEvente)

{

jlloc.setText("Location:

("+board.toRealX(e.getX())+","+board.toRealY(e.getY())+")");

}

/**鼠标压下*/

voidboard_mousePressed(MouseEvente)

{

index=board.getSelectexVexIndex(e.getX(),e.getY());

}

/**鼠标放开*/

voidboard_mouseReleased(MouseEvente)

{

index=-1;

}

/**鼠标拖动*/

voidboard_mouseDragged(MouseEvente)

{

intpx,py;

if(index!

=-1)

{

px=e.getX();

py=e.getY();

//将坐标限制在画板内

if(px<0)px=0;

if(px>board.getWidth())px=board.getWidth();

if(py<0)py=0;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1