OpenGl(jogl)分形算法生成树

来源:互联网 发布:数据分析师证 编辑:程序博客网 时间:2024/04/30 09:04

一,配置环境

1.需要的jar包

这里写图片描述
jar包的下载地址在这里

二,代码

1,GlPoint类

/** * 自定义的点类,存储x和y值 * @author mcl * */public class GlPoint {    /*x坐标*/    float x = 0.00f;    /*y坐标*/    float y = 0.00f;    public GlPoint() {    }    public GlPoint(float x, float y) {        this.x = x;        this.y = y;    }    public float getX() {        return x;    }    public void setX(float x) {        this.x = x;    }    public float getY() {        return y;    }    public void setY(float y) {        this.y = y;    }}

2,TreeAnimation类

import javax.swing.JFrame;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.jogamp.opengl.GL2;import com.jogamp.opengl.GLAutoDrawable;import com.jogamp.opengl.GLCapabilities;import com.jogamp.opengl.GLEventListener;import com.jogamp.opengl.GLProfile;import com.jogamp.opengl.awt.GLCanvas;/** * 实现GLEventListener接口 * @author mcl * */public class TreeAnimation implements GLEventListener{    static final String START_POINT_X = "START_POINT_X";    static final String START_POINT_Y = "START_POINT_Y";    static final String END_POINT_X = "END_POINT_X";    static final String END_POINT_Y = "END_POINT_Y";    double partition = 10.0;    JSONArray jsonArray = new JSONArray();    JSONArray jsonArray1 = new JSONArray();    JSONArray jsonArray2 = new JSONArray();    JSONArray jsonArray3 = new JSONArray();    JSONArray jsonArray4 = new JSONArray();    JSONArray jsonArray5 = new JSONArray();    JSONArray jsonArray6 = new JSONArray();    JSONArray jsonArray7 = new JSONArray();    @Override    public void init(GLAutoDrawable drawable) {        final GL2 gl = drawable.getGL().getGL2();        GlPoint start = new GlPoint(0, -0.70f);        GlPoint end = new GlPoint(0, -0.30f);        int level = 6;        double angle = 35.0 * (Math.PI / 180);        double smallAngle = -10.0 * (Math.PI / 180);        double smallAngle1 = -5.0 * (Math.PI / 180);        double smallAngle2 = 0.0 * (Math.PI / 180);        double smallAngle3 = 5.0 * (Math.PI / 180);        double smallAngle4 = 10.0 * (Math.PI / 180);        double rate = 0.8;        double bottom = -10.0;        jsonArray = createPointsOfTree(12, start, end, angle, rate, smallAngle);        jsonArray1 = createPointsOfTree(12, start, end, angle, rate, smallAngle1);        jsonArray2 = createPointsOfTree(12, start, end, angle, rate, smallAngle2);        jsonArray3 = createPointsOfTree(12, start, end, angle, rate, smallAngle3);        jsonArray4 = createPointsOfTree(12, start, end, angle, rate, smallAngle4);    }   @Override   public void display(GLAutoDrawable drawable) {      final GL2 gl = drawable.getGL().getGL2();      GlPoint start = new GlPoint(0, -1.0f);      GlPoint end = new GlPoint(0, -0.30f);      gl.glBegin (GL2.GL_LINES);//static field 多组双顶点线段      gl.glVertex3f(start.getX(), start.getY(), 1);      gl.glVertex3f(end.getX(), end.getY(), 1);      gl.glEnd();      gl.glClear(GL2.GL_STENCIL_BUFFER_BIT);      drawCenterTree(gl);   }   private void drawRightEndTree(GL2 gl2) {       GL2 gl = gl2;       for (int i = 0; i < jsonArray4.size(); i++) {           JSONObject object = (JSONObject) jsonArray4.get(i);           float startx = object.getFloatValue(START_POINT_X);           float starty = object.getFloatValue(START_POINT_Y);           float endx = object.getFloatValue(END_POINT_X);           float endy = object.getFloatValue(END_POINT_Y);           gl.glBegin (GL2.GL_LINES);//static field 多组双顶点线段           gl.glVertex3f(startx, starty, 1);           gl.glVertex3f(endx, endy, 1);           gl.glEnd();       }   }   private void drawRightTree(GL2 gl2) {       GL2 gl = gl2;       for (int i = 0; i < jsonArray3.size(); i++) {           JSONObject object = (JSONObject) jsonArray3.get(i);           float startx = object.getFloatValue(START_POINT_X);           float starty = object.getFloatValue(START_POINT_Y);           float endx = object.getFloatValue(END_POINT_X);           float endy = object.getFloatValue(END_POINT_Y);           gl.glBegin (GL2.GL_LINES);//static field 多组双顶点线段           gl.glVertex3f(startx, starty, 1);           gl.glVertex3f(endx, endy, 1);           gl.glEnd();       }   }   private void drawCenterTree(GL2 gl2) {       System.out.println("TreeAnimation.drawCenterTree()");       GL2 gl = gl2;       for (int i = 0; i < jsonArray2.size(); i++) {           JSONObject object = (JSONObject) jsonArray2.get(i);           float startx = object.getFloatValue(START_POINT_X);           float starty = object.getFloatValue(START_POINT_Y);           float endx = object.getFloatValue(END_POINT_X);           float endy = object.getFloatValue(END_POINT_Y);           gl.glBegin (GL2.GL_LINES);//static field 多组双顶点线段           gl.glVertex3f(startx, starty, 1);           gl.glVertex3f(endx, endy, 1);           gl.glEnd();       }   }   private void drawLeft2Tree(GL2 gl2) {       GL2 gl = gl2;       for (int i = 0; i < jsonArray1.size(); i++) {       JSONObject object = (JSONObject) jsonArray1.get(i);       float startx = object.getFloatValue(START_POINT_X);       float starty = object.getFloatValue(START_POINT_Y);       float endx = object.getFloatValue(END_POINT_X);       float endy = object.getFloatValue(END_POINT_Y);       gl.glBegin (GL2.GL_LINES);//static field 多组双顶点线段       gl.glVertex3f(startx, starty, 1);       gl.glVertex3f(endx, endy, 1);       gl.glEnd();       }   }   private void drawLeftTree(GL2 gl2) {       GL2 gl = gl2;       for (int i = 0; i < jsonArray.size(); i++) {           JSONObject object = (JSONObject) jsonArray.get(i);           float startx = object.getFloatValue(START_POINT_X);           float starty = object.getFloatValue(START_POINT_Y);           float endx = object.getFloatValue(END_POINT_X);           float endy = object.getFloatValue(END_POINT_Y);           gl.glBegin (GL2.GL_LINES);//static field 多组双顶点线段           gl.glVertex3f(startx, starty, 1);           gl.glVertex3f(endx, endy, 1);           gl.glEnd();       }   }   @Override   public void dispose(GLAutoDrawable arg0) {   }   @Override   public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height ) {   }   public static void main(String[] args) {       //轮廓,剖面,外形      final GLProfile profile = GLProfile.get(GLProfile.GL2);      //性能      GLCapabilities capabilities = new GLCapabilities(profile);      /*The canvas(画布)*/       final GLCanvas glcanvas = new GLCanvas(capabilities);      /*定义一条线*/      TreeAnimation l = new TreeAnimation();      /*设置监听器*/      glcanvas.addGLEventListener(l);      /*设置画布的宽,高*/      glcanvas.setSize(1200, 1200);      /*创建一个框架*/      final JFrame frame = new JFrame ("straight Line");      /*把画布添加到框架中*/      frame.getContentPane().add(glcanvas);      /*优先尺寸*/      frame.setSize(frame.getContentPane().getPreferredSize());      frame.setVisible(true);   }//end of main   /*计算向右偏移之后的向量*/   public static float computeToRightXVector(float xVertor, float yVertor, double tmpSin, double tmpCos, double rate) {       // 计算右边的点       return (float)((xVertor * tmpCos + yVertor * tmpSin) * rate);//11/20   }   /*计算向右偏移之后的y向量*/   public static float computeToRightYVector(float xVertor, float yVertor, double tmpSin, double tmpCos, double rate) {       // 计算右边的点       return (float)((-xVertor * tmpSin + yVertor * tmpCos) * rate);   }   /*计算向左偏移之后的向量*/   public static float computeToLeftXVector(float xVertor, float yVertor, double tmpSin, double tmpCos, double rate) {       // 计算左边的点       return (float)((xVertor * tmpCos - yVertor * tmpSin) * rate);//11/20   }   /*计算向左偏移之后的y向量*/   public static float computeToLeftYVector(float xVertor, float yVertor, double tmpSin, double tmpCos, double rate) {       // 计算左边的点       return (float)((xVertor * tmpSin + yVertor * tmpCos) * rate);   }   public JSONArray createPointsOfTree(int leveltmp,//递归层数           GlPoint fatherStart,//父线段的起始点            GlPoint fatherEnd, //父线段的结束点           double leafAngle, //分支和主干的角度           double rate,//分支占主干的比率           double smallAngle//树每次偏移的角度           ) {       int level = leveltmp;       //计算父向量       float xVertor = fatherEnd.getX() - fatherStart.getX();       float yVertor = fatherEnd.getY() - fatherStart.getY();       //主干偏移的小角度       double mainBodySin = Math.sin(smallAngle);       double mainBodyCos = Math.cos(smallAngle);       //右边偏移的角度       double tmpSin = Math.sin(leafAngle);       double tmpCos = Math.cos(leafAngle);       //计算主干偏移之后的向量       float mainXVertor = computeToRightXVector(xVertor, yVertor, mainBodySin, mainBodyCos, rate);       float mainYVertor = computeToRightYVector(xVertor, yVertor, mainBodySin, mainBodyCos, rate);       GlPoint mainStart = fatherEnd;       GlPoint mainEnd = new GlPoint(fatherEnd.getX() + mainXVertor, fatherEnd.getY() + mainYVertor);       JSONObject mainBody = new JSONObject();       mainBody.put(START_POINT_X,mainStart.getX());       mainBody.put(START_POINT_Y, mainStart.getY());       mainBody.put(END_POINT_X, mainEnd.getX());       mainBody.put(END_POINT_Y, mainEnd.getY());       //计算偏移后,左边枝干的向量       float leftXVector = computeToLeftXVector(mainXVertor, mainYVertor, tmpSin, tmpCos, rate);       float leftYVector = computeToLeftYVector(mainXVertor, mainYVertor, tmpSin, tmpCos, rate);       GlPoint leftStart = fatherEnd;       GlPoint leftEnd = new GlPoint(fatherEnd.getX() + leftXVector, fatherEnd.getY() + leftYVector);       JSONObject leftBody = new JSONObject();       leftBody.put(START_POINT_X,leftStart.getX());       leftBody.put(START_POINT_Y, leftStart.getY());       leftBody.put(END_POINT_X, leftEnd.getX());       leftBody.put(END_POINT_Y, leftEnd.getY());       //计算偏移后,右边的枝干向量       float rightXVector = computeToRightXVector(mainXVertor, mainYVertor, tmpSin, tmpCos, rate);       float rightVector = computeToRightYVector(mainXVertor, mainYVertor, tmpSin, tmpCos, rate);       GlPoint rightStart = fatherEnd;       GlPoint rightEnd = new GlPoint(fatherEnd.getX() + rightXVector, fatherEnd.getY() + rightVector);       JSONObject rightBody = new JSONObject();       rightBody.put(START_POINT_X,rightStart.getX());       rightBody.put(START_POINT_Y, rightStart.getY());       rightBody.put(END_POINT_X, rightEnd.getX());       rightBody.put(END_POINT_Y, rightEnd.getY());       JSONArray result = new JSONArray();       result.add(mainBody);       result.add(leftBody);       result.add(rightBody);       level--;       if (level > 0) {           //主干           JSONArray result1 = createPointsOfTree(level - 1, mainStart, mainEnd, leafAngle, rate, smallAngle);           //左边           JSONArray result2 = createPointsOfTree(level - 1, leftStart, leftEnd, leafAngle, rate, smallAngle);           //右边           JSONArray result3 = createPointsOfTree(level - 1, rightStart, rightEnd, leafAngle, rate, smallAngle);           for (int i = 0; i < result1.size(); i++) {               JSONObject object = (JSONObject) result1.get(i);               result.add(object);           }           for (int i = 0; i < result2.size(); i++) {               JSONObject object = (JSONObject) result2.get(i);               result.add(object);           }           for (int i = 0; i < result3.size(); i++) {               JSONObject object = (JSONObject) result3.get(i);               result.add(object);           }       }       return result;   }}

三、效果图

这就是程序运行之后的效果图,此树还可以向两边偏移,只需要设置一下角度就可以

这就是程序运行之后的效果图,此树还可以向两边偏移,只需要设置一下角度就可以