Thursday, November 27, 2008

Another applet embed test...

Here is a simple Processing applet that doesn't use OpenGL. I would be very grateful if somebody could tell me if it appears in the blog with IE on Windows.

Here's the html you'll need to embed an applet:-

<iframe width="482" height="322" frameborder="0" marginwidth="0" marginheight="0" src="http://somewhere-over-the-rainbow/applet/index.html"></iframe>

You'll need somewhere to store your applet though.

Embedding a Processing applet in a blog.


Well I think I've worked out how to embed an applet to show up in a blog. Well it works for me but I'm using Safari on a Mac. Would be great if somebody could tell me if it works on IE on Windows. The applet should appear below. Click and drag mouse to rotate camera, shift drag to zoom in and out.

Oh, I should mention the applet enables OpenGL mode so if it doesn't show up it could be because of that. As a test I'll post another applet which doesn't use OpenGL.


Sunday, November 23, 2008

Well I've started to write some Processing code for Chapter 33. I'm thinking that it might be useful to the reader to have a template project that sets up a 3-d environment ready for experimenting with. This is my first stab at it.

The code draws a grid, marks the origin and draws the x, y and z-axis. It also sets up some lighting. The view can be rotated using the cursor keys but mouse control would be much better... I'll add that in tomorrow. Code needs tidying up too. One thing that might be a bit confusing is that Processing uses a left hand coordinate system whereas OpenGL uses a right hand system. I've added a reflection transform so that the scene uses a right hand system, but I'm wondering if this just confuses things and I should really just stick with Processing's choice.

Here's the code in its rough state:-






import processing.opengl.*;

//
// Spherical coordiantes of camera.
//
float cameraR = 100.0 ;
float cameraPhi = PI / 4 ;
float cameraTheta = 0.0 ;


void setup()
{
//
// Enable OpenGL mode.
//
size(800, 600, OPENGL ) ;


colorMode( RGB, 1 ) ;

}

/**
* Handle a keyboard key press.
* At the moment, cursor keys control the camera.
*/
void keyPressed()
{
if ( key == CODED )
switch( keyCode )
{
case UP :
cameraPhi = cameraPhi > 0.1 ? cameraPhi - 0.01 : 0.1 ;
break ;

case DOWN :
cameraPhi = cameraPhi < PI / 4 - 0.1 ? cameraPhi + 0.01 : PI / 4 - 0.1 ;
break ;

case RIGHT :
cameraTheta = cameraTheta + 0.02 ;
break ;

case LEFT :
cameraTheta = cameraTheta - 0.02 ;
break ;
}

cameraTheta = cameraTheta < 2*PI ? cameraTheta : cameraTheta - 2*PI ;

}

/**
* Draw the scene.
*/
void draw()
{
//
// Initialise the view.
//
background( 0.0 ) ;

setCameraSpherical( cameraR, cameraPhi, -cameraTheta ) ;

//
// Reference page states that in OpenGL mode smooth defaults to on, but that's not the case!
//
smooth() ;

//
// Processing seems to use a left hand coordinate system.
// I prefer right as this is the norm for OpenGL.
//
scale( 1.0, -1.0, 1.0 ) ;

//
// Set up the lighting for the scene.
// This is done early on so that the lighting is fixed relative to the scene.
//
setupLights() ;

//
// Draw the coordinate centre and axis, and a grid.
// This will help when trying to work out the effect of transformations etc.
//
drawAxis( 10.0 ) ;
drawXYGrid( 100.0, 10, 4 ) ;




// cameraTheta += 0.01 ;
}

void setupLights()
{
ambientLight( 0.1, 0.1, 0.1 ) ;
directionalLight( 51.0, 102.0, 126.0, -1.0, -1.0, -1.0 ) ;
}

/**
* Set up the camera using spherical coordinates.
* @param r the distance from the pov to the camera
* @param phi the polar angle with the z-axis
* @param theta the azimuthal angle in the x/y-plane
*/
void setCameraSpherical( float r, float phi, float theta )
{
//
// Work out the x/y-z-coordinates of the camera.
//
float x = r * cos( theta )*sin( phi ) ;
float y = r * sin( theta ) * sin( phi ) ;
float z = r * cos( phi ) ;

//
// Need to work out the up vector.
// This is simply the image of the point ( 1, 0, 0 ) under the
// the given spherical map.
//
float nx = cos( theta ) * cos( phi ) ;
float ny = sin( theta ) * cos( phi ) ;
float nz = - sin( phi ) ;

beginCamera() ;
camera( x, y, z, 0.0, 0.0, 0.0, nx, ny, nz ) ;
endCamera() ;
}

/**
* Draw the unit x, y, z vectors.
*/

void drawAxis( float length )
{
pushMatrix();

//
// Highlight the origin with a white sphere.
//
noStroke() ;
fill( 1.0, 1.0, 1.0 ) ;
sphere( 1.5 ) ;

//
// Draw the x, y and z axis.
// The axis are actually drawn as unit length lines
// and we make use of a scaling transform to get them to the desired length.
//
scale( length, length, length ) ;


strokeWeight( 2 ) ;

beginShape( LINES ) ;

//
// x-axis in red.
//
stroke( 1.0, 0.0, 0.0 ) ;
vertex( 0.0, 0.0, 0.0 ) ;
vertex( 1.0, 0.0, 0.0 ) ;

//
// y-axis in green.
//
stroke( 0.0, 1.0, 0.0 ) ;
vertex( 0.0, 0.0, 0.0 ) ;
vertex( 0.0, 1.0, 0.0 ) ;

//
// z-axis in blue.
//
stroke( 0.0, 0.0, 1.0 ) ;
vertex( 0.0, 0.0, 0.0 ) ;
vertex( 0.0, 0.0, 1.0 ) ;

endShape() ;

popMatrix() ;

}

/**
* Draw a grid in the x-y plane.
*/
void drawXYGrid( float scale, int divisions, int minorDivisions )
{

pushMatrix();

scale( scale, scale, 0 ) ;

translate( -0.5, -0.5, 0 ) ;

noFill() ;
strokeWeight( 1 ) ;

float dw = 1.0 / divisions ;
float dm = dw / minorDivisions ;

beginShape( LINES ) ;

for ( int i = 0 ; i <= divisions ; ++i )
{
//
// Draw the minor divisions
//
strokeWeight( 0.5 ) ;
stroke( 0.6, 0.6, 0.6 ) ;

if ( i < divisions )
for ( int j = 1 ; j < minorDivisions ; ++j )
{
vertex( 0, i*dw + j*dm, 0 ) ;
vertex( 1, i*dw + j*dm, 0 ) ;
vertex( i*dw + j*dm, 0, 0 ) ;
vertex( i*dw + j*dm, 1, 0 ) ;
}

if ( i == divisions / 2 )
stroke( 0.9, 0.9, 0.9 ) ;
else
stroke( 0.8, 0.8, 0.8 ) ;

strokeWeight( 1.0 ) ;
vertex( 0, i*dw, 0 ) ;
vertex( 1, i*dw, 0 ) ;
vertex( i*dw, 0, 0 ) ;
vertex( i*dw, 1, 0 ) ;
}

endShape() ;


popMatrix();
}

Wednesday, November 12, 2008

Finally my Processing book has arrived from Waterstone's!!!