Use JLink to read from Mathematica

From JReality Wiki
Revision as of 09:18, 26 March 2012 by Andre (Talk | contribs)

(diff) ←Older revision | view current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

Source file: JLinkExample

Source file: torus.m


This example shows how to use the JLink package of Mathematica as a data source for a jReality scene graph.


A good introduction to using JLink as done here, is given in this document which isn't so easy to find on the JLink homepage.


Before proceeding, you need to have the following to run this example:

  • A license for Mathematica version 4.2 or later, and
  • JLink version 3.1:
    • The following folder must exist in your Mathematica installation: AddOns/JLInk and
    • the file ReleaseNotes.html should show a version 3.1+. (Earlier versions may work but have not been tested).

You can also download the latest version of JLink here.


Once you have verified that you have fulfilled these conditions, add JLink.jar to your classpath, and the location of the appropriate native library to JAVA_LIBRARY_PATH or use the -Djava.library.path option to the Java VM to do so.


You'll also need to edit two strings at the top of the source code to correspond to the configuration of your file system.

  • Edit the location of your Mathematica kernel, and
  • Edit the location of your jReality workspace.


Once that's all done, you can run the example. It first executes some simple operations to show some different ways that you can communicate with the Mathematica kernel. Then, it instructs the kernel to import the Mathematica package defining a torus surface:

    ml.evaluate("<<"+workspace+mmaFile); 
    ml.discardAnswer();


Here's the content of torus.m, which will be invoked via JLink:

torus[r_, R_, n_, m_] := Block[{du = 2 Pi / n, dv = 2 Pi/m},
    Table[ {Cos[u]*(R+r Sin[v]), 
    r*Cos[v],Sin[u] * (R+r Sin[v])}, 
    {u, 0, 2 Pi, du}, 
    {v,0,2  Pi, dv}]]


The real work is done in the method updateTorusFromMma(). The main steps:

  • Construct a string representing the Mathematica command to be evaluated.
  • Evaluate the command.
  • Wait for the answer.
  • Check that the answer (a Mathematica expression) is a three dimensional array.
  • Read the contents of the expression out into a java double[][][] array.
  • Use this Java array to set the vertices of a quad mesh factory.
  • Update the factory.


    private void updateTorusFromMma(){
        String command = String.format("torus[%g, %g, %d, %d]", r, R, m, n);
        System.err.println("command = "+command);
        try {
            ml.evaluate(command);
           ml.waitForAnswer();
 
            Expr expr = ml.getExpr();
             int[] dimn = expr.dimensions();
 
             int[] part = { 0, 0, 0 };
            double[][][] mesh = new double[dimn[0]][dimn[1]][dimn[2]];
            for (int i = 0; i < dimn[0]; ++i) {
                part[0] = i + 1;
                for (int j = 0; j < dimn[1]; ++j) {
                    part[1] = j + 1;
                    for (int k = 0; k < dimn[2]; ++k) {
                        part[2] = k + 1;
                        mesh[i][j][k] = expr.part(part).asDouble();
                    }
                }
            }
            qmf.setVLineCount(dimn[0]);
            qmf.setULineCount(dimn[1]);
            qmf.setVertexCoordinates(mesh);
             qmf.update();
        } catch (MathLinkException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExprFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
Previous: Explore noneuclidean geometry Developer Tutorial: Contents Next: Use jReality with jruby