Recently I've been looking at Povray, pyprocessing, and cfdg (version 3.0) as tools for creating digital images. I have branched two separate blogs where I mainly explore jruby + processing and processing.py

Friday, 29 July 2011

NetBeans For Processing (including opengl)

Using Native Libraries for Processing in Netbeans

To use processing in netbeans you should "create a processing library" this is described here:-

http://shinkirou.org/blog/2010/08/using-processing-in-netbeans/.

To use opengl in processing you should also create a opengl library, and add that to your project:-
Since processing-2.0 P3D is opengl, so it makes sense to include those files as well, and since 2.0a5 make sure to include the jar containing the native binaries for your system (Linux/Mac/Windows , also you no longer need the -Djava.lib.path to be passed at runtime).



To create the ProcessingOpenGL library you need the path to the opengl libraries and jogl src:-


/home/sid/processing-1.5.1/modes/java/libraries/opengl/library/opengl.jar
/home/sid/processing-1.5.1/modes/java/libraries/opengl/library/gluegen-rt.jar
/home/sid/processing-1.5.1/modes/java/libraries/opengl/library/jogl.jar


/home/sid/processing-1.5.1/modes/java/libraries/opengl/library/jogl-src.zip

If you want to run the applet from net beans you will need access the native libraries, to do this set the project properties as follows:-



VM Options: -Djava.library.path=/home/sid/processing-1.5.1/java/libraries/opengl/library/linux64

Obviously adjust the above paths to suit your environment, be it 32 bit linux/windows etc.

Update 26 February, with a bit of luck the processing developers will return to placing the native binaries in a jar, and the previous step will be unecessary (you will just have to put that jar on your path as for gluegen/jogl etc).  That's what seems to be happening recently anyway. For an update follow link http://martinpblogformasswritingproject.blogspot.co.uk/2012/07/setting-up-netbeans-72-for-processing-20.html

Thursday, 21 July 2011

New sphere primitive for use with processing and povwriter

In a previous blog entry I described the hand editing of a PovRAY file to add a sphere to sketch exported from processing to PovRAY, this was because the sphere primitive in processing is rather crude and does not export well for ray tracing. Now I include the possibility of providing an alternative sphere within the processing sketch that exports rather better, see version 0.58 of my povwriter library. The sphere is loosely based on lazydogs Ball of Confusion, the sphere is essentially an inflated icosahedron, which has the faces recursively subdivided to create greater detail. Here is an examples sketch using the alternative sphere primitive, the sphere detail is set somewhat arbitrarily according to the size of the sphere, and does not respond to the processing sphereDetail() directive:-

/** 
 * Copyright (c) 2011 Martin Prout
 * 
 * This demo & library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * http://creativecommons.org/licenses/LGPL/2.1/
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */


import povexport.*;
import povexport.povwriter.*;

/**
* This sketch is adapted from the DXF export processing library example
* But using a custom sphere based on an inflated recursive icosahedron
*/

boolean record = false;
PovExporter export;

void setup() {
  size(400, 400, P3D);
  export = new PovExporter(this);
  export.chooseTemplate();
  //export.setPovrayPath("/home/tux/bin/jedit"); //use this once to set povray path
  export.storeSettings(); // NB call storeSettings() after changes
  noStroke();
  sphereDetail(18);
}

void draw()
{ 
  lights();        // this needs to be outside the record loop
  if (record) {    
    noLights();    // let PovRAY do the lighting
    noLoop();      // don't loop while recording sketch
    beginRaw("povexport.RawPovray", dataPath("balls.pov"));
  }
  render();
  if (record) {
    endRaw();
    record = false;
    loop();
  }
}

void render() {  
  background(0);
  translate(width*0.7, height*0.7, width/20);
  for (int y = -1; y < 1; y++) {
    for (int x = -1; x < 1; x++) {
      for (int z = -1; z < 1; z++) {
        pushMatrix();
        translate(140*x, 140*y, -140*z);
        fill(random(255), random(255), random(255)); // a nice test for my colorFactory class
        export.sphere(60); // use a better sphere primitive for ray tracing
        popMatrix();
      }
    }
  }
}

void keyPressed() {
  switch(key) {
  case 'r': 
    record = true;
    break;
  case 'e':             // edit pov output and/or run povray (use commando file to run from jedit)
     String[] jargs = {"/home/tux/bin/jedit", dataPath("balls.pov")};
     //String[] jargs = {export.getPovrayPath(), dataPath("output.pov")}; // use this after path has been set
      //open(jargs); // this processing shortcut doesn't work for me on my linux box hence.....
      Runtime runtime = Runtime.getRuntime();
    try {
      if (this.record == false) {
        runtime.exec(jargs); // open jedit with FTest.pov file
      }
    } 
    catch (IOException ex) {
      ex.printStackTrace();
    }
    break;
  }
}


PovRAY rendered processing sketch

PovRAY rendered custom processing sphere in a Random Cage
using WBlut hemesh library to create the random cage (code by WBlut)

Sunday, 10 July 2011

Colourful Voronoi diagram in pyprocessing

The perfect way of working with pyprocessing is to use a dedicated python ide. I've just started working with Eric4, knocks spots off the regular processing ide, supports code completion, debug and much more (even a handy little python console). Took a bit of installing on my 64 bit linux box (I compiled latest 4.4.15 version and ubuntu natty is having a bit of a python version control fit at the moment). Get pyprocessing here.

