[comp.sources.misc] v06i014: liss - draw Lissajous figures on a Sun

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (01/30/89)

Posting-number: Volume 6, Issue 14
Submitted-by: jeff@ddsw1.MCS.COM (Jeff Haferman)
Archive-name: liss

[I had to "shar" this.  ++bsa]

The following program is something I adapted from an APL program
used as an example by the Professor of a Graphics course I took
last year.  I put it together to begin experimenting with Sunview
programming, so this is a first for me.  There are a couple of 
sloppy things, but as far as I can tell, it should work on all
Suns, though I've only tested it on a 3/50.  Also, it should be
easy to port to any machine (I know a Macintosh port would be 
simple.)

Anyway, this is a starting point for me to get more into Sun
programming.  Enjoy.

----------cut here---------cut here-----------cut here-----------cut here----
#! /bin/sh
# This file was wrapped with "dummyshar".  "sh" this file to extract.
# Contents:  liss.c
echo extracting 'liss.c'
if test -f 'liss.c' -a -z "$1"; then echo Not overwriting 'liss.c'; else
sed 's/^X//' << \EOF > 'liss.c'
X/*********************************************************************/
X/*                              liss                                 */
X/*      Purpose : Visual entertainment on a Sun.  Displays a         */
X/*                "Lissajous" figure, which is the connection        */
X/*                of points { cos(2*PI*x*i/n), sin(2*PI*y*i/n) }     */
X/*                for i=0,1,2,...,n and suitably chosen positive     */
X/*                integers x,y, and n.  Must use SunView.            */
X/*                                                                   */
X/*      Org :  Jeff Haferman 12/27/88                                */
X/*             jeff@ddsw1.mcs.com  or ...!oddjob!ddsw1.mcs.com!jeff  */
X/*                                                                   */
X/*      Compile:                                                     */
X/*            cc liss.c -o liss -lsuntool -lsunwindow -lpixrect -lm  */
X/*                                                                   */
X/*      Sample:                                                      */
X/*            liss 100 200 359                                       */
X/*                                                                   */
X/*********************************************************************/
X
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X#include <stdio.h>
X#include <math.h>
X
X#define X 1
X#define Y 2
X#define TRUE 1
X#define FALSE 0
X#define MAT(a) ((float *) a)
X
Xchar *progname;
X
Xmain (argc, argv)
Xchar **argv;
Xint argc;
X{
X	Frame frame;
X	Canvas canvas;
X	Pixwin *pw;
X	int x,y,n,i;
X	int plotx, ploty, plotx_last, ploty_last;
X	double dblx, dbly;
X	int first_pass=TRUE;
X	int width, height;
X	static float r2sun[3][3];
X	float *plot, *transform();
X
X	progname=argv[0];
X	if ( argc != 4 )
X		usage();
X
X	x= char2num(argv[1]);
X	y= char2num(argv[2]);
X	n= char2num(argv[3]);
X
X	frame = window_create(NULL, FRAME, 0);
X	canvas = window_create(frame, CANVAS,
X		CANVAS_FIXED_IMAGE, FALSE,
X		0);
X	pw= canvas_pixwin(canvas);
X
X	width = ((int) window_get(canvas, CANVAS_WIDTH))-1;
X	height = ((int) window_get(canvas, CANVAS_HEIGHT))-1;
X	get_transform(width,height,r2sun);
X
X	for (i=0; i<=n; i++) {
X		plotx_last = plotx; 
X		ploty_last = ploty; 
X		dblx = cos ((double)(2*M_PI*x*((float)i/(float)n)));
X	  	dbly = sin ((double)(2*M_PI*y*((float)i/(float)n)));
X	  	plot = transform((float)dblx,(float)dbly,r2sun);
X	  	plotx = (int) plot[X-1];
X	  	ploty = (int) plot[Y-1];
X		if (!first_pass) 
X			pw_vector(pw,plotx_last,ploty_last,plotx,ploty,PIX_SRC,1);
X		else 
X			first_pass=FALSE;
X	}
X	
X	window_main_loop(frame);
X	exit(0);
X}
X
X
Xget_transform(w,h,tranmat)
X	int w,h;
X	float *tranmat;
X{
Xint i,j;
X	float w0,w1,h0,h1;	
X	static float a[3][3]= { {-1,0,1},
X					         {-1,1,0},
X					         {1,0,0}};
X	static float b[3][3]= { {0,0,1},
X					         {0,0,1},
X					         {0,0,1}};
X	w0=(float)w;
X	w1=w0/2;
X	h0=(float)h;
X	h1=h0/2;
X	
X    b[0][0]=w1;
X	b[0][1]=h1;
X	b[1][0]=w1;
X	b[2][0]=w0;
X	b[2][1]=h1;
X
X	m_mult(a,b,tranmat,3,3,3);
X}
X
X
Xfloat
X*transform(x,y,tranmat)
X	float x,y,*tranmat;
X{
Xint j;
X	static float a[3]={0,0,1};
X	float b[3];
X
X	a[0]=x;
X	a[1]=y;
X	m_mult(a,tranmat,b,1,3,3);
X
X	return(b);
X}
X
X
X/*------------------------------------------------------------*/
X/*                                                            */
X/*   m_mult(A,B,C,m,n,p)                                      */
X/*          A is  an (m x n) matrix of floats                 */
X/*          B is  an (n x p) matrix of floats                 */
X/*          C is  an (m x p) matrix of floats                 */
X/*                                                            */
X/*    A and B must be set before the call.  C is then set     */
X/*    here as the product of A and B.  No checking is done    */
X/*    here on the dimensions of A and B.                      */
X/*                                                            */
X/*------------------------------------------------------------*/
X
Xm_mult(A,B,C,m,n,p)
X	float **A, **B, **C;
X	int	m, n, p;
X
X/* for a good explantion on passing arbitrary sized matrices
X   to functions, see pp. 119-121 in C++                       */
X
X{
X	int i, j, k;
X
X	for(i=0; i<=m-1; i++)
X		for(j=0; j<=p-1; j++) {
X			MAT(C)[i*p+j]=0;
X			for(k=0; k<=n-1; k++)	
X				MAT(C)[i*p+j]+= ( MAT(A)[i*n+k] * MAT(B)[k*p+j] );
X		}
X}
X
Xchar2num(c)
X	char *c;
X{
X	int i;
X
X	for (i = 0; *c >= '0' && *c <= '9'; c++)
X		i *= 10, i += *c - '0';
X	if (*c) 
X		usage();
X	return (i);
X}
X
X
Xusage()
X{
X	fprintf(stderr, "usage: %s \<x\> \<y\> \<n\>\n", progname);
X	fprintf(stderr, "       where x, y, and n are positive integers.");
X	exit(1);
X}
EOF
chars=`wc -c < 'liss.c'`
if test $chars !=     4785; then echo 'liss.c' is $chars characters, should be     4785 characters!; fi
fi
exit 0