java实现三角形分形山脉
程序员文章站
2022-06-24 18:22:14
本文实例为大家分享了java实现三角形分形山脉的具体代码,供大家参考,具体内容如下三角形分形山脉原理原型图如图,这是三角形分形山脉的一个原型图。首先我们让x1、x2、x3三个点组成的三角形的各条边的中...
本文实例为大家分享了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 } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。