sfls201803文库吧 关注:581贴子:10,822
  • 6回复贴,共1

【非专业人员慎入】洛伦茨吸引子——使用OpenGL和Java进行绘图

只看楼主收藏回复

看到的帮我叫一下朱奕帆
首先上截图

具体意义请自行上网搜索
使用四阶Runge-Kutta算法求解方程,σ=28,ρ=10,β=8/3,初值[x=10,y=10,z=10]
渲染使用OpenGL的GLSL进行差值着色(从黄到蓝)
绘图代码:
//screen.frag
uniform float max;
varying float f_index;
void main() {
float f=f_index/max;
vec4 mix_a=vec4(f,f,f,0);
gl_FragColor=mix(vec4(1.0,1.0,0.0,0.0),vec4(0.0,0.0,1.0,0.0),mix_a);
}
//screen.vert
uniform float max;
attribute float index;
varying float f_index;
void main() {
gl_Position=ftransform();
f_index=index;
}
//Renderer.java
package free.lolunz;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
public class Renderer {
protected double[][] lolunzValues;
protected int listId;
protected float rot;
protected ShadedRenderer sr;
public Renderer() {
this.lolunzValues=LolunzSolver.solve();
this.rot=0;
}
public void run() {
init();
while(!Display.isCloseRequested()) {
draw();
Display.update();
Display.sync(60);
}
destroy();
}
public void initDisplay() {
try {
Display.setDisplayMode(new DisplayMode(800,800));
Display.setInitialBackground(0.0f, 0.0f, 0.0f);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
Display.setResizable(false);
}
public void init() {
initDisplay();
this.sr=new ShadedRenderer();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(90, 1, 0.05f, 1000f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glEnable(GL11.GL_LINE_SMOOTH);
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
listId=GL11.glGenLists(1);
GL11.glNewList(listId, GL11.GL_COMPILE);
GL11.glBegin(GL11.GL_LINE_STRIP);
GL11.glTranslatef(0.0f,0.0f,-25.0f);
GL11.glColor3f(1.0f, 1.0f, 1.0f);
int loc=sr.getUniformLocation("max");
ARBShaderObjects.glUniform1fARB(loc, lolunzValues.length-1);
int loc2=sr.getAttribLocation("index");
for (int i=0;i<lolunzValues.length;++i) {
ARBVertexShader.glVertexAttrib1fARB(loc2, i);
GL11.glVertex3d(lolunzValues[i][0], lolunzValues[i][1], lolunzValues[i][2]);
}
GL11.glEnd();
GL11.glEndList();
}
public void draw() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
sr.predraw();
GL11.glLoadIdentity();
GL11.glTranslatef(0.0f,0.0f,-50.0f);
GL11.glRotatef(rot,1.0f,1.0f,1.0f);
++rot;
if (rot>360)
rot-=360;
GL11.glCallList(listId);
sr.postdraw();
}
public void destroy() {
Display.destroy();
}
public static void main(String[] args) {
new Renderer().run();
}
}
//ShadedRenderer.java
package free.lolunz;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GL11;
public class ShadedRenderer {
private boolean useShader;
private int program = 0;
public ShadedRenderer() {
int vertShader = 0, fragShader = 0;
try {
vertShader = createShader("shaders/screen.vert",
ARBVertexShader.GL_VERTEX_SHADER_ARB);
fragShader = createShader("shaders/screen.frag",
ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
} catch (Exception exc) {
exc.printStackTrace();
return;
} finally {
if (vertShader == 0 || fragShader == 0)
return;
}
program = ARBShaderObjects.glCreateProgramObjectARB();
if (program == 0)
return;
ARBShaderObjects.glAttachObjectARB(program, vertShader);
ARBShaderObjects.glAttachObjectARB(program, fragShader);
ARBShaderObjects.glLinkProgramARB(program);
if (ARBShaderObjects.glGetObjectParameteriARB(program,
ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) {
System.err.println(getLogInfo(program));
return;
}
ARBShaderObjects.glValidateProgramARB(program);
if (ARBShaderObjects.glGetObjectParameteriARB(program,
ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE) {
System.err.println(getLogInfo(program));
return;
}
useShader = true;
}
public void predraw(){
if(useShader)
ARBShaderObjects.glUseProgramObjectARB(program);
}
public void postdraw() {
if(useShader)
ARBShaderObjects.glUseProgramObjectARB(0);
}
public int getUniformLocation(String name) {
if (useShader) {
return ARBShaderObjects.glGetUniformLocationARB(program, name);
}
return 0;
}
public int getAttribLocation(String name) {
if (useShader) {
return ARBVertexShader.glGetAttribLocationARB(program, name);
}
return 0;
}
private int createShader(String filename, int shaderType) throws Exception {
int shader = 0;
try {
shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType);
if (shader == 0)
return 0;
ARBShaderObjects.glShaderSourceARB(shader,
readFileAsString(filename));
ARBShaderObjects.glCompileShaderARB(shader);
if (ARBShaderObjects.glGetObjectParameteriARB(shader,
ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE)
throw new RuntimeException("Error creating shader: "
+ getLogInfo(shader));
return shader;
} catch (Exception exc) {
ARBShaderObjects.glDeleteObjectARB(shader);
throw exc;
}
}
private static String getLogInfo(int obj) {
return ARBShaderObjects.glGetInfoLogARB(obj, ARBShaderObjects
.glGetObjectParameteriARB(obj,
ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB));
}
private String readFileAsString(String filename) throws Exception {
StringBuilder source = new StringBuilder();
FileInputStream in = new FileInputStream(filename);
Exception exception = null;
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
Exception innerExc = null;
try {
String line;
while ((line = reader.readLine()) != null)
source.append(line).append('\n');
} catch (Exception exc) {
exception = exc;
} finally {
try {
reader.close();
} catch (Exception exc) {
if (innerExc == null)
innerExc = exc;
else
exc.printStackTrace();
}
}
if (innerExc != null)
throw innerExc;
} catch (Exception exc) {
exception = exc;
} finally {
try {
in.close();
} catch (Exception exc) {
if (exception == null)
exception = exc;
else
exc.printStackTrace();
}
if (exception != null)
throw exception;
}
return source.toString();
}
}
求解代码:
//RungeKutta.java
package free.lolunz;
public class RungeKutta {
public static final double[][] solve(Function func,double tbegin,double tend,double [] y0) {
final int steps=5000;
final double step=(tend-tbegin)/(double)steps;
double[][] ans=new double[steps+1][y0.length];
addTo(ans[0],y0);
for (int i=0;i<steps;++i) {
double[] k1=func.f(tbegin+step*i, ans[i]);
double[] k2=func.f(tbegin+step*i+step/2, add(ans[i],multiply(k1,step/2)));
double[] k3=func.f(tbegin+step*i+step/2, add(ans[i],multiply(k2,step/2)));
double[] k4=func.f(tbegin+step*i+step, add(ans[i],multiply(k3,step)));
multiplyTo(k2,2);
multiplyTo(k3,2);
double[] tmp=addAll(k1,k2,k3,k4);
ans[i+1]=add(ans[i],multiply(tmp,step/6));
}
return ans;
}
private static final double[] addTo(double[] dst,double[] src) {
if (dst==null||src==null||dst.length!=src.length)
return dst;
for (int i=0;i<src.length;++i)
dst[i]+=src[i];
return dst;
}
private static final double[] add(double[] a,double[] b) {
if (a==null||b==null||a.length!=b.length)
return null;
double[] ans=new double[a.length];
for (int i=0;i<a.length;++i)
ans[i]=a[i]+b[i];
return ans;
}
private static final double[] multiply(double[] src,double n) {
if (src==null)
return null;
double[] ans=new double[src.length];
for (int i=0;i<src.length;++i)
ans[i]=n*src[i];
return ans;
}
private static final double[] addAll(double[]... arrays) {
double[] ans=new double[arrays[0].length];
for (int i=0;i<ans.length;++i)
for (int j=0;j<arrays.length;++j)
ans[i]+=arrays[j][i];
return ans;
}
private static final double[] multiplyTo(double[] src,double n) {
for (int i=0;i<src.length;++i)
src[i]*=n;
return src;
}
}
//Function.java
package free.lolunz;
public interface Function {
public double[] f(double t,double[] y);
}
//Lolunz,java


IP属地:浙江1楼2015-03-22 16:30回复
    //Lolunz.java
    package free.lolunz;
    public class Lolunz implements Function{
    @Override
    public double[] f(double t, double[] p) {
    final double sigma=10;
    final double rho=28;
    final double beta=(double)8/3;
    double x=p[0];
    double y=p[1];
    double z=p[2];
    double dx=sigma*(y-x);
    double dy=x*(rho-z)-y;
    double dz=x*y-beta*z;
    return new double[]{dx,dy,dz};
    }
    }
    //LolunzSolver.java
    package free.lolunz;
    public class LolunzSolver {
    public static double[][] solve() {
    Function lolunz=new Lolunz();
    double[] y0=new double[]{10,10,10};
    double tbegin=0;
    double tend=50;
    return RungeKutta.solve(lolunz, tbegin, tend, y0);
    }
    }
    工程中带有LWJGL的JavaOpengl实现包,具体内容见一下链接:


    IP属地:浙江2楼2015-03-22 16:32
    收起回复
      啊!五环!你比四环多一环


      3楼2015-03-22 19:56
      回复
        我已对三级缓存过敏


        来自Android客户端4楼2015-03-22 22:20
        收起回复