home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / dos / fraktale / fracxtr6.exe / OTHER / IFSSPELL.ZIP / IFSSPELL.C < prev    next >
C/C++ Source or Header  |  1993-10-19  |  12KB  |  418 lines

  1. /****************************************************************/
  2. /* ifsspell.c - generates ifs matrix entry readable by fractint */
  3. /****************************************************************/
  4. /* Written by Wesley B. Loewer, Copyright 1994.                 */
  5. /****************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <ctype.h>
  10. #include <math.h>
  11.  
  12. #define PI                      3.141592653589793
  13. #define MAX_AFFINES_PER_LETTER  5
  14. #define MAX_STRING_LENGTH       40
  15. #define SPELL_IFS_FILENAME      "spell.ifs"
  16. #define IFS_ENTRY_FORMAT        "% -9.5f"
  17. #define FRACTINT_SCALING_FACTOR  10
  18. #define NO_MATCH                 -1
  19.  
  20. char *string;
  21. double spacing=2;
  22. double total_area, total_width, total_height=10;
  23. FILE *spell_ifs;
  24.  
  25. struct affine_struct
  26.     {
  27.     double width, height;
  28.     double rot_angle, skew_angle; /* in degrees */
  29.     double horiz_shift, vert_shift; /* after rotations */
  30.     };
  31.  
  32. struct letter_struct
  33.     {
  34.     char letter;
  35.     int affine_num;
  36.     double width;
  37.     struct affine_struct affines[MAX_AFFINES_PER_LETTER];
  38.     /* calculated */
  39.     double area;
  40.     };
  41.  
  42. struct letter_struct letters[] =
  43.     {
  44.         {'A', 3, 8, {{10, 2, 78.7, 11.3, 2, 0},
  45.                      {10, 2, -78.7, -11.3, 4, 10},
  46.                      {2, 1.5, 0, 0, 3, 4.5},
  47.                }
  48.         },
  49.  
  50.         {'B', 5, 6, {{10, 2, 90, 0, 2, 0},
  51.                      {3.2, 2, -51.3, -38.7, 2, 10},
  52.                      {3.2, 2, -128.7, 38.7, 4, 7.5},
  53.                      {3.2, 2, -51.3, -38.7, 2, 5},
  54.                      {3.2, 2, -128.7, 38.7, 4, 2.5},
  55.                     }
  56.         },
  57.  
  58.         {'C', 3, 6, {{6, 2, 0, 0, 0, 8},
  59.                      {6, 2, 180, 0, 6, 2},
  60.                      {6, 2, 90, 0, 2, 2},
  61.                     }
  62.         },
  63.  
  64.         {'D', 4, 6, {{10, 2, 90, 0, 2, 0},
  65.                      {4, 2, 0, 45, 2, 8},
  66.                      {6, 2, -90, 0, 4, 8},
  67.                      {4, 2, 0, -45, 0, 0},
  68.                     }
  69.         },     
  70.  
  71.         {'E', 4, 6, {{6, 2, 0, 0, 0, 8},
  72.                      {6, 2, 0, 0, 0, 0},
  73.                      {4, 2, 0, 0, 2, 4},
  74.                      {6, 2, 90, 0, 2, 2},
  75.                     }
  76.         },
  77.  
  78.         {'F', 3, 6, {{6, 2, 0, 0, 0, 8},
  79.                      {4, 2, 0, 0, 2, 4},
  80.                      {8, 2, 90, 0, 2, 0},
  81.                     }
  82.         },
  83.  
  84.         {'G', 5, 7, {{7, 2, 0, 0, 0, 8},
  85.                      {6, 2, 90, 0, 2, 2},
  86.                      {5, 2, 0, 0, 0, 0},
  87.                      {3, 2, 90, 0, 7, 0},
  88.                      {4, 2, 0, 0, 3, 3},
  89.                     }
  90.         },
  91.  
  92.         {'H', 5, 6, {{4, 2, 90, 0, 2, 0},
  93.                      {4, 2, 90, 0, 2, 6},
  94.                      {6, 2, 0, 0, 0, 4},
  95.                      {4, 2, -90, 0, 4, 10},
  96.                      {4, 2, -90, 0, 4, 4},
  97.                     }
  98.         },
  99.  
  100.         {'I', 1, 2, {{10, 2, 90, 0, 2, 0},
  101.                     }
  102.         },
  103.  
  104.         {'J', 3, 6, {{8, 2, -90, 0, 4, 10},
  105.                      {4, 2, 180, 0, 6, 2},
  106.                      {4, 2, 90, 0, 2, 0},
  107.                     }
  108.         },
  109.  
  110.         {'K', 3, 6, {{10, 2, 90, 0, 2, 0},
  111.                      {5.4, 2, 68.2, 21.8, 4, 5},
  112.                      {5.4, 2, 111.8, -21.8, 6, 0},
  113.                     }
  114.         },
  115.  
  116.         {'L', 2, 6, {{8, 2, 90, 0, 2, 2},
  117.                      {6, 2, 0, 0, 0, 0},
  118.                     }
  119.         },
  120.  
  121.         {'M', 4, 10, {{10, 2, 90, 0, 2, 0},
  122.                       {10.2, 2, -68.2, -21.8, 0, 10},
  123.                       {10.2, 2, 68.2, 21.8, 6, 0},
  124.                       {10, 2, 90, 0, 10, 0},
  125.                      }
  126.         },
  127.  
  128.         {'N', 3, 8, {{10, 2, 90, 0, 2, 0},
  129.                       {10.2, 2, -68.2, -21.8, 1, 10},
  130.                       {10, 2, 90, 0, 8, 0},
  131.                      }
  132.         },
  133.  
  134.         {'O', 4, 6, {{6, 2, 0, 0, 0, 8},
  135.                      {6, 2, 180, 0, 6, 2},
  136.                      {6, 2, 90, 0, 2, 2},
  137.                      {6, 2, -90, 0, 4, 8},
  138.                     }
  139.         },
  140.  
  141.         {'P', 4, 6, {{8.5, 2, 90, 0, 2, 0},
  142.                      {4.5, 1.5, 0, 0, 0, 8.5},
  143.                      {3.5, 1.5, -90, 0, 4.5, 10},
  144.                      {4, 1.5, 0, 0, 2, 5},
  145.                     }
  146.         },
  147.  
  148.         {'Q', 5, 7.5, {{6, 2, 0, 0, 0, 8},
  149.                        {6, 2, 180, 0, 6, 2},
  150.                        {6, 2, 90, 0, 2, 2},
  151.                        {6, 2, -90, 0, 4, 8},
  152.                        {4, 2, -45, 0, 2.5, 1.5},
  153.                       }
  154.         },
  155.  
  156.         {'R', 5, 6, {{8.5, 2, 90, 0, 2, 0},
  157.                      {4.5, 1.5, 0, 0, 0, 8.5},
  158.                      {3.5, 1.5, -90, 0, 4.5, 10},
  159.                      {4, 1.5, 0, 0, 2, 5},
  160.                      {5.47, 2, -66, -24, 2, 5},
  161.                     }
  162.         },
  163.  
  164.         {'S', 5, 6, {{6, 2, 0, 0, 0, 0},
  165.                      {4, 2, 90, 0, 6, 2},
  166.                      {4, 2 ,180, 0, 4, 6},
  167.                      {4, 2, 90, 0, 2, 6},
  168.                      {4, 2, 0, 0, 2, 8},
  169.                     }
  170.         },
  171.  
  172.         {'T', 2, 6, {{8, 2, 90, 0, 4, 0},
  173.                      {6, 2, 0, 0, 0, 8},
  174.                     }
  175.         },
  176.  
  177.         {'U', 3, 6, {{8, 2, -90, 0, 4, 10},
  178.                      {6, 2, 180, 0, 6, 2},
  179.                      {8, 2, 90, 0, 2, 2},
  180.                     }
  181.         },
  182.  
  183.         {'V', 2, 8, {{10.4, 2, -73.3, -16.7, 0, 10},
  184.                      {10.4, 2, 73.3, 16.7, 5, 0},
  185.                     }
  186.         },
  187.  
  188.         {'W', 4, 12, {{10.2, 2, -78.7, -11.3, 0, 10},
  189.                       {6.7, 2, 63.4, 26.6, 4, 0},
  190.                       {6.7, 2, -63.4, -26.6, 5, 6},
  191.                       {10.2, 2, 78.7, 11.3, 10, 0},
  192.                      }
  193.         },
  194.  
  195.         {'X', 2, 7, {{11.2, 2, 63.4, 26.6, 2, 0},
  196.                      {11.2, 2, -63.4, -26.6, 0, 10},
  197.                     }
  198.         },
  199.  
  200.         {'Y', 3, 8, {{5, 2, 90, 0, 5, 0},
  201.                      {5.83, 2, 59, 31, 5, 5},
  202.                      {5.83, 2, -59, -31, 0, 10},
  203.                     }
  204.         },
  205.  
  206.         {'Z', 3, 6, {{6, 2, 0, 0, 0, 0},
  207.                      {6, 2, 0, 0, 0, 8},
  208.                      {7.2, 2, 56.3, 33.7, 2, 2},
  209.                     }
  210.         },
  211.  
  212.         {'-', 1, 6, {{6, 2, 0, 0, 0, 4},
  213.                     }
  214.         },
  215.  
  216.         {'+', 2, 6, {{6, 2, 0, 0, 0, 4},
  217.                      {6, 2, 90, 0, 4, 2},
  218.                     }
  219.         },
  220.  
  221.         {'=', 2, 6, {{6, 2, 0, 0, 0, 6},
  222.                      {6, 2, 0, 0, 0, 2},
  223.                     }
  224.         },
  225.  
  226.         {'/', 1, 7, {{11.2, 2, 63.4, 26.6, 2, 0},
  227.                     }
  228.         },
  229.  
  230.         {'\\', 1, 7, {{11.2, 2, -63.4, -26.6, 0, 10},
  231.                      }
  232.         },
  233.  
  234.         {'!', 2, 2, {{6, 2, 90, 0, 2, 4},
  235.                      {2, 2, 0, 0, 0, 0},
  236.                     }
  237.         },
  238.  
  239.         {'?', 5, 6, {{2, 2, 90, 0, 2, 6},
  240.                      {4, 2, 0, 0, 0, 8},
  241.                      {4, 2, -90, 0, 4, 10},
  242.                      {3.6, 2, -123.7, 33.7, 4, 6},
  243.                      {2, 2, 0, 0, 2, 0},
  244.                     }
  245.         },
  246.  
  247.         {'_', 0, 4}, /* to be used as a space character */
  248.  
  249.         {'\0' /* terminating character */
  250.         }
  251.     };
  252.  
  253.  
  254. /* these could be all calculated at compile time, but I'm much too lazy. */
  255. void init_letters(void)
  256.     {
  257.     int l, a;
  258.  
  259.     l=0;
  260.     while (letters[l].letter != '\0')
  261.         {
  262.         letters[l].area = 0;
  263.         for (a=0; a<letters[l].affine_num; a++)
  264.             {
  265.             letters[l].affines[a].width /= FRACTINT_SCALING_FACTOR;
  266.             letters[l].affines[a].height /= FRACTINT_SCALING_FACTOR;
  267.             letters[l].affines[a].horiz_shift /= FRACTINT_SCALING_FACTOR;
  268.             letters[l].affines[a].vert_shift /= FRACTINT_SCALING_FACTOR;
  269.             letters[l].area += letters[l].affines[a].width * letters[l].affines[a].height;
  270.             }
  271.         letters[l].width /= FRACTINT_SCALING_FACTOR;
  272.         l++;
  273.         }
  274.     spacing /= FRACTINT_SCALING_FACTOR;
  275.     total_height /= FRACTINT_SCALING_FACTOR;
  276.     }
  277.  
  278. int get_letter(int c)
  279.     {
  280.     int l=0;
  281.  
  282.     while (letters[l].letter != (char)c && letters[l].letter != '\0')
  283.         l++;
  284.     return letters[l].letter != '\0' ? l : NO_MATCH;
  285.     }
  286.  
  287. void get_totals(void)
  288.     {
  289.     int c;
  290.     int i, l;
  291.  
  292.     total_area = 0;
  293.     total_width = 0;
  294.     i = 0;
  295.     while ((c=string[i]) != '\0')
  296.         {
  297.         l = get_letter(toupper(c));
  298.         if (l != NO_MATCH)
  299.             {
  300.             total_area += letters[l].area;
  301.             total_width += letters[l].width + spacing;
  302.             }
  303.         i++;
  304.         }
  305.     }
  306.  
  307. void process_string(void)
  308.     {
  309.     int c;
  310.     int i, l, a;
  311.     double pos, xscale, yscale, tan_phi, sin_theta, cos_theta, xshift, yshift, prob;
  312.     struct affine_struct af;
  313.  
  314.     get_totals();
  315.     if (total_area == 0 || total_width == 0)
  316.         {
  317.         printf("Error: nothing to print\n");
  318.         exit (3);
  319.         }
  320.  
  321.     pos = spacing/2;
  322.     fprintf(spell_ifs,"%s  { ; generated by ifsspell\n",string);
  323.     i = 0;
  324.     while ((c=string[i]) !=0)
  325.         {
  326.         l = get_letter(toupper(c));
  327.         if (l != NO_MATCH)
  328.             {
  329.             for (a=0; a<letters[l].affine_num; a++)
  330.                 {
  331.                 af = letters[l].affines[a]; /* just to make life easier */
  332.  
  333.                 xscale = af.width / total_width;
  334.                 yscale = af.height / total_height;
  335.  
  336.                 tan_phi = -tan(PI/180*af.skew_angle);
  337.                 sin_theta = sin(PI/180*af.rot_angle);
  338.                 cos_theta = cos(PI/180*af.rot_angle);
  339.                 prob = af.width * af.height / total_area;
  340.                 xshift = af.horiz_shift+pos;
  341.                 yshift = af.vert_shift;
  342.  
  343.                 /* rotation_matrix * skew_matrix * scale_matrix * [x,y] + trans_matrix */
  344.  
  345.                 /* a term */
  346.                 fprintf(spell_ifs,IFS_ENTRY_FORMAT, xscale * cos_theta);
  347.  
  348.                 /* b term */
  349.                 fprintf(spell_ifs,IFS_ENTRY_FORMAT, yscale * (cos_theta*tan_phi - sin_theta));
  350.  
  351.                 /* c term */
  352.                 fprintf(spell_ifs,IFS_ENTRY_FORMAT, xscale * sin_theta);
  353.  
  354.                 /* d term */
  355.                 fprintf(spell_ifs,IFS_ENTRY_FORMAT, yscale * (sin_theta*tan_phi + cos_theta));
  356.  
  357.                 /* e term */
  358.                 fprintf(spell_ifs,IFS_ENTRY_FORMAT, xshift);
  359.  
  360.                 /* f term */
  361.                 fprintf(spell_ifs,IFS_ENTRY_FORMAT, yshift);
  362.  
  363.                 /* p term */
  364.                 fprintf(spell_ifs,IFS_ENTRY_FORMAT"\n", prob);
  365.                 }
  366.             pos += letters[l].width + spacing;
  367.             }
  368.         fprintf(spell_ifs,"\n"); /* separate letters with an extra line */
  369.         i++;
  370.         }
  371.     fprintf(spell_ifs,"}\n\n");
  372.     }
  373.  
  374.  
  375.  
  376. void init_spell_ifs_file(void)
  377.     {
  378. #ifdef DEBUG
  379.     spell_ifs = fopen(SPELL_IFS_FILENAME, "wt");
  380. #else
  381.     spell_ifs = fopen(SPELL_IFS_FILENAME, "at");
  382. #endif
  383.     if (spell_ifs == NULL)
  384.         {
  385.         printf("Error opening %s\n", SPELL_IFS_FILENAME);
  386.         exit (2);
  387.         }
  388.     }
  389.  
  390. void close_spell_ifs_file(void)
  391.     {
  392.     fclose(spell_ifs);
  393.     }
  394.  
  395. main(int argc, char *argv[])
  396.     {
  397.     int c;
  398.     int l;
  399.  
  400.     if (argc < 2)
  401.         {
  402.         printf("Usage: ifsspell string\n"
  403.                "available characters: ");
  404.         l = 0;
  405.         while ((c=letters[l++].letter) != '\0')
  406.             putchar(c);
  407.         putchar('\n');
  408.         return 1;
  409.         }
  410.  
  411.     init_letters();
  412.     string = argv[1];
  413.     init_spell_ifs_file();
  414.     process_string();
  415.     close_spell_ifs_file();
  416.     return 0;
  417.     }
  418.