## Saturday, March 31, 2007

### Plotting 3D functions with Groovy and Java3D

In this post I'm going to show a little demo that plots 3D functions by using Groovy and Java3D.

For this demo I'm going to use the Java3D builder created for previous posts.

The TriangleArray class will be used to create the grid to plot the function . Two triangles will be create for each set of 4 points. For future posts I'm going to try to change this to support TriangleStripArray or QuadArray.

In order to create each coordinate of the plane, a function that maps between the iteration number and the real coordinate to be plotted is required. In order to do this the createMapFunc was created, this function returns a function that maps between two coordinates.

Closure createMapFunc(int x1,int x2,double y1,double y2) { double m = (y2 - y1)/(x2 - x1); double b = y1 - m*x1; return { x -> m*x + b}}Closure createFloatMapFunc(int x1,int x2,double y1,double y2) { Closure f = createMapFunc(x1,x2,y1,y2); return { (float)f(it)};}

Given this we can now create the TriangleArray data required to plot the function:

Geometry createGeometry(Closure f,double min,double max,int gridSize) { Closure fInter = createFloatMapFunc(0,gridSize-1,min,max); TriangleArray ta = new TriangleArray(((gridSize-1)**2)*6, TriangleArray.COORDINATES |TriangleArray.NORMALS ); int idx = 0; float x,y,z; for ( iY in (0..(gridSize-2))) { for( iX in (0..(gridSize-2))) { // First triangle x = fInter(iX); y = fInter(iY); z = (float) f(x,y); ta.setCoordinate(idx,new Point3f(x,y,z)); x = fInter(iX+1); y = fInter(iY); z = (float) f(x,y); ta.setCoordinate(idx+1,new Point3f(x,y,z)); x = fInter(iX); y = fInter(iY+1); z = (float) f(x,y); ta.setCoordinate(idx+2,new Point3f(x,y,z)); idx += 3; // Second triangle x = fInter(iX+1); y = fInter(iY); z = (float) f(x,y); ta.setCoordinate(idx,new Point3f(x,y,z)); x = fInter(iX+1); y = fInter(iY+1); z = (float) f(x,y); ta.setCoordinate(idx+1,new Point3f(x,y,z)); x = fInter(iX); y = fInter(iY+1); z = (float) f(x,y); ta.setCoordinate(idx+2,new Point3f(x,y,z)); idx += 3; } } return ta;}

The function to be plotted is a parameter to the createGeometry function.

For this example the following function will be used:

def f = { x,y -> Math.cos(x+y)*Math.sin(x-y)}

Now that we have the code to generate the 3D function geometry we can create the Java3D/Swing required elements by using the Swing, Java3D and SimpleUniverse builders.

SwingBuilder sb = new SwingBuilder();SimpleUniverseBuilder sub = new SimpleUniverseBuilder();Java3dBuilder jb = new Java3dBuilder();         JFrame aFrame = sb.frame(title:"Function",size:[500,500]){    panel(layout: new FlowLayout()) {        thePanel = panel(preferredSize:[500,500],                         layout:new BorderLayout())            } }SimpleUniverse univ =     sub.simpleUniverse() {         viewingPlatform(nominalViewingTransform:true) {            orbitBehavior(                          flags:OrbitBehavior.REVERSE_ALL,                          bounds:new BoundingSphere(                                            new Point3d(0.0,0.0,0.0),                                             100.0))         }         viewer() {           view(minFrameCycleTime:5)                          }    }thePanel.add(univ.getCanvas(),BorderLayout.CENTER);BranchGroup bg =     jb.branchGroup() {         transformGroup(               capability:                       TransformGroup.ALLOW_TRANSFORM_WRITE) {        shape3d(geometry:createGeometry(f,-2.5,2.5,20),                 appearance:polyAppearance())    }}bg.compile();univ.addBranchGraph(bg);aFrame.show()

The result of running the program looks like this: As a last detail, the appearance of the surface is created with the createPolyAppearance function:

Appearance polyAppearance() {    Appearance app = new Appearance();    PolygonAttributes pa = new PolygonAttributes();    pa.setPolygonMode(PolygonAttributes.POLYGON_LINE);    app.setPolygonAttributes(pa);    return app;}

Code for this experiment can be found here.

In future posts I'm going to try to add more features, like materials applied to the surface geometry, axis lines, etc.

## Tuesday, March 27, 2007

### Formating Fortress code with Fortify

A couple of days ago I noticed that a new tool to generate LaTeX code from Fortress source code was available. The tool is called Fortify can be found in the same page where the reference implementation is located.

In this post I'm going to try to create a little example and run Fortify to see the output of the generated LaTeX document.

One of the interesting things about Fortress is that, the language will have an alternative syntax that uses a lot of graphical symbols that will make a Fortress program look like a mathematical document.

For this test I took my old Numerical Analysis book and copied the Newton Raphson algorithm.

The program looks like this:

component Testexport Executablenr(approx:RR64,f : RR64 -> RR64, f' : RR64 -> RR64, N : Number,tol : RR64) = do i:Number := 1 p:RR64 := 0 p0:RR64 := approx ready:Boolean := false while(i <= N AND NOT ready) do p := p0 - f(p0)/f'(p0) if |p - p0| < tol then ready := true end i := i + 1 p0 := p end pendmyF(x) = cos(x) - xmyF'(x) = - sin(x) - 1run(a:String...) = print nr(1.5,myF,myF',10,0.0001)end

Fortify is a tool that works inside Emacs. So I loaded fortify inside Emacs:

(load "..../fortify.el")

Then loaded Fortify by calling M-x fortify.

Selected the code: And pressed M-&, then LaTeX code is generated. To the generated code I added the LaTeX document declaration elements and imported a macros file included with Fortify.

\documentclass{article}\usepackage{url, amssymb, amsmath, amsthm, stmaryrd, xspace}\usepackage{amsfonts, graphicx, fullpage, times, hyperref}\input ../fortify/fortify-macros\begin{document}....\end{document}

After running LaTeX the code looks like this: ## Thursday, March 15, 2007

### An implementation of 'du -s *' in Powershell

While reading about Powershell I noticed that there's no out-of-the-box way(that I know of) to do something similar to 'du -s *' in Unix/Linux. In this post I'm going to show how to implement a similar functionality.

The -s option of the du is used to show only a the total size each argument. This is very useful when trying to determine which directories or files are taking too much space. For example:

$cd /cygdrive/c/Python25/$ du -bs *4794012 DLLs4160038 Doc13817   LICENSE.txt13752327        Lib88573   NEWS.txt56691   README.txt547784  Tools382592  include948600  libs24064   python.exe24576   pythonw.exe3248808 tcl4608    w9xpopen.exe

For better results the output could be combined with sort.

$du -bs * | sort -n4608 w9xpopen.exe13817 LICENSE.txt24064 python.exe24576 pythonw.exe56691 README.txt88573 NEWS.txt382592 include547784 Tools948600 libs3248808 tcl4160038 Doc4794012 DLLs13752327 Lib In order to implement this in Powershell (with the little knowledge I have from it) I wanted to implement the following strategy 1. get all the child elements from the base directory 2. for each element get the total size 3. generate a tuple with the element name and the total size In order to implement #1 a common get-childitem command was used. To implement #2, a combination of foreach-object + get-childitem -r + measure-object was used. And finally for #3 the select-object command was used. One implementation for this functionality is the following: function directory-summary($dir=".") {   get-childitem $dir | % {$f = $_ ; get-childitem -r$_.FullName |            measure-object -property length -sum |              select @{Name="Name";Expression={\$f}},Sum}
}

Running this command in the same directory shows:

PS C:\Python25> directory-summaryName                  Sum----                  ---DLLs              4794012Doc               4160038include            382592Lib              13752327libs               948600tcl               3248808Tools              547784LICENSE.txt         13817NEWS.txt            88573python.exe          24064pythonw.exe         24576README.txt          56691w9xpopen.exe         4608

We can also sort the results:

PS C:\Python25> directory-summary | sort sumName                  Sum----                  ---w9xpopen.exe         4608LICENSE.txt         13817python.exe          24064pythonw.exe         24576README.txt          56691NEWS.txt            88573include            382592Tools              547784libs               948600tcl               3248808Doc               4160038DLLs              4794012Lib              13752327

Maybe there's a shorter/better way to implement this, however it was very interesting and fun to learn a little bit more about Powershell while trying to solve this.

## Thursday, March 8, 2007

### More Java3D and Groovy Builders

In the previous post, a basic Builder for Java3D was shown. For this post I've decided to take one another example from the Java3D distribution and try to implement the scene creation code by using the builder. Also I've received nice suggestions that and I'm going to implement.

The example that I'm going to use is SphereMotion.java which is a nice demonstration of spheres, animation and lights.

The scene creation code of this example can be found in the createSceneGraph method of the SphereMotion class in SphereMotion.java. I'm not going to show the code in this post.

This example contains the following elements:

1. Uses the Background class to set the background color.

2. Creates a big Sphere which is the central element of the scene

3. Conditionally creates a PointLight, DirectionalLight or SpotLight for the Sphere illumination.

4. Uses a PositionInterpolator and RotationInterpolator to perform an animations

5. Uses AmbientLight for general scene illumination.

Helpers for Background, Sphere, PointLight, DirectionalLight, SpotLight, PositionInterpolator and AmbientLight were created.

According to the suggestions, we can use Groovy array literals to specify attribute values that require classes. For example instead of using "alpha: new Alpha(-1,4000)" use "alpha: [-1,4000]". This makes the code more readable.

The flexibility of having the control over attribute and element creation let's you support many ways of doing the same thing. For example, I wanted to allow the "position" attribute of the PointLight class to be specified as an instance of the Point3f class(for example "position:new Point(0.0f,0.0f,0.0f)) or as an array of three elements (for example "position:[0.0f, 0.0f, 0.0f]"). To implement this in the builder, the PointLightHelper code for the position attribute looks like this:

public class PointLightHelper extends LightHelper  {    protected void applyAttributes(Node aNode,                                  Map attributes) {    super.applyAttributes(aNode, attributes);    PointLight pl = (PointLight)aNode;        // Check the position attribute    if (attributes.get("position") != null) {        Object value = attributes.get("position");        if (AttributeHelper.isArrayList3fTuple(value)) {                            pl.setPosition(                AttributeHelper.arrayListToPoint3f(                       (ArrayList)value));        } else        if (value instanceof Point3f) {                            pl.setPosition((Point3f)value);        }                }        ...

where
 public static Point3f arrayListToPoint3f(ArrayList a) {  Vector3f result;          return     new Point3f(       ((Number)a.get(0)).floatValue(),       ((Number)a.get(1)).floatValue(),       ((Number)a.get(2)).floatValue()); } public static boolean isArrayList3fTuple(Object value) {     boolean result = false;     if (value instanceof ArrayList &&       ((ArrayList)value).size() == 3 ) {       ArrayList a = ((ArrayList)value);       result =               a.get(0) instanceof Number &&               a.get(1) instanceof Number &&               a.get(2) instanceof Number;     }     return result; }

The TransformGroupHelper class was also modified so more specific transformations can be specified. For example a I wanted to create a transform group to rotate on Y axis only. To solve this an attribute rotY(and rotX and rotZ) was created to support this directly on the TransformGroupHelper. This attribute was implemented as:

if (key.matches("rot(X|Y|Z)") &&     ((value instanceof Number) )) {        double dValue = ((Number)value).doubleValue();        Transform3D theRotationTransform =            new Transform3D();    tg.getTransform(theRotationTransform);                switch(Character.toUpperCase(              key.charAt(key.length() - 1))) {        case 'X':            theRotationTransform.rotX(dValue);            break;        case 'Y':            theRotationTransform.rotY(dValue);            break;        case 'Z':            theRotationTransform.rotZ(dValue);            break;    }                                    tg.setTransform(theRotationTransform);}

Once having the helpers for the new elements implemented, the only thing missing to resolve was to translate the scene creation code to the builder. One of the major issues was the creation of the Light object. In the original code, the Light was created like this:

  switch (lightType) {   case DIRECTIONAL_LIGHT:      lgt1 = new DirectionalLight(lColor1, lDirect1);      lgt2 = new DirectionalLight(lColor2, lDirect2);      break;   case POINT_LIGHT:      lgt1 = new PointLight(lColor1, lPoint, atten);      lgt2 = new PointLight(lColor2, lPoint, atten);      break;   case SPOT_LIGHT:      lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1,         25.0f * (float)Math.PI / 180.0f, 10.0f);      lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2,         25.0f * (float)Math.PI / 180.0f, 10.0f);      break;  }...l1Trans.addChild(lgt1);l2Trans.addChild(lgt2);

This means that the creation of the instance of the desired light is a parameter of the program. Also another issue was that two lights were created and different parents are assigned to each one. In order to support this we split the creation of both lights into two different switch statements.

The final code for the creation of this scene looks like this:

public BranchGroup createSceneGraph() {   Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);   Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);   Color3f objColor  = new Color3f(0.6f, 0.6f, 0.6f);   Color3f lColor1= new Color3f(1.0f, 0.0f, 0.0f);   Color3f lColor2= new Color3f(0.0f, 1.0f, 0.0f);   Color3f alColor= new Color3f(0.2f, 0.2f, 0.2f);   Color3f bgColor= new Color3f(0.05f, 0.05f, 0.2f);   TransformGroup t1;   TransformGroup t2;   Java3dBuilder j3b = new Java3dBuilder()   BoundingSphere bounds =      new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);   // Create the root of the branch graph   BranchGroup objRoot =    j3b.branchGroup() {     transformGroup(scale:0.4) {           background(color:new Color3f(0.05f, 0.05f, 0.2f),bounds:bounds)           sphere(radius:1.0f,                  flags:Sphere.GENERATE_NORMALS,                  divisions:80,                  material:new Material(objColor,                                         eColor,                                         objColor,                                         sColor,                                         100.0f),                  lighting:true                 )           t1 = transformGroup(                capability:TransformGroup.ALLOW_TRANSFORM_WRITE){              transformGroup(                  translate:[0.0, 0.0, 2.0])              {                  sphere(radius:0.05f,coloringAttributes:lColor1)                  switch(lightType) {                    case DIRECTIONAL_LIGHT:                        directionalLight(color:lColor1,                                         direction:[0.0, 0.0, -2.0],                                         influencingBounds:bounds)                        break;                    case POINT_LIGHT:                        pointLight(color:lColor1,                                    position:[0, 0, 0],                                   attenuation:[1,0,0],                                  influencingBounds:bounds)                        break;                    case SPOT_LIGHT:                        spotLight(color:lColor1,                                   position:[0, 0, 0],                                  attenuation:[1,0,0],                                  direction:[0.0, 0.0, -2.0],                                  spreadAngle:25.0f * (float)Math.PI / 180.0f,                                  concentration:10.0,                                  influencingBounds:bounds)                        break;                 }              }           }           t2 = transformGroup(                capability:TransformGroup.ALLOW_TRANSFORM_WRITE){              transformGroup(                  translate:[0.5, 0.8, 2.0])              {                 sphere(radius:0.05f,coloringAttributes:lColor2)                 switch(lightType) {                    case DIRECTIONAL_LIGHT:                        directionalLight(color:lColor2,                                         direction:[-0.5, -0.8, -2.0],                                         influencingBounds:bounds)                        break;                    case POINT_LIGHT:                        pointLight(color:lColor2,                                    position:[0, 0, 0],                                   attenuation:[1,0,0],                                  influencingBounds:bounds)                        break;                    case SPOT_LIGHT:                        spotLight(color:lColor2,                                   position:[0, 0, 0],                                  attenuation:[1,0,0],                                  direction:[-0.5, -0.8, -2.0],                                  spreadAngle:25.0f * (float)Math.PI / 180.0f,                                  concentration:10,                                  influencingBounds:bounds)                        break;                 }              }           }           ambientLight(color:alColor,                        influencingBounds:bounds)            rotationInterpolator(alpha:new Alpha(-1, Alpha.INCREASING_ENABLE,                        0, 0,                        4000, 0, 0,                        0, 0, 0),                               target:t1,                               axisOfTransform:new Transform3D(),                               schedulingBounds:bounds,                               minAngle:0.0f,                               maxAngle:Math.PI*2.0f);         rotationInterpolator(alpha:new Alpha(-1, Alpha.INCREASING_ENABLE,                        0, 0,                        1000, 0, 0,                        0, 0, 0),                               target:t2,                               axisOfTransform:new Transform3D(),                               schedulingBounds:bounds,                               minAngle:0.0f,                               maxAngle:0.0f);         positionInterpolator(               alpha:new Alpha(-1,                          Alpha.INCREASING_ENABLE |                          Alpha.DECREASING_ENABLE,                          0, 0,                          5000, 0, 0,                          5000, 0, 0),              target:univ.getViewingPlatform().getViewPlatformTransform(),              yAxisOfTransform:(-1*Math.PI/2.0),              schedulingBounds:bounds,              start:2.0f,              end:3.5f);        }   }   objRoot.compile();return objRoot; }

The result is the same as the Java example: If someone wants to look at the code of this experiment, it can be found here.

In future posts I'm going to try to implement more Java3D functionality into the builder.