欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenGl(jogl)分形算法生成树

程序员文章站 2023-12-27 14:08:15
...

一,配置环境

1.需要的jar包

OpenGl(jogl)分形算法生成树
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;
   }

}

三、效果图

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

OpenGl(jogl)分形算法生成树

上一篇:

下一篇: