您的位置:首页 > 运维架构

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;
}

}


三、效果图

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: