A CwGraph Rotating Cube

Gamma/Photon: Using Gamma™ with the Photon microGUIŽ, Version 4.0
Prev | Chapter 6. Sample Code and Cool Stuff | Next

# 6.3. A CwGraph Rotating Cube

This code creates two graphs, one of which is a two-dimensional representation of a cube that appears to rotate in three-dimensional space. The graphs are created using the `CwGraph` widget, a contributed widget created at Cogent Real-Time Systems, Inc. This program uses a dynamic library, which requires that Gamma be called from it's own directory. For example, if Gamma is in your /usr/cogent/bin/ directory, you would start this program with the following command:

$ `/usr/cogent/bin/phgamma graph.g 3d`

The code starts here:

    #!/usr/cogent/bin/phgamma

    /*
     * This example shows two graphs made using CwGraph.
     * One graph is a 3-dimensional rotating cube.  You can
     * display this graph using the argument "3d" on the
     * command line.  The other graph shows 6 randomly-
     * generated traces of various colors.  No argument is
     * necessary on the command line to display this graph.
     */

    /*
     * Load the required files, which include two dynamic
     * libraries that are not generally needed for Photon
     * widgets.
     */

    require_lisp ("PhotonWidgets");
    require_lisp("PhabTemplate.lsp");

    use3d = nil;

    /*
     * Used with the 3D cube example.
     */
    xrot = 0;
    yrot = 0;
    zrot = 0;
    pi = 3.141592653589;

    /*
     * Used with the 2D graph example.
     */
    DataSetSize = 100;
    count = 0;
    xlist1 = nil;

    function main ()
    {
    	PtInit (nil);

    	if (length(argv) > 1 && cadr(argv) == "3d")
    		use3d = t;

    	/* Set the redraw frequency. */

    	if (use3d)
    		every (0.1, #redraw());
    	else
    		every (0.1, #redraw2());

    	MakeWindow ();

    	PtRealizeWidget (w);
    	PtMainLoop();
    }

    function MakeWindow ()
    {
    	w = new (PtWindow);
    	gr = new (PtGroup);
    	gr.SetDim (325,300);

    	/* Anchor the group to the window.*/

    	gr.group_flags = Pt_GROUP_STRETCH_HORIZONTAL |
    	                 Pt_GROUP_STRETCH_VERTICAL;
    	gr.anchor_flags = Pt_LEFT_ANCHORED_LEFT |
    	                  Pt_RIGHT_ANCHORED_RIGHT |
    			  Pt_TOP_ANCHORED_TOP |
    			  Pt_BOTTOM_ANCHORED_BOTTOM;

    	/* Assign graph variables.*/

    	g = new (CwGraph);
    	g.SetDim (325, 300);
    	g.fill_color = 0x7777bb;
    	g.graph_x_axis_color = 0x00ff00;
    	g.graph_y_axis_color_left = 0x00ff00;
    	g.graph_y_axis_color_right = 0x00ff00;
    	g.graph_x_label_color = 0xffff00;
    	g.graph_y_label_color_left = 0xffff00;
    	g.graph_y_label_color_right = 0xffff00;

    	if (!use3d)
    	{
    		g.graph_traces = 4;
    		g.graph_xmin = 0;
    		g.graph_xmax = DataSetSize;
    		g.graph_x_label = "Test Trace";
    		g.graph_y_label_left = "Y Axis";
    		g.graph_y_label_right = "Alternate Axis";
    		g.graph_x_font = "helv14bi";
    		g.graph_y_font_left = "helv14b";
    		g.graph_y_font_right = "helv14i";
    		g.graph_flags = cons (Cw_GRAPH_Y_AXIS_LEFT |
    				      Cw_GRAPH_X_AXIS, -1);

    		CwGraphSetYLimits (g, 0, 0, 1000);
    		CwGraphSetYLimits (g, 1, 0, 1000);
    		CwGraphSetYLimits (g, 2, 0, 1000);
    		CwGraphSetYLimits (g, 3, 0, 1000);
    		CwGraphSetTraceColor (g, 0, 0xff0000);
    		CwGraphSetTraceColor (g, 1, 0x0000ff);
    		CwGraphSetTraceColor (g, 2, 0x00ffff);
    		CwGraphSetTraceColor (g, 3, 0x00ff00);
    	}
    	else
    	{
    		g.graph_traces = 6;
    		g.graph_xmin = -2;
    		g.graph_xmax = 2;
    		g.graph_flags = cons (Cw_GRAPH_Y_AXIS_RIGHT |
    				      Cw_GRAPH_Y_MAJOR_TICK_RIGHT |
    				      Cw_GRAPH_Y_MINOR_TICK_RIGHT |
    				      Cw_GRAPH_Y_AXIS_TITLE_RIGHT |
    				      Cw_GRAPH_Y_AXIS_LABEL_RIGHT
    				      , nil);
    		g.margin_width = 10;

    		CwGraphSetYLimits (g, 0, -2, 2);
    		CwGraphSetYLimits (g, 1, -2, 2);
    		CwGraphSetYLimits (g, 2, -2, 2);
    		CwGraphSetYLimits (g, 3, -2, 2);
    		CwGraphSetYLimits (g, 4, -2, 2);
    		CwGraphSetYLimits (g, 5, -2, 2);
    		CwGraphSetTraceColor (g, 0, 0xff0000);
    		CwGraphSetTraceColor (g, 1, 0xffff00);
    		CwGraphSetTraceColor (g, 2, 0x00ff00);
    		CwGraphSetTraceColor (g, 3, 0x00ff00);
    		CwGraphSetTraceColor (g, 4, 0x00ff00);
    		CwGraphSetTraceColor (g, 5, 0x00ff00);
    	}
    }

    /*
     * Functions for the 3D example.
     */

    function data (n, range, adder)
    {
    	local		i, l;

    	for (i=0; i<n; i++)
    	{
    		l = cons (random() * range + adder, l);
    	}
    	l;
    }

    function xlist (start, n)
    {
    	local		i, l;
    	for (i=start+n - 1; i>=start; i --)
    		l = cons (i,l);
    	l;
    }

    function newdata ()
    {
    	if (count > DataSetSize)
    	{
    		count = 0;
    		CwGraphClearTrace (g,0);
    		CwGraphClearTrace (g,1);
    	}
    	CwGraphAddXYPoints (g, 0, xlist(count,10), data(10,500,500));
    	CwGraphAddXYPoints (g, 1, xlist(count,10), data(10,500,0));
    	count += 10;
    }

    function mk3dpt (x, y, z)
    {
    	array (x, y, z);
    }

    function cube3d ()
    {
    	array (array (mk3dpt(-1,1,1), mk3dpt(-1,-1,1),
    		      mk3dpt(1,-1,1), mk3dpt(1,1,1),
    		      mk3dpt(-1,1,1)),
    		   array (mk3dpt(-1,1,-1), mk3dpt(1,1,-1),
    			  mk3dpt(1,-1,-1), mk3dpt(-1,-1,-1),
    			  mk3dpt(-1,1,-1)),
    		   array (mk3dpt(-1,1,1), mk3dpt(-1,1,-1)),
    		   array (mk3dpt(1,1,1), mk3dpt(1,1,-1)),
    		   array (mk3dpt(1,-1,1), mk3dpt(1,-1,-1)),
    		   array (mk3dpt(-1,-1,1), mk3dpt(-1,-1,-1))
    		   );
    }

    function identmatrix ()
    {
    	array (array (1,0,0,0),
    	       array(0,1,0,0),
    	       array (0,0,1,0),
    	       array (0,0,0,1));
    }

    function matxmat (mat1, mat2)
    {
    	local		i,j,res=array(array(0,0,0,0),
    				      array(0,0,0,0),
    				      array(0,0,0,0),
    				      array(0,0,0,0));

    	for (i=0; i<4; i++)
    	{
    		for (j=0; j<4; j++)
    		{
    			res[i][j] = mat1[i][0] * mat2[0][j] +
    				    mat1[i][1] * mat2[1][j] +
    				    mat1[i][2] * mat2[2][j] +
    				    mat1[i][3] * mat2[3][j];
    		}
    	}
    	res;
    }

    function vecxmat (vec, mat)
    {
    	local	res = array (0,0,0,0);
    	local	i;

    	for (i=0; i<4; i++)
    	{
    		res[i] = vec[0] * mat[0][i] +
    		         vec[1] * mat[1][i] +
    			 vec[2] * mat[2][i];
    	}
    	res;
    }

    function xrotmat (degrees)
    {
    	local		rad = degrees / 180 * pi, ret = identmatrix();
    	ret[1][1] = ret[2][2] = cos (rad);
    	ret[1][2] = sin (rad);
    	ret[2][1] = -sin (rad);
    	ret;
    }

    function yrotmat (degrees)
    {
    	local		rad = degrees / 180 * pi, ret = identmatrix();
    	ret[0][0] = ret[2][2] = cos (rad);
    	ret[0][2] = sin (rad);
    	ret[2][0] = -sin (rad);
    	ret;
    }

    function zrotmat (degrees)
    {
    	local		rad = degrees / 180 * pi, ret = identmatrix();
    	ret[0][0] = ret[1][1] = cos (rad);
    	ret[0][1] = sin (rad);
    	ret[1][0] = -sin (rad);
    	ret;
    }

    function redraw ()
    {
    	local		c = cube3d();
    	local		mat = identmatrix();
    	local		xr = xrotmat(xrot);
    	local		yr = yrotmat(yrot);
    	local		zr = zrotmat(zrot);
    	local		traces = array();
    	local		i=0, xpts, ypts, vec;

    	xrot += 1;
    	yrot += 1;
    	zrot += 1;

    	mat = matxmat (mat, xr);
    	mat = matxmat (mat, yr);
    	mat = matxmat (mat, zr);

    	i=0;
    	with trace in c do
    	{
    		xpts = nil;
    		ypts = nil;
    		with pt in trace do
    		{
    			vec = vecxmat (pt, mat);
    			xpts = cons (vec[0], xpts);
    			ypts = cons (vec[1], ypts);
    		}
    		traces[i] = cons (xpts,ypts);
    		i++;
    	}

    	PtHold();
    	for (i=0; i<6; i++)
    	{
    		CwGraphClearTrace (g,i);
    		CwGraphAddXYPoints (g, i, car(traces[i]),
    				    cdr(traces[i]));
    	}
    	PtRelease();
    }

    /*
     * Function for the 2D example.
     */

    function redraw2 ()
    {
    	local	nanosleep = list;

    	PtHold();
    	{
    		ylist1 = data (DataSetSize, 400, 600);
    		ylist2 = data (DataSetSize, 400, 400);
    		ylist3 = data (DataSetSize, 400, 200);
    		ylist4 = data (DataSetSize, 400, 0);
    		xlist1 = xlist (0, DataSetSize);
    	}
    	CwGraphClearTrace (g,0);
    	CwGraphClearTrace (g,1);
    	CwGraphClearTrace (g,2);
    	CwGraphClearTrace (g,3);
    	CwGraphAddXYPoints (g, 0, xlist1, ylist1);
    	CwGraphAddXYPoints (g, 1, xlist1, ylist2);
    	CwGraphAddXYPoints (g, 2, xlist1, ylist3);
    	CwGraphAddXYPoints (g, 3, xlist1, ylist4);
    	PtRelease();
    }

Prev | Home | Next
Handling Keyboard Events | Up | A CwMatrix Spreadsheet

Copyright 1995-2002 by Cogent Real-Time Systems, Inc.