"""
Copyright (c) 2011 Martin Prout
 
This module is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
http://creativecommons.org/licenses/LGPL/2.1/

voronoi.py example
"""

from pyprocessing import *
from os import getcwd,  path
from random import randint
# this sketch uses the vanilla processing convention of a local 'data' folder
# where images etc should be stored, and python path.join to create a 
# cross platform address, depends working directory being where script is located
# and that directory containing the data folder

data_path = path.join(getcwd(), 'data')  

X = 0   # intelligible array indicies
Y = 1
R = 0
G = 1
B = 2
display_center = False

def setup():
    """
    pyprocessing setup
    """
    size(800, 600)
    global original,  image_array,  npos,  ncol,  n,  voronoi
    voronoi = None
    original = loadImage(path.join(data_path, 'voronoi.png') ) 
    n = randint(50, 100)                   # randomly determine number of cells
    nc= [[None] * n for i in range(3)]     # initialize empty multi arrays     
    ncol = [None] * n
    np =[[None] * 2 for j in range(n)]     # avoid  copy by reference trap (python bites)
    for i in xrange(n):
        np[i][X], np[i][Y]  = randint(0, width - 1),  randint(0, height - 1)
        nc[R][i] = randint(0, 255)                             # random red
        nc[G][i] = randint(0, 255)                             # random green
        nc[B][i] = randint(0, 255)                             # random blue
        ncol[i] = nc[R][i]<<16|nc[G][i]<<8|nc[B][i]  # bit shifting to a RGB color
    npos = sorted(np, compare_pixel_index)
    
def draw():
    """
    Loads an existing voronoi image from file to keep the impatient happy, creates 
    (it takes a while) a new voronoi image by brute force, and draws it screen. This
    is the draw loop so we can change things here using key/mouse etc
    """    
    global original, voronoi, npos,  ncol,  n
    if (frame.count < 5):
        background(original)      
    elif (voronoi == None):
        voronoi = new_voronoi(npos, ncol,  n)   # this is a candidate for a new thread!
    else:
        background(voronoi)
    if (display_center):
        fill(0)
        for vc in npos:
            ellipse(vc[X], vc[Y], 5, 5)
       
def  compare_pixel_index(a,  b):
    """
    Used to sort voronoi centers by their pixel index 
    """
    return cmp(a[1]*a[0] +a[0],  b[1]*b[0] +b[0])
        
def new_voronoi(npos, ncol,  n):
    """
    Creates a voronoi image by brute force
    @param npos = x, y position array voronoi cell centers
    @param ncol = RGB color int
    @param  n = no of voronoi cells
    @return new voronoi Pimage
    There is a possible speed up if we don't check every voronoi center
    see commented out code, the cut off maxima/minima were empirically 
    determined, if more than one center or no center is seen in a cell adjust 
    the appropriate cut off below code lines 85 to 88.
    """
    voronoi = PImage(width, height,  RGB)
    # minima = 0            # to get a slight speed up we don't check every cell center
    # maxima = int(0.6 * n) # minima and maxima determine which values are checked 
    for y in xrange(height):
        #if (y > 0.1 * height):  
        #    maxima = int(n * 0.8) if (y < 0.15 * height) else n       
        #    if (y > 0.8 * height):
        #        minima = int(n * 0.1) if (y < 0.9 * height) else int(n * 0.15)  
        for x in xrange(width):
            dmin = ((width - 1) * (width - 1)) + ((height - 1) * (height - 1)) 
            j = -1                
            for i in xrange(n):
            #for i in xrange(minima, maxima):  
                d = ((npos[i][X]- x) * (npos[i][X]- x)) + ((npos[i][Y]- y) * (npos[i][Y]- y)) 
                if d < dmin:
                    dmin = d
                    j = i
            voronoi.pixels[y*width+x] = ncol[j] 
    voronoi.updatePixels()
    return voronoi
    
def keyPressed():
    """
    Press 'c' to toggle the display of voronoi cell "centers" 
    Press 's' to save the current file to disk
    """
    global display_center
    if key.char in 'cC':
        display_center = not display_center
    if key.char in 'sS':
        global voronoi
        voronoi.save(path.join(data_path, "new_voronoi.png"))
    if key.char in 'eE':
        exit(0)
run()


Updated 5 September 2011 to include a possible speed up and the ability to toggle the display of voronoi "centers".

Monday, 4 July 2011

Negative modulus in python, ruby and java

Java whipped hands down by both ruby and python!!
Java just returns rubbish (see footnote below applet), whereas ruby and python return a value you can use!!!!
If we are talking geometry for example, and we have a negative angle, what we want is the complement of 360, and that's what we get with ruby and python. In java we need some sort of kludge like:-


while(delta < 0){
delta += 360;
}



I came across this when experimenting with sine/cosine lookup tables for my LSystems library for processing.
Here is the example which demonstrates the lookup tables in action, with my LSystems library, a pity I can't get the finish as sexy as my PovRAY rendered Rod Hilbert in previous posts press '+' to increase depth '-' to decrease depth:-



Footnote it was interesting to read this article concerning the implementation of modulo (for negative values) in many computer languages (ie crap in most cases!!), and some spreadsheets.

Followers

Blog Archive

About Me

My photo
Pembrokeshire, United Kingdom
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2