前期准备

在上次的博客中,我们已经用java了解并制作了画图板,可以在上面添加绘制椭圆、曲线、填充、改变颜色等功能,在之后的版本中会进行修改。
    今天要做的是通过递归的方式绘制山脉。

具体步骤

1、窗体的设计

这一部分没有什么需要具体描述的,步骤按照前一个博客中的进行设计就好。需要注意的是窗体背景的设置需要用到Panel组件,直接set是没有用的。

public class background {public void showbg() {JFrame bg = new JFrame();// 设置窗体基本属性bg.setTitle("地球平原");bg.setSize(800, 600);bg.setLocationRelativeTo(null);// 窗体关闭时结束程序bg.setDefaultCloseOperation(bg.EXIT_ON_CLOSE);// 设置背景颜色,直接设置没有用,需要用Panel组件Color bgcolor = new Color(255, 255, 255);bg.getContentPane().setBackground(bgcolor);// 设置布局,放在可见前才显示FlowLayout flow = new FlowLayout();bg.setLayout(flow);// 设置可见,并获取画布对象bg.setVisible(true);Graphics g = bg.getGraphics();// 设置鼠标监听器MouseListener mouselistener = new MouseListener();bg.addMouseListener(mouselistener);}public static void main(String args[]) {background bg = new background();bg.showbg();}
}

2、山脉的绘制

这部分是整个绘制的重点,比较考验递归的思维。

  • 大致思路是取一条水平横线,计算横线两个端点(记为P,Q)的中点M’,将中点向上或者向下平移一段距离,得到新的点M。
    ----将P和M两点作为新的端点重复上述过程
    ----将M和Q两点也作为新的端点重复上述过程
    最终将所得的所有点连起来,这样我们就会得到一条折线,只要对变化时的参数进行控制,就会呈现山脉的效果。
  • 整个的迭代过程类似于一个满二叉树。times为二叉树的总层数,timescounter为这一次调用函数时所在的那一层。
        public void showmt(double startx, double starty, double endx, double endy, Color mtcolor, double range, double timescounter) {double midx, midy;//计算中点坐标midx = (startx + endx) / 2;midy = (starty + endy) / 2 + (Math.random() * 2 - 1)/*正负号*/ * range;if (timescounter++ == times) {//画山脉轮廓g.drawLine((int) startx, (int) starty, (int) midx, (int) midy);g.drawLine((int) midx, (int) midy, (int) endx, (int) endy);} else {//随着相邻两个点的横坐标距离减少,纵坐标随机起伏范围也要减小range *= rate;//递归showmt(startx, starty, midx, midy, mtcolor, range, timescounter);showmt(midx, midy, endx, endy, mtcolor, range, timescounter);}}

如果我们对变换时的参数不加控制,就会使得画出的直线类似于噪声的声波,杂乱无章。要画出比较像山脉的图案:

  • 首先,要设置中点上下偏移的范围range,保证不会出现山峰过高或过矮
  • 其次,为了使得山脉更平滑,加入了参数rate∈(0,1),随着timescounter的增加,range*=rate,相邻两点间的高度起伏就不会太大,否则就会如下图所示
  • 最后timescounter对于每一次函数调用来说都是唯一且独立的,所以一定要放在参数中传入,使得其他函数的调用不会影响到这次函数调用的timescounter。times的值不要太小,会没有山脉的感觉;也不要太大,计算机会处理的很慢。(关于提升绘画速度的会在下一次博客中提到)

3、添加监听器

public class MouseListener implements java.awt.event.MouseListener, ActionListener {Graphics g;public void setGraphics(Graphics g) {this.g = g;}public void mouseClicked(MouseEvent e) {//绘制山脉mountain mountain = new mountain();mountain.setGraphics(g);//此处为伪代码,颜色和位置根据需要修改Color mtcolor = new Color( ,,);mountain.showmt(0, starty, 800, endy, mtcolor, 100, 1);// showmt(double startx, double starty, double endx, double endy, Color mtcolor, double range, double timescounter)}}public void mousePressed(MouseEvent e) {}public void mouseReleased(MouseEvent e) {}public void mouseEntered(MouseEvent e) {}public void mouseExited(MouseEvent e) {}public void actionPerformed(ActionEvent e) { }}

运行结果

最终画出来应该是这样的轮廓

武汉加油!中国加油!

下集预告

只有轮廓?
    一座山没感觉?
    递归次数多了画图太慢?
    且听下回分解。
    链接:java画图板之平面山水画(二)(附源码)

java画图板之平面山水画(一)相关推荐

  1. java画图板之平面山水画(二)

    java画图板之平面山水画(一):https://blog.csdn.net/qq_43348021/article/details/104346805 上次的博客中已经将山脉的轮廓画出来了,这次我们 ...

  2. JAVA画图板01 —— 窗体的实现

    画图板 界面开发: 创建窗体对象 完善界面 个人将自制的JAVA画图板分为了三个模块,分别是界面.监听器以及画笔,这一章来介绍界面的相关代码. 界面开发: 创建窗体对象 首先需要创建一个窗体对象.JF ...

  3. java画图板代码_java学习小总结——画图板制做(附代码)

    学习java这门编程语言也有一个多月了.~若是能用本身学的编程语言去开发一些小程序软件能够说是本身一直求之不得吧!.模仿XP的画图板的开发则是学java来最先作的一个小软件.也是把以前学到的不少知识得 ...

  4. 一个Java画图板程序的设计

    本文讲述一个画图板应用程序的设计,屏幕抓图如下.这篇文章带有三个附件,其中两个jar文件都是j2sdk1.4.2_08编译打包,包含源代码,可执行,如下表: 附件名称及链接 详情 jDraw_basi ...

  5. Java 画图板用随机数搞“混沌游戏”

    今晚做了这样的一个任务:用随机数在画图板里面生成四个点,然后选出其中的三个点组成一个三角形,把三角形的三个顶点标为1.2.3,另一个点标为4,把4点随机与1.2.3三个点中一个点进行连接,取连线的中点 ...

  6. Java画图板界面上的添加

    步骤 1.创建类来实现接口(动作监听器和鼠标监听器) 2.在按钮上添加动作监听器,通过e.getActioncommand(),来得到按钮上的字,通过button =(JButton)e.getAct ...

  7. Java画图板的简单实现。(重绘,多边形,曲线画笔,画图片)

    思路: ①画图板的界面 ②创建监听器类 ③给按钮加上鼠标监听 ③画图版的重绘 第一部分:界面类 ①画图板的界面 ③给按钮加上鼠标监听 public class SampleDraw extends J ...

  8. java 画图板源代码_非常值得学习的java 绘图板源代码

    package minidrawpad; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; impor ...

  9. java 画图板 锯齿_java绘画中的锯齿问题

    java给图中的锯齿问题也称作呈现兼容性问题 JDK(tm)1.1呈现模型是基于像素给的模型,该模型的坐标无限细分,且位于像素之间.使用一个一像素宽的画笔执行绘制操作,填充路径锚点向下和向右的像素.J ...

最新文章

  1. linux的mysql修改用户密码与忘记密码的方法
  2. Sublime Text 3 安装及插件推荐
  3. 实例24:python
  4. mysql 导入 mssql_MySQL(csv,text)导入mssql使用方法
  5. amd显卡更新最新驱动鼠标顿卡的解决方法
  6. python语法错误怎么办_python错误处理详解
  7. 放弃 VSCode,再次选择使用十年之久的 Emacs
  8. Hooks解决了什么问题?
  9. C语言学习系列(六)存储类
  10. Hierarchical Softmax、CBOW词带模型抽象化及其公式推理以及python代码实现包括注释
  11. PHP 数组常用操作函数随记
  12. Windows下CodeLite支持中文的正确设置方法
  13. 数据分析模型 第六章
  14. 机器学习-分类-线性分类器
  15. R中常用统计指标含义
  16. n个元素进栈,有几种出栈方式
  17. centos7使用救援模式备份数据
  18. 矩阵顺时针旋转90°、180°、270°
  19. srtruct input_event学习
  20. 发那科机器人请关闭电源_发那科FANUC机器人报警处理(中文)

热门文章

  1. 17岁少年捅死想要性侵女友的歹徒:我坐牢,也不能让她受伤
  2. AES解密失败 WxMaCryptUtils.decrypt(sessionKey,encryptedData, iv)
  3. 关于python程序格式框架以下选项中描述错误的是_关于Python程序格式框架的描述,以下选项中错误的是...
  4. 8.8 json和文件操作
  5. 返还delegation
  6. hello.c的一生
  7. Python今日编程——判断水仙花数然后求水仙花数
  8. vue2升级到 Vue3的异同(入门须知)
  9. PHP对接国际验证码接口DEMO示例
  10. Windows8 安装Vs2008 报错的解决方法