Java递归方法实现山脉绘制

网友投稿 239 2022-09-04


Java递归方法实现山脉绘制

本文实例为大家分享了java递归方法实现山脉绘制的具体代码,供大家参考,具体内容如下

一、山脉绘制的思路

给定两个点A(x1,y1),B(x2,y2),递归不断取中点,同时给定一个范围[-range,range]和一个比率rate。每次取中点后,这个中点的纵坐标的值加上这个范围内的随机值,同时通过range=range*rate来缩小这个变化的范围,最后,通过相邻的点连线,绘制成一个山脉的形状。

二、整段代码如下

package com.yf1031;

import java.awt.FlowLayout;

import java.awt.Graphics;

import java.util.Random;

import javax.swing.JFrame;

public class Drawpanel {

public static void main(String[] args) {

Drawpanel drawpanel = new Drawpanel();

drawpanel.showUI();

}

public void showUI() {

JFrame jf = new JFrame();

jf.setTitle("山脉");

jf.setSize(800, 800);

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

jf.setLayout(new FlowLayout());

jf.setLocationRelativeTo(null);

jf.setVisible(true);

Graphics g = jf.getGraphics();

int xl = 10, yl =500 , xr = 750, yr = 600, range = 300;

double rate = 0.5;

try {

Thread.sleep(566);

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

divide(xl, yl, xr, yr, g, range, rate);

}

public void divide(int xl, int yl, int xr, int yr, Graphics g, int range, double rate) {

if(Math.abs(xr - xl) <= 1 | range == 0) {

g.drawLine(xl, yl, xr, yr);

}else {

int x=(xr+xl)/2;

int y = (yl+yr)/2;

//按比例缩小range

Random rand = new Random();

int num = rand.nextInt(range*2) - range;

range = (int)(range*rate);

//与B点递归,迭代A点

divide(x, y+num, xr, yr, g, range, rate);

//与A点递归,迭代B点

divide(xl, yl, x, y+num, g, range, rate);

}

}

}

结果为:

现在,我们来对整段代码进行分析,这个整个代码主要通过divide方法 进行递归取中点画图形,代码如下:

public void divide(int xl, int yl, int xr, int yr, Graphics g, int range, double rate) {

if(Math.abs(xr - xl) <= 1 | range == 0) {

g.drawLine(xl, yl, xr, yr);

}else {

int x=(xr+xl)/2;

int y = (yl+yr)/2;

//按比例缩小range

Random rand = new Random();

int num = rand.nextInt(range*2) - range;

range = (int)(range*rate);

//与B点递归,迭代A点

divide(x, y+num, xr, yr, g, range, rate);

//与A点递归,迭代B点

divide(xl, yl, x, y+num, g, range, rate);

}

}

在这段代码中,我们首先需要去判断一下传入进来的两个点A,B的横坐标的差值是否小于等于1或者是变量range等于0,如果是http://,则直接画线即可,因为像素最小单位就为1,不能用小数表示;否则,就要取递归取中点了,然后,通过给A,B两个点上加上动态的变化量range,从而实现不停的递归画线,最终形成了山脉的形状。

三、实现山脉的填充功能

山脉填充功能的效果图:

那它是如何实现该功能的呢?

那先来看一段代码:

public void divide(int xl, int yl, int xr, int yr, Graphics g, int range, double rate) {

if(Math.abs(xr - xl) <= 10 | range == 0) {

g.drawLine(xl, yl, xr, yr);

Polygon p = new Polygon();

p.addPoint(xl, yl);//这里需要连接几个点就添加几个点,而且按一定的顺序,顺时针和逆时针都行

p.addPoint(xl, 800);

p.addPoint(xr, 800);

p.addPoint(xr, yr);

g.fillPolygon(p);

}else {

int x=(xr+xl)/2;

int y = (yl+yr)/2;

//按比例缩小range

Random rand = new Random();

int num = rand.nextInt(range*2) -http:// range;

range = (int)(range*rate);

//与B点递归,迭代A点

divide(x, y+num, xr, yr, g, range, rate);

//与A点递归,迭代B点

divide(xl, yl, x, y+num, g, range, rate);

}

}

根据上述的这段代码,我们可以看到本文利用Polygon类创建了一个对象,Polygon类封装了对坐标空间内封闭的二维区域的描述。 该区域由任意数量的线段界定,每个线段都是多边形的一侧。 在内部,多边形由(x,y)个坐标对列表组成,其中每对坐标定义了多边形的顶点,两个连续的对是作为多边形侧面的线的端点。 (x,y)点的第一对和最后一对通过封闭多边形的线段相连。 当这四个点按一定顺序(顺时针和逆时针都行)连接起来,然后利用fillPolygon方法进行填充,最终得到了上面山脉填充效果图。

四、使用缓冲图片画图

我们都知道,当你需要画好几张图片的时候,会发现画的速度很慢,这个时候BufferedImage类就应运而生,Java中画图一般会使用该类创建对象去实现更快的画图。

它的原理: 是先将一幅图片加载到内存中(BufferedImage生成的图片在内存里有一个图像缓冲区,利用这个缓冲区我们可以很方便地操作这个图片),提供获得绘图对象、图像缩放、选择图像平滑度等功能,通常用来做图片大小变换、图片变灰、设置透明不透明等。

关键程序的代码为:

//创建缓冲图片

BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_RGB);

//获取缓冲图片的画笔

Graphics buffg = bufferedImage.getGraphics();

divide(xl, yl, xr, yr, buffg, range, rate);

//将缓冲图片画在窗体上

g.drawImage(bufferedImage, 0, 0, null);

读者可以自己结合上面的 “二、整段代码” 去比较所改动的地方,除了这段关键的代码改动了,其余并没有改动

实现的效果图为:

看到这样的效果图,我发现跟我之前所画的山脉不一样,“三、山脉填充功能” 所画的山脉是黑色来填充,白色为天空,但我现在所画的这个就刚刚相反,刚开始的我百思不得其解,因此,我想这给这个填充色不要弄成默认的填充色,而是设置成蓝色,则效果图如下:

这个图与上面的图片进行对比,可以得到的结论是: 当使用BufferedImage类来创建缓冲图片时,缓冲图片的背景色就是黑色,而当你使用默认的填充时,Java中为了区分,会将默认填充黑色改为默认填充白色,只是为了做区分而已,而当你将填充的颜色改为蓝色,那么下面就是蓝色了,不再是白色了。

通过上面的实验,得到一个结论: 当你的程序出现了跟你的预期结果不一致的时候,你可以去多做实验,多设置输出来弄清楚自己编写代码什么时候出错了!!!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Django模板(Django模板的作用)
下一篇:Django路由(django路由分发实现页面显示跳转)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~