java实现三角形分形山脉
作者:Benjamin. 发布时间:2023-05-23 23:47:40
本文实例为大家分享了java实现三角形分形山脉的具体代码,供大家参考,具体内容如下
三角形分形山脉原理
原型图
如图,这是三角形分形山脉的一个原型图。首先我们让x1、x2、x3三个点组成的三角形的各条边的中点mid1、mid2、mid3可以在大三角形内部画一个三角形,这时就会有四个小三角形,那么我们对这四个小三角形做同样的操作,如此就可以画出雏形了。接下来我们只需要对内部每个需要连线三角形的y坐标做相关操作就可以了。
效果图
山脉分形之前的问题
重写equals与hasCode方法
重写的原因
就像下面这张图所展示的效果一样,其中出现了一个三角形分形两边的情况,导致下面这张图没有上面的图看上去更有山脉的感觉。
出现这种情况是因为其中一条边的中点向两边波动时,它的两个顶点不同方向连线后留下的大片空白区域导致的(见上图)。所以我们要想办法记录这条边的中点,使它们只记录它的一个中点,这样我们就能解决大片空白区域的问题了。
equals与hasCode
这里我们用到了hashMap,那么就牵涉到hashMap存储的问题。如图,hashMap在存储对象数据时会通过它的hasCode与哈希函数计算该对象的存储位置,如果这个位置没有存储数据,则直接存储这个对象;如果存在有对象,我们则需要比较他们的hasCode来比较他们是否是同一个对象,如果是true已经存在这个对象的情况下,那么我们就不操作,如果是false还没有存入这个对象,我们则在这个存储位置的后面将这个对象链接进来就好了。综上,我们要自己建立一个数据类型来记录这条边的两个点的x、y坐标及波动后中点的y坐标,所以我们要重写equals与hasCode方法。
三角形山脉代码
import java.awt.Color;
import java.awt.Graphics;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javax.swing.JFrame;
public class Recursive extends JFrame{
private int[] xLabel;
private int[] yLabel;
Map<Object, Integer> map = new HashMap<>();
Integer shiftY = 100;
public void drawTri(Graphics g, int x1, int y1, int x2, int y2, int x3, int y3,
int deep, double range) {
xLabel = new int[] {x1, x2, x3};
yLabel = new int[] {y1, y2, y3};
int shiftY1 = 0;
int shiftY2 = 0;
int shiftY3 = 0;
if(deep-- < 0) {
Color color = new Color(43, 43, 41, 233);
g.setColor(color);
g.drawPolygon(xLabel, yLabel, 3);
return;
}
range *= 0.62;
int midX1 = (x1 + x2) / 2;
int midX2 = (x2 + x3) / 2;
int midX3 = (x3 + x1) / 2;
int midY1 = (y1 + y2) / 2;
int midY2 = (y2 + y3) / 2;
int midY3 = (y3 + y1) / 2;
//其中每个点相对应
if(verify(x2, y2, x1, y1)){
shiftY1 = shiftY;
} else{
shiftY1 = shift(midY1,range);
}
if (verify(x3, y3, x2, y2)) {
shiftY2 = shiftY;
} else {
shiftY2 = shift(midY2,range);
}
if(verify(x1, y1, x3, y3)) {
shiftY3 = shiftY;
} else{
shiftY3 = shift(midY3,range);
}
//边对象对应,震荡点
//存入边对象
map.put(new LineObject(x1, y1, x2, y2), shiftY1);
map.put(new LineObject(x2, y2, x3, y3), shiftY2);
map.put(new LineObject(x3, y3, x1, y1), shiftY3);
drawTri(g, x1, y1, midX1, shiftY1, midX3, shiftY3, deep, range); //顶
drawTri(g, midX1, shiftY1, x2, y2, midX2, shiftY2, deep, range); //左
drawTri(g, midX3, shiftY3, midX2, shiftY2, x3, y3, deep, range); //右
drawTri(g, midX2, shiftY2, midX3, shiftY3, midX1, shiftY1, deep, range); //中
}
public int shift(int y, double range) {
return y += (Math.random() * 2 - 1) * range;
}
public boolean verify(int x1, int y1, int x2, int y2) {
LineObject lineObject = new LineObject(x1, y1, x2, y2);
if(map.containsKey(lineObject)){
shiftY = map.get(lineObject);
return true;
}
return false;
}
public void UI() {
this.setTitle("test");
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
this.setSize(1000,1000);
this.setLocationRelativeTo(null);
this.setVisible(true);
Graphics g=this.getGraphics();
RecursiveListener rl=new RecursiveListener();
this.addMouseListener(rl);
rl.g=g;
}
}
class LineObject {
int x1;
int y1;
int x2;
int y2;
public LineObject(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LineObject that = (LineObject) o;
return x1 == that.x1 &&
y1 == that.y1 &&
x2 == that.x2 &&
y2 == that.y2;
}
@Override
public int hashCode() {
return Objects.hash(x1, y1, x2, y2);
}
}
三角形山脉 *
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class TriangleListener implements MouseListener {
int x1, x2, x3, y1, y2, y3;
int count = 0;
Graphics g;
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
g.drawOval(e.getX() - 4, e.getY() - 4, 8, 8);
if (count == 0) {
x1 = e.getX();
y1 = e.getY();
count++;
} else if (count == 1) {
x2 = e.getX();
y2 = e.getY();
count++;
g.drawLine(x1, y1, x2, y2);
} else {
x3 = e.getX();
y3 = e.getY();
g.drawLine(x1, y1, x3, y3);
g.drawLine(x2, y2, x3, y3);
count = 0;
Triangle triangle = new Triangle();
triangle.recursion(x1, y1, x2, y2, x3, y3, g, 9, 800);
}
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
来源:https://blog.csdn.net/qq_44836027/article/details/108081246


猜你喜欢
- 先看看效果图:package wuwang.tools.utils; import java.io.File; import java.io
- Java 最初版本只为常用的数据结构提供了很少的一组类:Vector、Stack、Hashtable、BitSet 与 Enumeratio
- 随着时间的推移现在的软件要求显示的内容越来越多,所以要在小的屏幕上能够更好的显示更多的内容,首先我们会想到底部菜单栏,但是有时候像今日头条新
- 概述在移动应用开发中,消息推送可以说是一项非常重要的功能,它能够起到提醒或者唤醒用户的作用,同时也是产品运营人员更高效地实现运营目标的重要手
- makeCertPic.javapackage pic;import java.awt.Color;import java.awt.Font
- springboot logback动态获取application的配置项在多环境的情况下,logback的日志路径需要进行针对性配置,也就
- 本文实例讲述了Java简单验证身份证功能。分享给大家供大家参考,具体如下:package org.cxy.csdn.example;impo
- 这几天琢磨写一个Android的Runtime用来加速HTML5 Canvas,让GameBuilder+CanTK 不但开发速度快,运行速
- 目录无SpringMVC全局异常时的流程图SpringMVC全局异常流程图其实是一个ModelAndView对象配置文件applicatio
- 本文实例讲述了C#自定义RSA加密解密及RSA签名和验证类。分享给大家供大家参考。具体分析如下:这个C#类自定义RSA加密解密及RSA签名和
- 一、堆的概念堆的定义:n个元素的序列{k1 , k2 , … , kn}称之为堆,当且仅当满足以下条件时:(1)ki
- 前言:什么是多数据源?最常见的单一应用中最多涉及到一个数据库,即是一个数据源(Datasource)。那么顾名思义,多数据源就是在一个单一应
- JPA like 模糊查询 语法格式public List<InstitutionInfo> getAllInstitution
- 前言本篇技术实现主要是运行是代理,不涉及到插桩技术,不引入插件,对业务影响点最小技术难点1. 如何拦截到所有的view的点击事件view有个
- 最近公司项目中有一个类似滴滴出行填写验证码的弹框,下面是我撸出来的效果: 中间的那个输入密码的6个框框其实就是用shape画的背景
- 一、前言系统执行业务逻辑之前,会对输入数据进行校验,检测数据是否有效合法的。所以我们可能会写大量的if else等判断逻辑,特别是在不同方法
- 1.面向接口编程和面向对象编程是什么关系首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是
- 这篇文章主要介绍了Spring MVC处理方法返回值过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- IDEA自定义pom依赖抽离公共代码,代码解耦,减少重复第一步: 抽离公共部分的代码第二步: 点击右侧工具栏的maven,刷新,点击skip
- @SuppressWarnings 注解@SuppressWarnings: 抑制编译器警告如下,可以看到idea中有警告的颜色标注当我们不