OpenGl(jogl)分形算法生成树
2017-06-24 14:21
375 查看
一,配置环境
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; } }
三、效果图
这就是程序运行之后的效果图,此树还可以向两边偏移,只需要设置一下角度就可以相关文章推荐
- 用opengl生成螺旋线算法
- OpenGL入门2——曲线生成算法
- 基于OpenGL的三种直线生成算法
- 最简单的分形图像生成算法
- 【OpenGL】中点圆、椭圆生成算法
- 【OpenGL】直线生成算法DDA+Bresenham
- OpenGL 4.0 GLSL 用 shadow map 算法 生成阴影
- 最简单的分形图像生成算法
- 计算机图形学(二)输出图元_6_OpenGL曲线函数_3_椭圆生成算法
- 基于OpenGL的三种直线生成算法
- 计算机图形学(二)输出图元_6_OpenGL曲线函数_1_圆生成算法
- TopCoder 算法比赛图论实战1—最小生成树问题
- 圆的生成算法
- 一个排列、组合的生成算法 [zz]
- 一个排列、组合的生成算法
- 数独游戏的生成算法
- .NET平台下带权限控制的TreeView控件节点生成算法
- 基础算法测试——生成一个1-10之间的随机整数组合
- 计算机图形学—DDA直线生成算法
- [Visual Basic]源代码推荐:vb的GUID生成算法