home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!husc6!necntc!ncoast!allbery
- From: igp@camcon.UUCP (Ian Phillipps)
- Newsgroups: comp.sources.misc
- Subject: v03i055: A sunview program to draw "roses"
- Keywords: rose sunview trivia pictures
- Message-ID: <1593@titan.camcon.uucp>
- Date: 15 Jun 88 13:23:18 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: igp@camcon.UUCP (Ian Phillipps)
- Organization: Cambridge Consultants Ltd., Cambridge, UK
- Lines: 261
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 3, Issue 55
- Submitted-By: "Ian Phillipps" <igp@camcon.UUCP>
- Archive-Name: rose
-
- This is an amusing toy for Sun console users. If you want to convert it to
- some other windowing system, please do. The guts of the mathematics is about
- five lines in redraw() - the rest is padding.
-
-
- Shell archive - cut here - send the rest to sh, type "make".
- #!/bin/sh
- # shar: Shell Archiver (v1.22)
- #
- # Run the following text with /bin/sh to create:
- # rose.c
- # Makefile
- #
- sed 's/^X//' << 'SHAR_EOF' > rose.c &&
- X/* A pretty pixture-drawer @(#)rose.c 1.9
- X This program is supplied as-is, and is certainly not suitable for any
- X purpose.
- X My thanks to Colin Attenborough, whose version on a 6502-based home
- X computer prompted my question "How fast would that run on a Sun?";
- X to the Guardian newspaper for drawing Colin's attention to the algorithm,
- X and to Peter M Maurer of A T & T, whose article "A Rose is a Rose..."
- X in the American Mathematical Monthly (Oct 87, p 631) started it all.
- X
- X Ian Phillipps (igp@camcon.uucp), 15 June 1988
- X
- X Tested on Sun 3 (SunOS 3.5) and Sun 4 (SunOS 3.2).
- X */
- X
- X#include <stdio.h>
- X#include <math.h>
- X#include <suntool/sunview.h>
- X#include <suntool/canvas.h>
- X#include <suntool/panel.h>
- X
- X/* A greater variety of drawing types is obtained if QUANTUM is composite
- X 360 does just fine - it has nothing to do directly with degrees. */
- X#define QUANTUM 360 /* Number of increments in a revolution */
- X
- X/* Size and Slider_length should be related for a sensible panel layout */
- X#define SIZE 700 /* Initial size of canvas (square) */
- X#define SLIDER_LENGTH ((QUANTUM-2)/1)
- X#define FILL_SCALE 9/10 /* Note absence of brackets (kludge) */
- X
- Xstatic Frame frame;
- Xstatic Panel_item panel_n, panel_d;
- Xstatic Canvas canvas;
- Xstatic Pixwin *pw;
- X
- Xstatic double sinx[QUANTUM], cosx[QUANTUM]; /* trig tables */
- X
- Xenum rect_type { PIXWIN, PIXRECT };
- X
- Xredraw( type, pw, width, height )
- X enum rect_type type;
- X Pixwin *pw;
- X int width, height;
- X{
- X int xoffset = width / 2;
- X int n = (int)panel_get_value( panel_n );
- X int d = (int)panel_get_value( panel_d );
- X int a = 0;
- X int yoffset = height /2;
- X int xscale = xoffset * FILL_SCALE;
- X int yscale = yoffset * FILL_SCALE;
- X int x = xoffset;
- X int y = yoffset;
- X double r = 0.0;
- X int newx = xoffset;
- X int newy = yoffset;
- X /* Black marks to Sun for having two different animals - pixwin and
- X pixrect - which makes this kludge necessary. Maybe you can get a pixwin
- X from a pixrect or vice-versa? */
- X if ( type == PIXWIN )
- X {
- X pw_batch_on( pw );
- X /* clear the window */
- X pw_writebackground(pw, 0, 0, width, height, PIX_SRC );
- X }
- X else
- X pr_rop((struct pixrect*)pw, 0, 0, width, height, PIX_CLR,
- X (struct pixrect*)0, 0, 0 );
- X /* This is the kernel of the whole thing: draw the lines */
- X do
- X {
- X x = newx;
- X y = newy;
- X a = ( a + d ) % QUANTUM;
- X r = sinx[ (n * a ) % QUANTUM ];
- X newx = xoffset + xscale * r * sinx[a];
- X newy = yoffset + yscale * r * cosx[a];
- X if ( type == PIXWIN )
- X pw_vector( pw, x, y, newx, newy, PIX_SRC, 1 );
- X else
- X pr_vector( (struct pixrect*)pw, x, y, newx, newy, PIX_SRC, 1 );
- X }
- X while ( a != 0 );
- X /* unbatch */
- X if ( type == PIXWIN )
- X pw_batch_off( pw );
- X}
- X
- Xredraw_proc()
- X{
- X int width = (int)window_get( canvas, WIN_WIDTH );
- X int height = (int)window_get( canvas, WIN_HEIGHT );
- X redraw( PIXWIN, pw, width, height );
- X /* It would be faster to redraw the icon only when necessary - however
- X this makes the program *2 more complicated - need to get involved
- X with Notifiers and all that */
- X redraw_icon();
- X}
- X
- Xredraw_icon()
- X{
- X /* get pixrect for icon */
- X Icon icon = (Icon) window_get( frame, FRAME_ICON );
- X Pixrect *pr = (Pixrect*) icon_get( icon, ICON_IMAGE );
- X redraw( PIXRECT, pr, pr->pr_size.x, pr->pr_size.y );
- X icon_set( icon, ICON_IMAGE, pr, 0 );
- X window_set( frame, FRAME_ICON, icon, 0 );
- X}
- X
- X/* procedures to adjust the sliders one step at a time */
- Xn_down_proc()
- X{
- X int n = (int) panel_get_value( panel_n );
- X panel_set_value( panel_n, (caddr_t)(n-1) );
- X redraw_proc();
- X}
- X
- Xn_up_proc()
- X{
- X int n = (int) panel_get_value( panel_n );
- X panel_set_value( panel_n, (caddr_t)(n+1) );
- X redraw_proc();
- X}
- X
- Xd_down_proc()
- X{
- X int d = (int) panel_get_value( panel_d );
- X panel_set_value( panel_d, (caddr_t)(d-1) );
- X redraw_proc();
- X}
- X
- Xd_up_proc()
- X{
- X int d = (int) panel_get_value( panel_d );
- X panel_set_value( panel_d, (caddr_t)(d+1) );
- X redraw_proc();
- X}
- X
- X
- Xquit_proc()
- X{
- X exit(0);
- X}
- X
- Xmain( argc, argv )
- X int argc; char **argv;
- X{
- X /* open the canvas */
- X Panel panel;
- X struct pixrect *icon_pr = mem_create ( 64, 64, 1 );
- X Icon icon = icon_create( ICON_IMAGE, icon_pr, 0 );
- X frame = window_create( NULL, FRAME,
- X WIN_HEIGHT, SIZE + 100,
- X WIN_WIDTH, SIZE,
- X FRAME_ARGS, argc, argv,
- X FRAME_LABEL, "Rose display program by igp@camcon.uucp Version 1.9",
- X FRAME_ICON, icon,
- X 0 );
- X panel = window_create( frame, PANEL,
- X WIN_WIDTH, SIZE,
- X 0 );
- X /* draw a panel */
- X srand( time((long*)0));
- X panel_n = panel_create_item( panel, PANEL_SLIDER,
- X PANEL_LABEL_STRING, "N ",
- X PANEL_MIN_VALUE, 1,
- X PANEL_SLIDER_WIDTH, SLIDER_LENGTH,
- X PANEL_MAX_VALUE, QUANTUM-1,
- X PANEL_NOTIFY_PROC, redraw_proc,
- X PANEL_VALUE, (rand()/256)%(QUANTUM-2) + 1,
- X 0 );
- X panel_create_item( panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image( panel, "down", 0, (Pixfont *) 0 ),
- X PANEL_NOTIFY_PROC, n_down_proc,
- X 0 );
- X panel_create_item( panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image( panel, "up", 0, (Pixfont *) 0 ),
- X PANEL_NOTIFY_PROC, n_up_proc,
- X 0 );
- X panel_d = panel_create_item( panel, PANEL_SLIDER,
- X PANEL_LABEL_STRING, "D ",
- X PANEL_MIN_VALUE, 1,
- X PANEL_SLIDER_WIDTH, SLIDER_LENGTH,
- X PANEL_MAX_VALUE, QUANTUM-1,
- X PANEL_VALUE, (rand()/256)%(QUANTUM-2) + 1,
- X PANEL_NOTIFY_PROC, redraw_proc,
- X 0 );
- X panel_create_item( panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image( panel, "down", 0, (Pixfont *) 0 ),
- X PANEL_NOTIFY_PROC, d_down_proc,
- X 0 );
- X panel_create_item( panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image( panel, "up", 0, (Pixfont *) 0 ),
- X PANEL_NOTIFY_PROC, d_up_proc,
- X 0 );
- X panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "quit", 0, (Pixfont *) 0),
- X PANEL_NOTIFY_PROC, quit_proc,
- X 0);
- X window_fit_height( panel );
- X canvas = window_create( frame, CANVAS,
- X WIN_BELOW, panel,
- X WIN_X, 0,
- X WIN_HEIGHT, SIZE,
- X WIN_WIDTH, SIZE,
- X CANVAS_FIXED_IMAGE, FALSE,
- X CANVAS_REPAINT_PROC, redraw_proc,
- X 0 );
- X pw = canvas_pixwin( canvas );
- X window_fit(frame);
- X /* precompute trig stuff */
- X { int i;
- X for ( i=0; i<QUANTUM; i++ )
- X {
- X sinx[i] = sin(i*(2*M_PI/QUANTUM));
- X cosx[i] = cos(i*(2*M_PI/QUANTUM));
- X }
- X }
- X redraw_icon();
- X window_main_loop(frame);
- X exit(0);
- X}
- SHAR_EOF
- chmod 0644 rose.c || echo "restore of rose.c fails"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- XLDFLAGS=-lsuntool -lsunwindow -lpixrect -lm
- XCFLAGS=-O
- X
- X# This is only necessary because of a stupidity in Sun's default.mk which
- X# puts LDFLAGS too early in the line
- Xrose: rose.c
- X $(CC) $(CFLAGS) -o $@ $? $(LDFLAGS)
- SHAR_EOF
- chmod 0644 Makefile || echo "restore of Makefile fails"
- exit 0
- --
- UUCP: ...!ukc!camcon!igp | Cambridge Consultants Ltd | Ian Phillipps
- or: igp@camcon.uucp | Science Park, Milton Road |-----------------
- Phone: +44 223 358855 | Cambridge CB4 4DW, England |
-