home *** CD-ROM | disk | FTP | other *** search
- /* > C.Penrose
- *
- * Title: Penrose Purpose: Display Penrose tiles Called from Control */
-
- /* (C) D McQuillan 1984 */
- /* Design by Roger Penrose */
-
- /* Examples of designs using a */
- /* pair of tiles which cannot */
- /* tile periodically. */
- /* Scientific American Jan '77 */
-
- #include<math.h>
-
- #include "wimp.h" /* access to WIMP SWIs */
- #include "coords.h" /* coordinate conversion functions */
- #include "bbc.h" /* olde-style graphics routines */
-
- #include "Display.h"
-
- display_datas display_data;
-
- char display_name[] = "Penrose";
-
- #define PI 3.14159273
-
- extern int MulScale(int m1, int m2, int scale);
- #define FSCALE 0x1000000
- #define DSCALE 0x100
-
- static int dn;
- static int t36, t72, p, pm1, mp2;
-
- static void F1(display_datas *d, int xa, int ya, int xb, int yb, int side, int D);
- static void F2(display_datas *d, int xa, int ya, int xb, int yb, int side, int D);
-
- void display_init(int type)
- {
- t36 = FSCALE * tan(PI / 5);
- t72 = FSCALE * tan(2 * PI / 5);
- p = FSCALE * ((sqrt(5) + 1) / 2);
- pm1 = p - FSCALE;
- mp2 = FSCALE * 2 - p;
-
- dn = type % 6;
- }
-
- void display_menu(void)
- {
- /*
- * printf("Penrose Tiles\n\n");
- * printf(" prototype figures are deflated.\n\n");
- * printf(" The DESIGNs are:\n");
- * printf(" 1 - Penrose's Kites and Darts\n");
- * printf(" 2 - Gingerbread Men\n");
- * printf(" 3 - Roman Tiles\n");
- * printf(" 4 - Curves, show pentagonal f||m\n");
- * printf(" 5 - Solid rhombuses\n\n");
- *
- * do { printf("DESIGN (1..5)? "); scanf("%d", &dn); } while (dn < 1 || dn > 5);
- */
- }
-
- void display_show(display_datas *display, wimp_redrawstr *r)
- {
- coords_cvtstr *cvt = (coords_cvtstr *)&r->box;
- int p1, p2, m, D;
-
- display->x0 = DSCALE * r->g.x0;
- display->y0 = DSCALE * r->g.y0;
- display->x1 = DSCALE * r->g.x1;
- display->y1 = DSCALE * r->g.y1;
-
- p1 = FSCALE * 1;
- p2 = FSCALE * (1 + p) - p1;
- m = 1000000;
- D = 22;
- if (dn == 1 || dn == 3 || dn == 4)
- D = D + 1;
- F1( display,
- DSCALE * coords_x_toscreen(640 - MulScale(m, p1, 24), cvt)+DSCALE/2,
- DSCALE * coords_y_toscreen(512, cvt)+DSCALE/2,
- DSCALE * coords_x_toscreen(640 + MulScale(m, p2, 24), cvt)+DSCALE/2,
- DSCALE * coords_y_toscreen(512, cvt)+DSCALE/2,
- 1, D);
- F1( display,
- DSCALE * coords_x_toscreen(640 - MulScale(m, p1, 24), cvt)+DSCALE/2,
- DSCALE * coords_y_toscreen(512, cvt)+DSCALE/2,
- DSCALE * coords_x_toscreen(640 + MulScale(m, p2, 24), cvt)+DSCALE/2,
- DSCALE * coords_y_toscreen(512, cvt)+DSCALE/2,
- -1, D);
- }
-
- static void F1(display_datas *d, int xa, int ya, int xb, int yb, int side, int D)
- {
- int xp, yp;
- xp = (xa + xb + side * MulScale(yb - ya, t36, 24)) / 2;
- yp = (ya + yb - side * MulScale(xb - xa, t36, 24)) / 2;
-
- #ifdef TRACE
- printf("F1 %d %d %d %d %d %d %d %d\n", xa, ya, xb, yb, xp, yp, side, D);
- #endif
-
- if (xa >= d->x0 && xa <= d->x1 && ya >= d->y0 && ya <= d->y1)
- {
- }
- else if (xa < d->x0 && xb < d->x0 && xp < d->x0)
- return;
- else if (xa > d->x1 && xb > d->x1 && xp > d->x1)
- return;
- else if (ya < d->y0 && yb < d->y0 && yp < d->y0)
- return;
- else if (ya > d->y1 && yb > d->y1 && yp > d->y1)
- return;
-
- if (D == 0)
- {
- int ixa = xa / DSCALE, iya = ya / DSCALE;
- int ixb = xb / DSCALE, iyb = yb / DSCALE;
- int ixp = xp / DSCALE, iyp = yp / DSCALE;
- int ix, iy;
- #ifdef TRACE
- return;
- #endif
-
- switch (dn)
- {
- case 0:
- ix = (MulScale(xa, pm1, 24) + MulScale(xb, mp2, 24)) / DSCALE;
- iy = (MulScale(ya, pm1, 24) + MulScale(yb, mp2, 24)) / DSCALE;
-
- bbc_move(ixa, iya);
- bbc_draw(ixp, iyp);
- bbc_plot(37, ix, iy);
- if (side > 0)
- bbc_plot(37, ixb, iyb);
- break;
- case 1:
- ix = (MulScale(xa, pm1, 24) + MulScale(xb, mp2, 24)) / DSCALE;
- iy = (MulScale(ya, pm1, 24) + MulScale(yb, mp2, 24)) / DSCALE;
-
- bbc_gcol(0, 15);
- bbc_move(ix, iy);
- bbc_move(ixp, iyp);
- bbc_plot(85, ixa, iya);
- bbc_gcol(0, 7);
- bbc_draw(ixp, iyp);
- bbc_plot(37, ix, iy);
- if (side > 0)
- bbc_plot(37, ixb, iyb);
- break;
- case 2:
- bbc_gcol(0, 11);
- bbc_move((3 * ixp + ixb) / 4, (3 * iyp + iyb) / 4);
- bbc_move((ixb + ixp) / 2, (iyb + iyp) / 2);
- bbc_plot(85, (ixa + ixb) / 2, (iya + iyb) / 2);
- bbc_move((2 * ixa + ixp) / 3, (2 * iya + iyp) / 3);
- bbc_plot(85, ixa, iya);
- bbc_gcol(0, 7);
- break;
- case 3:
- bbc_gcol(0, 13);
- bbc_move(ixp, iyp);
- bbc_move((ixa + ixb) / 2, (iya + iyb) / 2);
- bbc_plot(85, (ixp + ixb) / 2, (iyp + iyb) / 2);
- bbc_plot(85, (3 * ixb + ixa) / 4, (3 * iyb + iya) / 4);
- bbc_move((3 * ixa + ixb) / 4, (3 * iya + iyb) / 4);
- bbc_move((ixa + ixp) / 2, (iya + iyp) / 2);
- bbc_plot(85, ixa, iya);
- bbc_gcol(0, 7);
- break;
- case 4:
- bbc_move((2 * ixp + ixb) / 3, (2 * iyp + iyb) / 3);
- bbc_draw((ixa + 3 * ixp) / 4, (iya + 3 * iyp) / 4);
- break;
- case 5:
- bbc_move(ixa, iya);
- bbc_draw(ixp, iyp);
- bbc_draw(ixb, iyb);
- break;
- }
- }
- else
- {
- F2(d, xp, yp,
- MulScale(xp, pm1, 24) + MulScale(xb, mp2, 24),
- MulScale(yp, pm1, 24) + MulScale(yb, mp2, 24),
- -side, D - 1);
- F1(d, xp, yp, xa, ya, side, D - 1);
- F1(d, xb, yb,
- MulScale(xa, pm1, 24) + MulScale(xb, mp2, 24),
- MulScale(ya, pm1, 24) + MulScale(yb, mp2, 24),
- -side, D - 1);
- }
- }
-
- static void F2(display_datas *d, int xa, int ya, int xb, int yb, int side, int D)
- {
- int xp, yp;
-
- xp = (xa + xb + side * MulScale(yb - ya, t72, 24)) / 2;
- yp = (ya + yb - side * MulScale(xb - xa, t72, 24)) / 2;
-
- #ifdef TRACE
- printf("F2 %d %d %d %d %d %d %d %d\n", xa, ya, xb, yb, xp, yp, side, D);
- #endif
-
- if (xa >= d->x0 && xa <= d->x1 && ya >= d->y0 && ya <= d->y1)
- {
- }
- else if (xa < d->x0 && xb < d->x0 && xp < d->x0)
- return;
- else if (xa > d->x1 && xb > d->x1 && xp > d->x1)
- return;
- else if (ya < d->y0 && yb < d->y0 && yp < d->y0)
- return;
- else if (ya > d->y1 && yb > d->y1 && yp > d->y1)
- return;
-
- if (D == 0)
- {
- int ixa = xa / DSCALE, iya = ya / DSCALE;
- int ixb = xb / DSCALE, iyb = yb / DSCALE;
- int ixp = xp / DSCALE, iyp = yp / DSCALE;
-
- #ifdef TRACE
- return;
- #endif
-
- switch (dn)
- {
- case 0:
- if (side > 0)
- {
- bbc_move(ixb, iyb);
- bbc_plot(13, ixa, iya);
- bbc_draw(ixp, iyp);
- }
- break;
- case 1:
- if (side > 0)
- {
- bbc_move(ixb, iyb);
- bbc_plot(13, ixa, iya);
- bbc_draw(ixp, iyp);
- }
- break;
- case 2:
- bbc_gcol(0, 9);
- bbc_move((3 * ixb + ixp) / 4, (3 * iyb + iyp) / 4);
- bbc_move((ixb + ixp) / 2, (iyb + iyp) / 2);
- bbc_plot(85, (ixa + ixb) / 2, (iya + iyb) / 2);
- bbc_plot(85, (2 * ixa + ixp) / 3, (2 * iya + iyp) / 3);
- bbc_plot(85, ixa, iya);
- bbc_gcol(0, 7);
- break;
- case 3:
- bbc_gcol(0, 13);
- bbc_move(ixb, iyb);
- bbc_move((ixb + ixp) / 2, (iyb + iyp) / 2);
- bbc_plot(85, (ixa + 3 * ixb) / 4, (iya + 3 * iyb) / 4);
- bbc_move((3 * ixa + ixb) / 4, (3 * iya + iyb) / 4);
- bbc_move((ixa + ixp) / 2, (iya + iyp) / 2);
- bbc_plot(85, ixa, iya);
- bbc_gcol(0, 7);
- break;
- case 4:
- bbc_move((ixp + 2 * ixb) / 3, (iyp + 2 * iyb) / 3);
- bbc_draw((ixa + 3 * ixp) / 4, (iya + 3 * iyp) / 4);
- break;
- case 5:
- bbc_gcol(0, 14);
- bbc_move(ixa, iya);
- bbc_move(ixp, iyp);
- bbc_plot(85, ixb, iyb);
- bbc_gcol(0, 7);
- bbc_draw(ixp, iyp);
- bbc_draw(ixa, iya);
- break;
- }
- }
- else
- {
- F1(d, xp, yp, xa, ya, side, D - 1);
- F2(d, xb, yb,
- MulScale(xb, pm1, 24) + MulScale(xp, mp2, 24),
- MulScale(yb, pm1, 24) + MulScale(yp, mp2, 24),
- side, D - 1);
- }
- }
-