栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

平面及3D山脉——Java实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

平面及3D山脉——Java实现

1,画平面山脉

 大概思路就是给定两个点(x1,y1),(x2,y2),然后取他们的中点(px,py),然后再取(x1,y1)和(px,py)的中点和(x2,y2)和(px,py)的中点,同时给定一个范围[-range,range]和一个比率rate,每次取中点后的中点纵坐标都加上这个范围内的随机值,每次中点后range都乘以rate来缩小range的范围。当两个点的横坐标小于某个值或者不能再取中点时就连接起来,即可。

递归方法的代码

public void draw(double x1,double y1,double x2,double y2,int range,double rate) {
		if(Math.abs(x1-x2)<=1|range==0) {
            //画线
			g.drawLine((int)x1,(int) y1, (int)x2,(int) y2);
		}else {
		    double Px=(x1+x2)/2;
		    double Py=(y1+y2)/2;
            //在[-range,range]范围内震荡y值
		    Random random=new Random();
		    int num = random.nextInt(range*2) - range;
            //缩小range
		    range = (int)(range*rate);
            //递归调用
	        sm(x1,y1,Px,Py-num,range,rate);
		    sm(Px,Py-num,x2,y2,range,rate);
		}
	}

调用方法draw(x1,y1,x2,y2,500,0.55);的效果为

 调用时加个for循环,加上填充图形等方法就可以完成平面山脉的绘制,效果如下:

 2,3D山脉的绘制

首先,要会递归分形画带有立体感的三角形,效果如下:

 大概思路就是三角形每两个点之间取中点,但是要给所求的中点的纵坐标加上某个范围内的值,实现中点的震荡,这样就能实现带有一定立体感的三角形。代码如下:

    //画立体三角形
    public void draw(double x1,double y1,double x2,double y2,double x3,double y3,double count,int range,int rate) {
    	if(count<0) {
    		int[] px = { (int)x1, (int)x2, (int)x3 };
			int[] py = { (int)y1, (int)y2, (int)y3 };
			Color color = new Color(100, 100, 100, 80);
            g.drawPolygon(px, py, 3);
           return;
    	}
    	count--;
        //中点坐标
        double ax,ay,bx,by,cx,cy;
        
        //用随机数类实现纵坐标的偏移
    	Random random1=new Random();

        ax=(x1+x2)/2;
	    ay=(y1+y2)/2+random1.nextInt(range);

        bx=(x1+x3)/2;
	    by=(y1+y3)/2+random1.nextInt(range);

        cx=(x2+x3)/2;
	    cy=(y2+y3)/2+random1.nextInt(range);
        
        //缩小range的值
	    range*=rate;
        
        //递归分形
        draw(x1,y1,ax,ay,bx,by,count,range,rate);
    	draw(x2,y2,ax,ay,cx,cy,count,range,rate);
    	draw(x3,y3,cx,cy,bx,by,count,range,rate);
    }

 这代码并不完善,中间还有许多倒三角形空白,所以还要给中间的倒三角形加上递归分形。效果如下:

 这时就会出现问题了。在之前递归中,倒三角形的边上已经有了中值震荡点,在加上中间倒三角形的递归分形后,倒三角形边上的所有中值震荡点会重新再取一遍,这样就会产生两给中点,不解决这个问题,最后的立体山脉就会出现空白和不完整问题。如何解决呢?

解决方法很简单,当倒三角形递归分形时,每当其取震荡中点时,判断以前是不是有过,有就直接取用之前的震荡中值点,没有则自己取震荡中值点。判断之前是不是有过震荡中值点,就需要把之前取到的震荡中值点都存起来,每当要取震荡中值点的时候就拿出来一一比较。

我能力有限,只会用数组,但其实用数组来存点的效率是很低的,或许以后学到更好的方法会加以改进吧。

//数组来存点
public Arry[] arry=new Arry[100000];

public class Arry {
	   double x,y,z;
	   public Arry(double x,double y,double z) {
		 this.x=x;//中点值横坐标
		 this.y=y;//中点值纵坐标
		 this.z=z;//中点值偏移量
	}
}

创建一个类用来存点,每当取到新的震荡中值点就放入数组中保存。

int index=0;
Arry arry=new Arry(x,y,z);
arry[index++]=arry;

每次再取震荡中点时,遍历数组比较即可。方法代码如下:

public void draw(double x1,double y1,double x2,double y2,double x3,double y3,double count,int range) {
    	if(count<0) {
    		int[] px = { (int)x1, (int)x2, (int)x3 };
			int[] py = { (int)y1, (int)y2, (int)y3 };
			Color color = new Color(100, 100, 100, 80);
            g.drawPolygon(px, py, 3);
    		return;
    	}
    	count--;
        int flag1=1,flag2=1,flag3=1;
        int u=0,j=0,k=0;
    	double ax=0,ay=0,az=0,bx=0,by=0,bz=0,cx=0,cy=0,cz=0;
    	Random random1=new Random();
    	
    	for(int i=0;i

效果如下:

 然后给增加递归层数,加上填充(Polygon)的方法,

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/336671.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号