home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume3 / rose < prev    next >
Internet Message Format  |  1989-02-03  |  8KB

  1. Path: xanth!mcnc!gatech!bloom-beacon!mit-eddie!ll-xn!ames!necntc!ncoast!allbery
  2. From: igp@camcon.UUCP (Ian Phillipps)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i055: A sunview program to draw "roses"
  5. Keywords: rose sunview trivia pictures
  6. Message-ID: <1593@titan.camcon.uucp>
  7. Date: 15 Jun 88 13:23:18 GMT
  8. Sender: allbery@ncoast.UUCP
  9. Reply-To: igp@camcon.UUCP (Ian Phillipps)
  10. Organization: Cambridge Consultants Ltd., Cambridge, UK
  11. Lines: 261
  12. Approved: allbery@ncoast.UUCP
  13.  
  14. comp.sources.misc: Volume 3, Issue 55
  15. Submitted-By: "Ian Phillipps" <igp@camcon.UUCP>
  16. Archive-Name: rose
  17.  
  18. This is an amusing toy for Sun console users. If you want to convert it to
  19. some other windowing system, please do. The guts of the mathematics is about
  20. five lines in redraw() - the rest is padding.
  21.  
  22.  
  23. Shell archive - cut here - send the rest to sh, type "make".
  24. #!/bin/sh
  25. # shar:    Shell Archiver  (v1.22)
  26. #
  27. #    Run the following text with /bin/sh to create:
  28. #      rose.c
  29. #      Makefile
  30. #
  31. sed 's/^X//' << 'SHAR_EOF' > rose.c &&
  32. X/* A pretty pixture-drawer @(#)rose.c    1.9
  33. X   This program is supplied as-is, and is certainly not suitable for any
  34. X   purpose.
  35. X   My thanks to Colin Attenborough, whose version on a 6502-based home
  36. X   computer prompted my question "How fast would that run on a Sun?";
  37. X   to the Guardian newspaper for drawing Colin's attention to the algorithm,
  38. X   and to Peter M Maurer of A T & T, whose article "A Rose is a Rose..."
  39. X   in the American Mathematical Monthly (Oct 87, p 631) started it all.
  40. X
  41. X   Ian Phillipps (igp@camcon.uucp), 15 June 1988
  42. X
  43. X   Tested on Sun 3 (SunOS 3.5) and Sun 4 (SunOS 3.2).
  44. X */
  45. X
  46. X#include <stdio.h>
  47. X#include <math.h>
  48. X#include <suntool/sunview.h>
  49. X#include <suntool/canvas.h>
  50. X#include <suntool/panel.h>
  51. X
  52. X/* A greater variety of drawing types is obtained if QUANTUM is composite
  53. X   360 does just fine - it has nothing to do directly with degrees.  */
  54. X#define QUANTUM 360    /* Number of increments in a revolution */
  55. X
  56. X/* Size and Slider_length should be related for a sensible panel layout */
  57. X#define SIZE 700    /* Initial size of canvas (square) */
  58. X#define SLIDER_LENGTH ((QUANTUM-2)/1)
  59. X#define FILL_SCALE    9/10    /* Note absence of brackets (kludge) */
  60. X
  61. Xstatic Frame frame;
  62. Xstatic Panel_item panel_n, panel_d;
  63. Xstatic Canvas canvas;
  64. Xstatic Pixwin *pw;
  65. X
  66. Xstatic double sinx[QUANTUM], cosx[QUANTUM];    /* trig tables */
  67. X
  68. Xenum rect_type { PIXWIN, PIXRECT };
  69. X
  70. Xredraw( type, pw, width, height )
  71. X    enum rect_type type;
  72. X    Pixwin *pw;
  73. X    int width, height;
  74. X{
  75. X    int xoffset = width / 2;
  76. X    int n = (int)panel_get_value( panel_n );
  77. X    int d = (int)panel_get_value( panel_d );
  78. X    int a = 0;
  79. X    int yoffset = height /2;
  80. X    int xscale = xoffset * FILL_SCALE;
  81. X    int yscale = yoffset * FILL_SCALE;
  82. X    int x = xoffset;
  83. X    int y = yoffset;
  84. X    double r = 0.0;
  85. X    int newx = xoffset;
  86. X    int newy = yoffset;
  87. X    /* Black marks to Sun for having two different animals - pixwin and
  88. X       pixrect - which makes this kludge necessary. Maybe you can get a pixwin
  89. X       from a pixrect or vice-versa? */
  90. X    if ( type == PIXWIN )
  91. X    {
  92. X    pw_batch_on( pw );
  93. X    /* clear the window */
  94. X    pw_writebackground(pw, 0, 0, width, height, PIX_SRC );
  95. X    }
  96. X    else
  97. X    pr_rop((struct pixrect*)pw, 0, 0, width, height, PIX_CLR,
  98. X            (struct pixrect*)0, 0, 0 );
  99. X    /* This is the kernel of the whole thing: draw the lines */
  100. X    do
  101. X    {
  102. X    x = newx;
  103. X    y = newy;
  104. X    a = ( a + d ) % QUANTUM;
  105. X    r = sinx[ (n * a ) % QUANTUM ];
  106. X    newx = xoffset + xscale * r * sinx[a];
  107. X    newy = yoffset + yscale * r * cosx[a];
  108. X    if ( type == PIXWIN )
  109. X        pw_vector( pw, x, y, newx, newy, PIX_SRC, 1 );
  110. X    else
  111. X        pr_vector( (struct pixrect*)pw, x, y, newx, newy, PIX_SRC, 1 );
  112. X    }
  113. X    while ( a != 0 );
  114. X    /* unbatch */
  115. X    if ( type == PIXWIN )
  116. X    pw_batch_off( pw );
  117. X}
  118. X
  119. Xredraw_proc()
  120. X{
  121. X    int width = (int)window_get( canvas, WIN_WIDTH );
  122. X    int height = (int)window_get( canvas, WIN_HEIGHT );
  123. X    redraw( PIXWIN, pw, width, height );
  124. X    /* It would be faster to redraw the icon only when necessary - however
  125. X       this makes the program *2 more complicated - need to get involved
  126. X       with Notifiers and all that */
  127. X    redraw_icon();
  128. X}
  129. X
  130. Xredraw_icon()
  131. X{
  132. X    /* get pixrect for icon */
  133. X    Icon icon = (Icon) window_get( frame, FRAME_ICON );
  134. X    Pixrect *pr = (Pixrect*) icon_get( icon, ICON_IMAGE );
  135. X    redraw( PIXRECT, pr, pr->pr_size.x, pr->pr_size.y );
  136. X    icon_set( icon, ICON_IMAGE, pr, 0 );
  137. X    window_set( frame, FRAME_ICON, icon, 0 );
  138. X}
  139. X
  140. X/* procedures to adjust the sliders one step at a time */
  141. Xn_down_proc()
  142. X{
  143. X    int n = (int) panel_get_value( panel_n );
  144. X    panel_set_value( panel_n, (caddr_t)(n-1) );
  145. X    redraw_proc();
  146. X}
  147. X
  148. Xn_up_proc()
  149. X{
  150. X    int n = (int) panel_get_value( panel_n );
  151. X    panel_set_value( panel_n, (caddr_t)(n+1) );
  152. X    redraw_proc();
  153. X}
  154. X
  155. Xd_down_proc()
  156. X{
  157. X    int d = (int) panel_get_value( panel_d );
  158. X    panel_set_value( panel_d, (caddr_t)(d-1) );
  159. X    redraw_proc();
  160. X}
  161. X
  162. Xd_up_proc()
  163. X{
  164. X    int d = (int) panel_get_value( panel_d );
  165. X    panel_set_value( panel_d, (caddr_t)(d+1) );
  166. X    redraw_proc();
  167. X}
  168. X
  169. X
  170. Xquit_proc()
  171. X{
  172. X    exit(0);
  173. X}
  174. X
  175. Xmain( argc, argv )
  176. X    int argc; char **argv;
  177. X{
  178. X    /* open the canvas */
  179. X    Panel panel;
  180. X    struct pixrect *icon_pr = mem_create ( 64, 64, 1 );
  181. X    Icon icon = icon_create( ICON_IMAGE, icon_pr, 0 );
  182. X    frame = window_create( NULL, FRAME,
  183. X                    WIN_HEIGHT, SIZE + 100,
  184. X                    WIN_WIDTH, SIZE,
  185. X                    FRAME_ARGS, argc, argv,
  186. X    FRAME_LABEL, "Rose display program by igp@camcon.uucp  Version 1.9",
  187. X                    FRAME_ICON, icon,
  188. X                    0 );
  189. X    panel = window_create( frame, PANEL,
  190. X                    WIN_WIDTH, SIZE,
  191. X                    0 );
  192. X    /* draw a panel */
  193. X    srand( time((long*)0));
  194. X    panel_n = panel_create_item( panel, PANEL_SLIDER,
  195. X                PANEL_LABEL_STRING, "N ",
  196. X                PANEL_MIN_VALUE, 1,
  197. X                PANEL_SLIDER_WIDTH, SLIDER_LENGTH,
  198. X                PANEL_MAX_VALUE, QUANTUM-1,
  199. X                PANEL_NOTIFY_PROC, redraw_proc,
  200. X                PANEL_VALUE, (rand()/256)%(QUANTUM-2) + 1,
  201. X                0 );
  202. X    panel_create_item( panel, PANEL_BUTTON,
  203. X                PANEL_LABEL_IMAGE,
  204. X            panel_button_image( panel, "down", 0, (Pixfont *) 0 ),
  205. X                PANEL_NOTIFY_PROC, n_down_proc,
  206. X                0 );
  207. X    panel_create_item( panel, PANEL_BUTTON,
  208. X                PANEL_LABEL_IMAGE,
  209. X            panel_button_image( panel, "up", 0, (Pixfont *) 0 ),
  210. X                PANEL_NOTIFY_PROC, n_up_proc,
  211. X                0 );
  212. X    panel_d = panel_create_item( panel, PANEL_SLIDER,
  213. X                PANEL_LABEL_STRING, "D ",
  214. X                PANEL_MIN_VALUE, 1,
  215. X                PANEL_SLIDER_WIDTH, SLIDER_LENGTH,
  216. X                PANEL_MAX_VALUE, QUANTUM-1,
  217. X                PANEL_VALUE, (rand()/256)%(QUANTUM-2) + 1,
  218. X                PANEL_NOTIFY_PROC, redraw_proc,
  219. X                0 );
  220. X    panel_create_item( panel, PANEL_BUTTON,
  221. X                PANEL_LABEL_IMAGE,
  222. X            panel_button_image( panel, "down", 0, (Pixfont *) 0 ),
  223. X                PANEL_NOTIFY_PROC, d_down_proc,
  224. X                0 );
  225. X    panel_create_item( panel, PANEL_BUTTON,
  226. X                PANEL_LABEL_IMAGE,
  227. X            panel_button_image( panel, "up", 0, (Pixfont *) 0 ),
  228. X                PANEL_NOTIFY_PROC, d_up_proc,
  229. X                0 );
  230. X    panel_create_item(panel, PANEL_BUTTON,
  231. X                      PANEL_LABEL_IMAGE,
  232. X                      panel_button_image(panel, "quit", 0, (Pixfont *) 0),
  233. X                      PANEL_NOTIFY_PROC, quit_proc,
  234. X                      0);
  235. X    window_fit_height( panel );
  236. X    canvas = window_create( frame, CANVAS,
  237. X                WIN_BELOW, panel,
  238. X                WIN_X, 0,
  239. X                WIN_HEIGHT, SIZE,
  240. X                WIN_WIDTH, SIZE,
  241. X                CANVAS_FIXED_IMAGE, FALSE,
  242. X                CANVAS_REPAINT_PROC, redraw_proc,
  243. X                0 );
  244. X    pw = canvas_pixwin( canvas );
  245. X    window_fit(frame);
  246. X    /* precompute trig stuff */
  247. X    { int i;
  248. X    for ( i=0; i<QUANTUM; i++ )
  249. X    {
  250. X        sinx[i] = sin(i*(2*M_PI/QUANTUM));
  251. X        cosx[i] = cos(i*(2*M_PI/QUANTUM));
  252. X    }
  253. X    }
  254. X    redraw_icon();
  255. X    window_main_loop(frame);
  256. X    exit(0);
  257. X}
  258. SHAR_EOF
  259. chmod 0644 rose.c || echo "restore of rose.c fails"
  260. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  261. XLDFLAGS=-lsuntool -lsunwindow -lpixrect -lm
  262. XCFLAGS=-O
  263. X
  264. X# This is only necessary because of a stupidity in Sun's default.mk which
  265. X# puts LDFLAGS too early in the line
  266. Xrose: rose.c
  267. X    $(CC) $(CFLAGS) -o $@ $? $(LDFLAGS)
  268. SHAR_EOF
  269. chmod 0644 Makefile || echo "restore of Makefile fails"
  270. exit 0
  271. -- 
  272. UUCP:  ...!ukc!camcon!igp | Cambridge Consultants Ltd  |  Ian Phillipps
  273. or:    igp@camcon.uucp    | Science Park, Milton Road  |-----------------
  274. Phone: +44 223 358855     | Cambridge CB4 4DW, England |
  275.