java画Hibert曲线

以前用java画过Koch曲线,Hibert也是分形曲线的一种而且具有很多奇特的性质。文章(一个非常不错的博客)对Hibert 的性质和画法给出了详细的介绍。本程序就是参考该文

章写出的。程序的运行效果如图所示分别为迭代次数取4,7,8时的效果:



程序代码:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JFrame;

public class Hibert extends JFrame{
	static final int DOWN=1;
	static final int LEFT=2;
	static final int RIGHT=3;
	static final int UP=4;
	
	public static void main(String[] args) {
		new Hibert();
	}
	Hibert(){
		this.setBounds(200, 200, 800, 800);  
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
        this.setVisible(true); 
	}
	public void paint(Graphics g) { 
		super.paint(g);
		g.setColor(Color.red);
		Rectangle rect=new Rectangle(100,100,600,600);
		drawHibert(rect,DOWN,9,g);
	}
	/*drawHibert 返回Hibert曲线的起始点和终点,direction是Hibert曲线的方向。n为迭代的次数算法采用分治的
	 * 思想,把一块区域分割成四部分,然后在每个部分画hibert曲线,最后把这四部分连在一起。注意考虑曲线的方向。
	*/
	public Point[] drawHibert(Rectangle rect, int direction,int n,Graphics g){
		Point[] temp=new Point[2];
		int width=rect.width/2;
		int height=rect.height/2;
		if(n==0){//当n=0时,hibert变成一个点。
			Point p=new Point(rect.x+width,rect.y+height);
			temp[0]=p;
			temp[1]=p;
		}
		else{
			Rectangle rect1=new Rectangle(rect.x,rect.y,width,height);
			Rectangle rect2=new Rectangle(rect.x+width,rect.y,width,height);
			Rectangle rect3=new Rectangle(rect.x,rect.y+height,width,height);
			Rectangle rect4=new Rectangle(rect.x+width,rect.y+width,width,height);
			switch (direction){
				case DOWN:{
					Point[] point1=drawHibert(rect1,DOWN,n-1,g);
					Point[] point2=drawHibert(rect2,DOWN,n-1,g);
					Point[] point3=drawHibert(rect3,LEFT,n-1,g);
					Point[] point4=drawHibert(rect4,RIGHT,n-1,g);
					g.drawLine(point1[1].x, point1[1].y, point2[0].x,point2[0].y);
					g.drawLine(point1[0].x, point1[0].y, point3[0].x,point3[0].y);
					g.drawLine(point2[1].x, point2[1].y, point4[0].x,point4[0].y);
					temp[0]=point3[1];
					temp[1]=point4[1];
					break;
				}
				case LEFT:{
					Point[] point1=drawHibert(rect1,UP,n-1,g);
					Point[] point2=drawHibert(rect2,LEFT,n-1,g);
					Point[] point3=drawHibert(rect3,DOWN,n-1,g);
					Point[] point4=drawHibert(rect4,LEFT,n-1,g);
					g.drawLine(point1[1].x, point1[1].y, point2[0].x,point2[0].y);
					g.drawLine(point3[1].x, point3[1].y, point4[1].x,point4[1].y);
					g.drawLine(point2[1].x, point2[1].y, point4[0].x,point4[0].y);
					temp[0]=point1[0];
					temp[1]=point3[0];
					break;
				}
				case RIGHT:{
					Point[] point1=drawHibert(rect1,RIGHT,n-1,g);
					Point[] point2=drawHibert(rect2,UP,n-1,g);
					Point[] point3=drawHibert(rect3,RIGHT,n-1,g);
					Point[] point4=drawHibert(rect4,DOWN,n-1,g);
					g.drawLine(point1[0].x, point1[0].y, point2[0].x,point2[0].y);
					g.drawLine(point1[1].x, point1[1].y, point3[0].x,point3[0].y);
					g.drawLine(point3[1].x, point3[1].y, point4[0].x,point4[0].y);
					temp[0]=point2[1];
					temp[1]=point4[1];
					break;
				}
				case UP:{
					Point[] point1=drawHibert(rect1,LEFT,n-1,g);
					Point[] point2=drawHibert(rect2,RIGHT,n-1,g);
					Point[] point3=drawHibert(rect3,UP,n-1,g);
					Point[] point4=drawHibert(rect4,UP,n-1,g);
					g.drawLine(point1[1].x, point1[1].y, point3[0].x,point3[0].y);
					g.drawLine(point2[1].x, point2[1].y, point4[1].x,point4[1].y);
					g.drawLine(point3[1].x, point3[1].y, point4[0].x,point4[0].y);
					temp[0]=point1[0];
					temp[1]=point2[0];
					break;
				}
			}
		}
		return temp;
	}
}
该程序有一点小缺陷,从效果图中可以看出区块和区块之间的间距明显要比区块内部之间的间距要大,主要是整形除法的向下取值造成的。可以采用浮点数计算然后在映射到整数区域的办法,不过比较麻烦。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值