计算机图形学实验报告+完整代码Word文档格式.docx
《计算机图形学实验报告+完整代码Word文档格式.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告+完整代码Word文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
Koch曲线是一个数学曲线,同时也是早期被描述的一种分形曲线。
它由瑞典数学家HelgevonKoch在1904年发表的一篇题为“从初等几何构造的一条没有切线的连续曲线”的论文中提出。
有一种Koch曲线是象雪花一样,被称为Koch雪花(或Koch星),它是由三条Koch曲线围成的等边三角形。
如图所示(用附件自带画图软件所画):
3,解决方案
设想从一个线段开始,根据下列规则构造一个Koch曲线:
1.三等分一条线段;
2.用一个等边三角形替代第一步划分三等分的中间部分;
3.在每一条直线上,重复第二步。
Koch曲线是以上步骤地无限重复的极限结果。
Koch曲线的长度为无穷大,因为以上的变换都是一条线段变四条线段,每一条线段的长度是上一级的1/3,因此操作n步的总长度是(4/3)n:
若n→∞,则总长度趋于无穷。
Koch曲线的分形维数是log4/log3≈1.26,其维数大于线的维数
(1),小于Peano填充曲线的维数
(2)。
Koch曲线是连续的,但是处处不可导的。
Koch雪花的面积是2*√3*s&
sup2;
/5,这里的s是最初三角形的边长,Koch雪花的面积是原三角形面积的8/5,它成为一条无限长的边界围绕着一个有限的面积的几何对象。
下面先看自己画的一幅图(生成元初始状态):
图中可以看到生成元的起点坐标为(x1,y1),终点坐标为(x2,y2),线段长度记为length,其递归深度depth=0;
再看自己画的另一幅图(生成元第一次变化):
把变化后的每段线段长度记为len。
图上的坐标可以这样计算:
(xa,ya)
xa=x1+(x2-x1)/3.0;
ya=y1+(y2-y1)/3.0;
(xb,yb)
xb=(xa+x2)/2.0;
yb=(ya+y2)/2.0;
(xc,yc)
xc=xa+len*cosα;
yc=ya-len*sinα;
对于len
len=length/(3^depth);
//此次depth=0;
至于角度α的求解,可以先算出直线本身的倾斜角度actan((y2-y1)/(x2-x1)),再加上初始角度α0,则有α=actan((y2-y1)/(x2-x1))+α;
生成元第二次~第n次变化
。
。
依次类推
4,具体代码
packageKochSnowFlake;
importjava.awt.*;
importjavax.swing.*;
/**
*@TitleKoch雪花
*@Author孙琨
*@Date2013-11-23
*@AtXUST
*@AllCopyrightby孙琨
*
*/
publicclassFractalJPanelextendsJPanel{//Koch雪花分形具体算法
privateintdepth;
//递归深度
privateColorcolor;
privatefinalstaticintWIDTH=600;
privatefinalstaticintHEIGHT=700;
privatefinalstaticintlength=450;
publicFractalJPanel(intdepth){
setColor(Color.BLUE);
setDepth(depth);
setBackground(Color.WHITE);
setPreferredSize(newDimension(WIDTH,HEIGHT));
}
privatedoublegetAngle(intx1,inty1,intx2,inty2){//计算相邻两直线间的夹角
returnMath.atan2((y1-y2),(x2-x1))+Math.PI/3;
publicvoiddrawFractal(intdepth,intx1,inty1,intx2,inty2,Graphicsg){//递归绘制
//递归结束条件
if(depth==0){
g.drawLine(x1,y1,x2,y2);
}else{
//计算坐标(xa,ya)
intxa=(int)Math.round(x1+(x2-x1)/3.0);
intya=(int)Math.round(y1+(y2-y1)/3.0);
//计算坐标(xb,yb)
intxb=(int)Math.round((xa+x2)/2.0);
intyb=(int)Math.round((ya+y2)/2.0);
//计算递归后的线元长度
intlen=(int)(length/Math.pow(3,(this.depth-depth+1)));
doubleangle=getAngle(x1,y1,x2,y2);
//计算坐标(xc,yc)
intxc=(int)Math.round(xa+len*Math.cos(angle));
intyc=(int)Math.round(ya-len*Math.sin(angle));
//递归
drawFractal(depth-1,x1,y1,xa,ya,g);
drawFractal(depth-1,xa,ya,xc,yc,g);
drawFractal(depth-1,xc,yc,xb,yb,g);
drawFractal(depth-1,xb,yb,x2,y2,g);
publicvoidpaintComponent(Graphicsg){
super.paintComponent(g);
//绘制最初的三条直线,形成初始三角形图案
g.setColor(color);
drawFractal(depth,50,450,275,60,g);
drawFractal(depth,275,60,500,450,g);
drawFractal(depth,500,450,50,450,g);
//获取递归深度
publicintgetDepth(){
returndepth;
//设置递归深度
publicvoidsetDepth(intdepth){
this.depth=depth;
//设置颜色
publicvoidsetColor(Colorcolor){
this.color=color;
}
importjava.awt.event.*;
publicclassFractalJFrameextendsJFrame{//Koch雪花整体设计
privatefinalstaticintMIN_DEPTH=0;
//最小递归深度
privateColorcolor=Color.BLUE;
privateJButtonincreaseDepthJButton;
//增加递归深度按钮
privateJButtondecreaseDepthJButton;
//减少递归深度按钮
privateJButtonsetColorJButton;
//设置颜色按钮
privateJPanelmainJPanel;
privateJPanelcontrolJPanel;
privateFractalJPaneldrawSpace;
//Koch雪花分形具体算法类的一个对象
privateJLabeldepthJLabel;
//记录递归深度的标签
publicFractalJFrame(){
//添加标题
super("
Koch雪花"
);
//添加按钮
controlJPanel=newJPanel();
setColorJButton=newJButton("
设置颜色"
increaseDepthJButton=newJButton("
增加递归深度"
decreaseDepthJButton=newJButton("
减少递归深度"
controlJPanel.add(setColorJButton);
controlJPanel.add(increaseDepthJButton);
controlJPanel.add(decreaseDepthJButton);
//设置按钮相应的有关监听器
setColorJButton.addActionListener(
newActionListener(){
publicvoidactionPerformed(ActionEventevent){
color=JColorChooser.showDialog(
FractalJFrame.this,"
请选择一种颜色"
color);
if(color==null){
color=Color.BLUE;
drawSpace.setColor(color);
);
increaseDepthJButton.addActionListener(newActionListener(){
intdepth=drawSpace.getDepth();
depth++;
if(depth>
=MIN_DEPTH){
depthJLabel.setText("
depth:
"
+depth);
drawSpace.setDepth(depth);
repaint();
decreaseDepthJButton.addActionListener(newActionListener(){
depth--;
});
depthJLabel=newJLabel("
0"
controlJPanel.add(depthJLabel);
drawSpace=newFractalJPanel(0);
mainJPanel=newJPanel();
mainJPanel.setLayout(newBorderLayout());
mainJPanel.add(controlJPanel,BorderLayout.NORTH);
mainJPanel.add(drawSpace);
add(mainJPanel);
setSize(WIDTH,HEIGHT);
setVisible(true);
publicstaticvoidmain(Stringargs[]){//主方法
FractalJFrameframe=newFractalJFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
5,运行结果截图
6,实验总结
此次实验,学习了Koch雪花的绘制,加深了对分形和递归调用的理解。
学习计算机图形学的兴趣更加浓厚了。