java實現(xiàn)三角形分形山脈
本文實例為大家分享了java實現(xiàn)三角形分形山脈的具體代碼,供大家參考,具體內(nèi)容如下
三角形分形山脈原理
原型圖
如圖,這是三角形分形山脈的一個原型圖。首先我們讓x1、x2、x3三個點組成的三角形的各條邊的中點mid1、mid2、mid3可以在大三角形內(nèi)部畫一個三角形,這時就會有四個小三角形,那么我們對這四個小三角形做同樣的操作,如此就可以畫出雛形了。接下來我們只需要對內(nèi)部每個需要連線三角形的y坐標做相關(guān)操作就可以了。
效果圖
山脈分形之前的問題
重寫equals與hasCode方法
重寫的原因
就像下面這張圖所展示的效果一樣,其中出現(xiàn)了一個三角形分形兩邊的情況,導致下面這張圖沒有上面的圖看上去更有山脈的感覺。
出現(xiàn)這種情況是因為其中一條邊的中點向兩邊波動時,它的兩個頂點不同方向連線后留下的大片空白區(qū)域?qū)е碌模ㄒ娚蠄D)。所以我們要想辦法記錄這條邊的中點,使它們只記錄它的一個中點,這樣我們就能解決大片空白區(qū)域的問題了。
equals與hasCode
這里我們用到了hashMap,那么就牽涉到hashMap存儲的問題。如圖,hashMap在存儲對象數(shù)據(jù)時會通過它的hasCode與哈希函數(shù)計算該對象的存儲位置,如果這個位置沒有存儲數(shù)據(jù),則直接存儲這個對象;如果存在有對象,我們則需要比較他們的hasCode來比較他們是否是同一個對象,如果是true已經(jīng)存在這個對象的情況下,那么我們就不操作,如果是false還沒有存入這個對象,我們則在這個存儲位置的后面將這個對象鏈接進來就好了。綜上,我們要自己建立一個數(shù)據(jù)類型來記錄這條邊的兩個點的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; ? ? ? ? //其中每個點相對應(yīng) ? ? ? ? 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); ? ? ? ? } ? ? ? ? ? ? //邊對象對應(yīng),震蕩點 ? ? ? ? ? ? //存入邊對象 ? ? ? ? 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); ? ? } }
三角形山脈監(jiān)聽器
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 ?? ?} }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springboot全局配置文件與多環(huán)境配置的全過程
SpringBoot項目在多環(huán)境配置上表現(xiàn)的非常優(yōu)秀,只需要非常簡單的操作就可以完成配置,下面這篇文章主要給大家介紹了關(guān)于springboot全局配置文件與多環(huán)境配置的相關(guān)資料,需要的朋友可以參考下2021-12-12如何在 Linux 上搭建 java 部署環(huán)境(安裝jdk/tomcat/mys
這篇文章主要介紹了如何在 Linux 上搭建 java 部署環(huán)境(安裝jdk/tomcat/mysql) + 將程序部署到云服務(wù)器上的操作),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01Jackson 反序列化時實現(xiàn)大小寫不敏感設(shè)置
這篇文章主要介紹了Jackson 反序列化時實現(xiàn)大小寫不敏感設(shè)置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06Feign遠程調(diào)用Multipartfile參數(shù)處理
這篇文章主要介紹了Feign遠程調(diào)用Multipartfile參數(shù)處理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03