home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 2 / DATAFILE_PDCD2.iso / utilities2 / _penrose / !penrose / c / Penrose < prev   
Encoding:
Text File  |  1991-06-05  |  8.5 KB  |  291 lines

  1. /* > C.Penrose
  2.  * 
  3.  * Title:    Penrose Purpose:  Display Penrose tiles Called from Control */
  4.  
  5. /* (C) D McQuillan 1984    */
  6. /* Design by Roger Penrose */
  7.  
  8. /* Examples of designs using a */
  9. /* pair of tiles which cannot  */
  10. /* tile periodically.          */
  11. /* Scientific American Jan '77 */
  12.  
  13. #include<math.h>
  14.  
  15. #include "wimp.h"               /* access to WIMP SWIs                      */
  16. #include "coords.h"             /* coordinate conversion functions          */
  17. #include "bbc.h"                /* olde-style graphics routines             */
  18.  
  19. #include "Display.h"
  20.  
  21. display_datas display_data;
  22.  
  23. char display_name[] = "Penrose";
  24.  
  25. #define PI 3.14159273
  26.  
  27. extern int MulScale(int m1, int m2, int scale);
  28. #define FSCALE 0x1000000
  29. #define DSCALE 0x100
  30.  
  31. static int dn;
  32. static int t36, t72, p, pm1, mp2;
  33.  
  34. static void F1(display_datas *d, int xa, int ya, int xb, int yb, int side, int D);
  35. static void F2(display_datas *d, int xa, int ya, int xb, int yb, int side, int D);
  36.  
  37. void display_init(int type)
  38. {
  39.     t36 = FSCALE * tan(PI / 5);
  40.     t72 = FSCALE * tan(2 * PI / 5);
  41.     p = FSCALE * ((sqrt(5) + 1) / 2);
  42.     pm1 = p - FSCALE;
  43.     mp2 = FSCALE * 2 - p;
  44.  
  45.     dn = type % 6;
  46. }
  47.  
  48. void display_menu(void)
  49. {
  50.     /*
  51.      * printf("Penrose Tiles\n\n");
  52.      * printf(" prototype figures are deflated.\n\n");
  53.      * printf("  The DESIGNs are:\n");
  54.      * printf(" 1 - Penrose's Kites and Darts\n");
  55.      * printf(" 2 - Gingerbread Men\n");
  56.      * printf(" 3 - Roman Tiles\n");
  57.      * printf(" 4 - Curves, show pentagonal f||m\n");
  58.      * printf(" 5 - Solid rhombuses\n\n");
  59.      * 
  60.      * do { printf("DESIGN (1..5)? "); scanf("%d", &dn); } while (dn < 1 || dn > 5);
  61.      */
  62. }
  63.  
  64. void display_show(display_datas *display, wimp_redrawstr *r)
  65. {
  66.     coords_cvtstr *cvt = (coords_cvtstr *)&r->box;
  67.     int p1, p2, m, D;
  68.  
  69.     display->x0 = DSCALE * r->g.x0;
  70.     display->y0 = DSCALE * r->g.y0;
  71.     display->x1 = DSCALE * r->g.x1;
  72.     display->y1 = DSCALE * r->g.y1;
  73.  
  74.     p1 = FSCALE * 1;
  75.     p2 = FSCALE * (1 + p) - p1;
  76.     m = 1000000;
  77.     D = 22;
  78.     if (dn == 1 || dn == 3 || dn == 4)
  79.         D = D + 1;
  80.     F1( display,
  81.         DSCALE * coords_x_toscreen(640 - MulScale(m, p1, 24), cvt)+DSCALE/2,
  82.         DSCALE * coords_y_toscreen(512, cvt)+DSCALE/2,
  83.         DSCALE * coords_x_toscreen(640 + MulScale(m, p2, 24), cvt)+DSCALE/2,
  84.         DSCALE * coords_y_toscreen(512, cvt)+DSCALE/2,
  85.         1, D);
  86.     F1( display,
  87.         DSCALE * coords_x_toscreen(640 - MulScale(m, p1, 24), cvt)+DSCALE/2,
  88.         DSCALE * coords_y_toscreen(512, cvt)+DSCALE/2,
  89.         DSCALE * coords_x_toscreen(640 + MulScale(m, p2, 24), cvt)+DSCALE/2,
  90.         DSCALE * coords_y_toscreen(512, cvt)+DSCALE/2,
  91.         -1, D);
  92. }
  93.  
  94. static void F1(display_datas *d, int xa, int ya, int xb, int yb, int side, int D)
  95. {
  96.     int xp, yp;
  97.     xp = (xa + xb + side * MulScale(yb - ya, t36, 24)) / 2;
  98.     yp = (ya + yb - side * MulScale(xb - xa, t36, 24)) / 2;
  99.  
  100. #ifdef TRACE
  101.     printf("F1 %d %d %d %d %d %d %d %d\n", xa, ya, xb, yb, xp, yp, side, D);
  102. #endif
  103.  
  104.     if (xa >= d->x0 && xa <= d->x1 && ya >= d->y0 && ya <= d->y1)
  105.     {
  106.     }
  107.     else if (xa < d->x0 && xb < d->x0 && xp < d->x0)
  108.         return;
  109.     else if (xa > d->x1 && xb > d->x1 && xp > d->x1)
  110.         return;
  111.     else if (ya < d->y0 && yb < d->y0 && yp < d->y0)
  112.         return;
  113.     else if (ya > d->y1 && yb > d->y1 && yp > d->y1)
  114.         return;
  115.  
  116.     if (D == 0)
  117.     {
  118.         int ixa = xa / DSCALE, iya = ya / DSCALE;
  119.         int ixb = xb / DSCALE, iyb = yb / DSCALE;
  120.         int ixp = xp / DSCALE, iyp = yp / DSCALE;
  121.         int ix, iy;
  122. #ifdef TRACE
  123.         return;
  124. #endif
  125.  
  126.         switch (dn)
  127.         {
  128.         case 0:
  129.             ix = (MulScale(xa, pm1, 24) + MulScale(xb, mp2, 24)) / DSCALE;
  130.             iy = (MulScale(ya, pm1, 24) + MulScale(yb, mp2, 24)) / DSCALE;
  131.  
  132.             bbc_move(ixa, iya);
  133.             bbc_draw(ixp, iyp);
  134.             bbc_plot(37, ix, iy);
  135.             if (side > 0)
  136.                 bbc_plot(37, ixb, iyb);
  137.             break;
  138.         case 1:
  139.             ix = (MulScale(xa, pm1, 24) + MulScale(xb, mp2, 24)) / DSCALE;
  140.             iy = (MulScale(ya, pm1, 24) + MulScale(yb, mp2, 24)) / DSCALE;
  141.  
  142.             bbc_gcol(0, 15);
  143.             bbc_move(ix, iy);
  144.             bbc_move(ixp, iyp);
  145.             bbc_plot(85, ixa, iya);
  146.             bbc_gcol(0, 7);
  147.             bbc_draw(ixp, iyp);
  148.             bbc_plot(37, ix, iy);
  149.             if (side > 0)
  150.                 bbc_plot(37, ixb, iyb);
  151.             break;
  152.         case 2:
  153.             bbc_gcol(0, 11);
  154.             bbc_move((3 * ixp + ixb) / 4, (3 * iyp + iyb) / 4);
  155.             bbc_move((ixb + ixp) / 2, (iyb + iyp) / 2);
  156.             bbc_plot(85, (ixa + ixb) / 2, (iya + iyb) / 2);
  157.             bbc_move((2 * ixa + ixp) / 3, (2 * iya + iyp) / 3);
  158.             bbc_plot(85, ixa, iya);
  159.             bbc_gcol(0, 7);
  160.             break;
  161.         case 3:
  162.             bbc_gcol(0, 13);
  163.             bbc_move(ixp, iyp);
  164.             bbc_move((ixa + ixb) / 2, (iya + iyb) / 2);
  165.             bbc_plot(85, (ixp + ixb) / 2, (iyp + iyb) / 2);
  166.             bbc_plot(85, (3 * ixb + ixa) / 4, (3 * iyb + iya) / 4);
  167.             bbc_move((3 * ixa + ixb) / 4, (3 * iya + iyb) / 4);
  168.             bbc_move((ixa + ixp) / 2, (iya + iyp) / 2);
  169.             bbc_plot(85, ixa, iya);
  170.             bbc_gcol(0, 7);
  171.             break;
  172.         case 4:
  173.             bbc_move((2 * ixp + ixb) / 3, (2 * iyp + iyb) / 3);
  174.             bbc_draw((ixa + 3 * ixp) / 4, (iya + 3 * iyp) / 4);
  175.             break;
  176.         case 5:
  177.             bbc_move(ixa, iya);
  178.             bbc_draw(ixp, iyp);
  179.             bbc_draw(ixb, iyb);
  180.             break;
  181.         }
  182.     }
  183.     else
  184.     {
  185.         F2(d, xp, yp,
  186.            MulScale(xp, pm1, 24) + MulScale(xb, mp2, 24),
  187.            MulScale(yp, pm1, 24) + MulScale(yb, mp2, 24),
  188.            -side, D - 1);
  189.         F1(d, xp, yp, xa, ya, side, D - 1);
  190.         F1(d, xb, yb,
  191.            MulScale(xa, pm1, 24) + MulScale(xb, mp2, 24),
  192.            MulScale(ya, pm1, 24) + MulScale(yb, mp2, 24),
  193.            -side, D - 1);
  194.     }
  195. }
  196.  
  197. static void F2(display_datas *d, int xa, int ya, int xb, int yb, int side, int D)
  198. {
  199.     int xp, yp;
  200.  
  201.     xp = (xa + xb + side * MulScale(yb - ya, t72, 24)) / 2;
  202.     yp = (ya + yb - side * MulScale(xb - xa, t72, 24)) / 2;
  203.  
  204. #ifdef TRACE
  205.     printf("F2 %d %d %d %d %d %d %d %d\n", xa, ya, xb, yb, xp, yp, side, D);
  206. #endif
  207.  
  208.     if (xa >= d->x0 && xa <= d->x1 && ya >= d->y0 && ya <= d->y1)
  209.     {
  210.     }
  211.     else if (xa < d->x0 && xb < d->x0 && xp < d->x0)
  212.         return;
  213.     else if (xa > d->x1 && xb > d->x1 && xp > d->x1)
  214.         return;
  215.     else if (ya < d->y0 && yb < d->y0 && yp < d->y0)
  216.         return;
  217.     else if (ya > d->y1 && yb > d->y1 && yp > d->y1)
  218.         return;
  219.  
  220.     if (D == 0)
  221.     {
  222.         int ixa = xa / DSCALE, iya = ya / DSCALE;
  223.         int ixb = xb / DSCALE, iyb = yb / DSCALE;
  224.         int ixp = xp / DSCALE, iyp = yp / DSCALE;
  225.  
  226. #ifdef TRACE
  227.         return;
  228. #endif
  229.  
  230.         switch (dn)
  231.         {
  232.         case 0:
  233.             if (side > 0)
  234.             {
  235.                 bbc_move(ixb, iyb);
  236.                 bbc_plot(13, ixa, iya);
  237.                 bbc_draw(ixp, iyp);
  238.             }
  239.             break;
  240.         case 1:
  241.             if (side > 0)
  242.             {
  243.                 bbc_move(ixb, iyb);
  244.                 bbc_plot(13, ixa, iya);
  245.                 bbc_draw(ixp, iyp);
  246.             }
  247.             break;
  248.         case 2:
  249.             bbc_gcol(0, 9);
  250.             bbc_move((3 * ixb + ixp) / 4, (3 * iyb + iyp) / 4);
  251.             bbc_move((ixb + ixp) / 2, (iyb + iyp) / 2);
  252.             bbc_plot(85, (ixa + ixb) / 2, (iya + iyb) / 2);
  253.             bbc_plot(85, (2 * ixa + ixp) / 3, (2 * iya + iyp) / 3);
  254.             bbc_plot(85, ixa, iya);
  255.             bbc_gcol(0, 7);
  256.             break;
  257.         case 3:
  258.             bbc_gcol(0, 13);
  259.             bbc_move(ixb, iyb);
  260.             bbc_move((ixb + ixp) / 2, (iyb + iyp) / 2);
  261.             bbc_plot(85, (ixa + 3 * ixb) / 4, (iya + 3 * iyb) / 4);
  262.             bbc_move((3 * ixa + ixb) / 4, (3 * iya + iyb) / 4);
  263.             bbc_move((ixa + ixp) / 2, (iya + iyp) / 2);
  264.             bbc_plot(85, ixa, iya);
  265.             bbc_gcol(0, 7);
  266.             break;
  267.         case 4:
  268.             bbc_move((ixp + 2 * ixb) / 3, (iyp + 2 * iyb) / 3);
  269.             bbc_draw((ixa + 3 * ixp) / 4, (iya + 3 * iyp) / 4);
  270.             break;
  271.         case 5:
  272.             bbc_gcol(0, 14);
  273.             bbc_move(ixa, iya);
  274.             bbc_move(ixp, iyp);
  275.             bbc_plot(85, ixb, iyb);
  276.             bbc_gcol(0, 7);
  277.             bbc_draw(ixp, iyp);
  278.             bbc_draw(ixa, iya);
  279.             break;
  280.         }
  281.     }
  282.     else
  283.     {
  284.         F1(d, xp, yp, xa, ya, side, D - 1);
  285.         F2(d, xb, yb,
  286.            MulScale(xb, pm1, 24) + MulScale(xp, mp2, 24),
  287.            MulScale(yb, pm1, 24) + MulScale(yp, mp2, 24),
  288.            side, D - 1);
  289.     }
  290. }
  291.