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,如果是,则直接画线即可,因为像素最小单位就为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) - 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中为了区分,会将默认填充黑色改为默认填充白色,只是为了做区分而已,而当你将填充的颜色改为蓝色,那么下面就是蓝色了,不再是白色了。

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现平面山脉模型

    本文实例为大家分享了java实现平面山脉模型的具体代码,供大家参考,具体内容如下 核心方法:递归 其实当我第一次看到这个题目时,心中想的不就是个普通的递归吗,直接取两个点,然后不断取横坐标中点,然后中点纵坐标取随机数不就行吗,代码如下 public void recur(Graphics g, double x1, double x2, double y1, double y2, int range) {             double x3 = (x1 + x2) / 2;       

  • Java实现递归山脉

    本文实例为大家分享了Java实现递归山脉的具体代码,供大家参考,具体内容如下 一.递归山脉的要求 给定左右两个点X1(Lx,Ly),X2(Rx,Ry),一个y轴动态范围-range~range,在该动态范围内随机选取一个数num,选取一个中点M,中点的横坐标为(Lx+Rx)/2,纵坐标为(Ly+Ry)/2+num,连接左端点与中点.中点与右端点.如此反复,再分别取左端点X1和中点M的中点.中点M和右端点X2的中点,range范围按一定比例缩小,连接两点形成递归山脉. 二.创新点 之前我们调用递归

  • Java分形绘制山脉模型

    本文实例为大家分享了Java分形绘制山脉模型的具体代码,供大家参考,具体内容如下 如何绘制一个山脉 构思设计 任意选取三个点,选取一个范围和一个比率,每一个都对这三个点取中点,中点的纵坐标加一个在范围内的随机值,当完成一次递归之后缩小这个范围即range*rate连线的时候,将三角形的一个点和这个点的两条边生成的中点相连,最后将三条边的中点相连所以应该有四个递归调用. 代码实现及注解 package Mountion; import java.awt.Graphics; import java.

  • Java递归方法实现山脉绘制

    本文实例为大家分享了Java递归方法实现山脉绘制的具体代码,供大家参考,具体内容如下 一.山脉绘制的思路 给定两个点A(x1,y1),B(x2,y2),递归不断取中点,同时给定一个范围[-range,range]和一个比率rate.每次取中点后,这个中点的纵坐标的值加上这个范围内的随机值,同时通过range=range*rate来缩小这个变化的范围,最后,通过相邻的点连线,绘制成一个山脉的形状. 二.整段代码如下 package com.yf1031; import java.awt.FlowL

  • Java 在PDF中绘制形状的两种方法

    在我们编辑PDF文档的过程中,有时候需要在文档中添加一些如多边形.矩形.椭圆形之类的图形,而Free Spire PDF for Java 则正好可以帮助我们在Java程序中通过代码在PDF文档中绘制形状,以及设置形状边线颜色和填充色. Jar包导入 方法一:下载Free Spire.PDF for Java包并解压缩,然后将lib文件夹下的Spire.Pdf.jar包作为依赖项导入到Java应用程序中 方法二:直接通过Maven仓库安装JAR包,配置pom.xml文件的代码如下: <repos

  • Java 基于Spire.Cloud.SDK for Java在PDF中绘制形状

    Spire.Cloud.SDK for Java提供了pdfPathApi接口可用于在PDF文档中绘制形状(或图形),如绘制线条形状drawLine().绘制矩形形状drawRectanglef(),下面将介绍如何通过Java示例和步骤来实现: 一.导入jar文件.(有2种方式) 创建Maven项目程序,通过maven仓库下载导入.以IDEA为例,新建Maven项目,在pom.xml文件中配置maven仓库路径,并指定spire.cloud.sdk的依赖,如下: <repositories>

  • Java递归方法求5!的实现代码

    题目:利用递归方法求5!. 程序分析:递归公式:fn=fn_1*4! 程序设计: import java.util.Scanner; public class Ex22 { public static void main(String[] args) { Scanner s = new Scanner(System.in); int n = s.nextInt(); Ex22 tfr = new Ex22(); System.out.println(tfr.recursion(n)); } pu

  • java绘制国际象棋与中国象棋棋盘

    JAVA API 中的绘制图形类的paint()方法,我们可以轻松绘制中国象棋与国际象棋的棋盘.详见代码:  一.中国象棋棋盘代码 import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class ChineseChese extends Frame{

  • Java中的递归方法示例介绍

    目录 递归 递归的注意事项: 案例一 递归求阶乘 不使用递归实现阶乘 使用递归实现阶乘 澳大利亚不死神兔(斐波那契数列) 使用数组实现 使用递归实现 总结 递归 方法定义本身调用方法本身的现象叫做递归 在这之前我们学的东西:例如StringBuffer.append().append().append()这个不叫递归.这个叫方法的连续调用Math.max(Math.max(a,b),c)也不是递归,那这些是什么呢?这些是方法的调用. 那什么是递归呢? 举例: 从前有座山,山里有座庙,庙里有个老和

  • java实现飞机大战游戏

    java实现飞机大战 用Java写个飞机大战游戏练习一下,实现可播放游戏背景音乐和游戏的基本功能 设计 1.准备好相应的图片和背景音乐(.wav文件): 2.直接看源码: 3.还有部分功能未实现. 源码 package forGame 加载游戏图片类 package forGame; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.image.BufferedImage; import java.io.Fil

  • java实战之飞机大战小游戏(源码加注释)

    一.工程文件 二.Main.java 主函数,实现类 package ui; //主函数实现 public class Main { public static void main(String[] args) { //创建窗体 GameFrame frame = new GameFrame(); //创建面板 GamePanel panel = new GamePanel(frame); //调用开始游戏的方法启动游戏 panel.action(); //将面板加入到窗体中 frame.add

随机推荐