科赫曲线又被称为雪花曲线,是分形中的一种,画科特曲线的基本思路是先画一个给定边长和顶点坐标的正三角形,通过数学方法求出另外两个点的坐标,然后从界面获得要递归的次数(递归一次三角形的每一条边就被分为三等分以此类推),求出每一条边最终被分成了多长的小等分,最后从某一个顶点开始画最小等份的_/\_形状并逐层向上返回(另外两个端点也一样)。


要注意的地方:
1、 从界面输入的递归次数是String类型的,在用之前要将其转换为int类型的

//获取递归次数 

 String a = jta.getText(); 

 //将String “a”转为int a 

 times = Integer.parseInt(a); 

2、 要画线段的起始坐标先定义为double,因为用数学函数求出的是double类型的数据,画的时候再强制转换为int,这样可以使得误差小一些。 

3、 要将给出的角度转换为弧度角,例如angle为180度(无法表示出),所以就要转化为Math.PI(3.141592657)弧度 

 R = Math.PI/180*angle; 




具体代码如下: 

package com20130318; 


import java.awt.Color; 


import java.awt.Graphics; 


import javax.swing.JFrame; 

import javax.swing.JLabel; 

import javax.swing.JTextField; 


/** 

 * 写一个画科特曲线的类 

 * @author 

 * 

 */ 

public class Koch extends JFrame{ 

 //主函数 

 public static void main(String args[]){ 

 Koch ko = new Koch(); 

 ko.showInfo(); 

 } 



 public void showInfo(){ 

 //创建一个固定大小的窗体对象 

 JFrame jf = new JFrame(); 

 jf.setSize(400,400); 

 //设置窗体的布局管理 

 java.awt.FlowLayout fl = new java.awt.FlowLayout(); 

 jf.setLayout(fl); 


 jf.setResizable(false); 

 jf.setDefaultCloseOperation(3); 

 //jf.getContentPane().setBackground(Color.BLACK); 


 //创建一个标签 


 String str="递归层数:"; 

 JLabel jl = new JLabel(str); 

 jf.add(jl); 

 //标签长度 

 JTextField jta = new JTextField(10); 

 jf.add(jta); 

 jf.setVisible(true); 


 //得到画布对象 

 Graphics gr = jf.getGraphics(); 


 //创建一个鼠标监听器 

 MyMouseListener lis = new MyMouseListener(); 

 lis.gr = gr; 

 lis.jta = jta; 

 jf.addMouseListener(lis); 

 } 

} 



package com20130318; 


import java.awt.Color; 

import java.awt.Graphics; 

import java.awt.event.MouseEvent; 

import java.awt.event.MouseListener; 


import javax.swing.JTextField; 

/** 

 * 自定义一个鼠标监听器类 

 * @author Administrator 

 * 

 */ 

public class MyMouseListener implements MouseListener{ 

 Graphics gr; 

 JTextField jta; 

 //times用来记录递归调用的次数 

 int times ; 

 double angle; 

 //(x0,y0)表示要画线段的起始坐标,先定义为double,画线段时再强制转换为int 

 double x0; 

 double y0; 

 //length表示当前线段的长度 

 double length; 



 /** 

 * 自定义mouseClicked方法 用来获取递归次数 

 */ 

 public void mouseClicked(MouseEvent e) { 

 gr.clearRect(50, 50,600,600); 

 //获取递归次数 

 String a = jta.getText(); 

 //将String “5”转为int “5” 

 times = Integer.parseInt(a); 


 paint(gr); 

// try { 

// Thread.sleep(200); 

// }catch(Exception ef){} 

// 


 } 



 /** 

 * 定义一个paint方法 

 * @param g 传入画布参数 

 */ 

 public void paint(Graphics g) { 

 gr.setColor(Color.BLUE); 

 // 返回3的time次幂的值 

 int N = (int) Math.pow(3, times); 

 //求出当前长度 

 length = 200.0 / N; 


 /** 

 * 画 "/ "(x0,y0)左下的端点,,因为三角形的顶点坐标为(150,100),所以y0 = (int)(Math.sqrt(3)*100)+50 

 */ 

 angle = -60; 

 x0 = 50; 

 y0 = (int)(Math.sqrt(3) * 100) + 100; 

 drawKoch(g, times, angle); 


 /** 

 * 画 "\" (x0,y0)左上的端点(150,100) 

 */ 

 angle = 60; 

 x0 = 150; 

 y0 = 100; 

 drawKoch(g, times, angle); 


 /** 

 * 画" _ "(x0,y0)右端点 

 */ 

 angle = 180; 

 x0 = 250; 

 y0 = (int)(Math.sqrt(3) * 100) + 100; 

 drawKoch(g, times, angle); 

 } 



 public void drawKoch(Graphics g, int n, double angle) { 

 double x1, y1, R; 


 if (n == 0) { 

 //转化为弧度角,例如angle为180度(无法表示出),则可以转化为Math.PI(3.1415926)弧度 

 R = Math.PI / 180 * angle; 


 //每次求出离当前端点最近的下一端点坐标,并画出该线段 

 x1 = length * Math.cos(R) + x0; 

 y1 = length * Math.sin(R) + y0; 

 g.drawLine((int) x0, (int) y0, (int) x1, (int) y1); 

 //更换当前端点坐标 

 x0 = x1; 

 y0 = y1; 

 return; 

 } 


 /** 

 * 画出的曲线依次是_/\_ 

 */ 

 drawKoch(g, n-1, angle); 

 drawKoch(g, n-1, angle - 60); 

 drawKoch(g, n-1, angle + 60); 

 drawKoch(g, n-1, angle); 

 } 






 @Override 

 public void mousePressed(MouseEvent e) { 

 // TODO Auto-generated method stub 


 } 


 @Override 

 public void mouseReleased(MouseEvent e) { 

 // TODO Auto-generated method stub 


 } 


 @Override 

 public void mouseEntered(MouseEvent e) { 

 // TODO Auto-generated method stub 


 } 


 @Override 

 public void mouseExited(MouseEvent e) { 

 // TODO Auto-generated method stub 


 } 


}