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 >
Wrap
C/C++ Source or Header
|
1993-10-19
|
12KB
|
418 lines
/****************************************************************/
/* ifsspell.c - generates ifs matrix entry readable by fractint */
/****************************************************************/
/* Written by Wesley B. Loewer, Copyright 1994. */
/****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#define PI 3.141592653589793
#define MAX_AFFINES_PER_LETTER 5
#define MAX_STRING_LENGTH 40
#define SPELL_IFS_FILENAME "spell.ifs"
#define IFS_ENTRY_FORMAT "% -9.5f"
#define FRACTINT_SCALING_FACTOR 10
#define NO_MATCH -1
char *string;
double spacing=2;
double total_area, total_width, total_height=10;
FILE *spell_ifs;
struct affine_struct
{
double width, height;
double rot_angle, skew_angle; /* in degrees */
double horiz_shift, vert_shift; /* after rotations */
};
struct letter_struct
{
char letter;
int affine_num;
double width;
struct affine_struct affines[MAX_AFFINES_PER_LETTER];
/* calculated */
double area;
};
struct letter_struct letters[] =
{
{'A', 3, 8, {{10, 2, 78.7, 11.3, 2, 0},
{10, 2, -78.7, -11.3, 4, 10},
{2, 1.5, 0, 0, 3, 4.5},
}
},
{'B', 5, 6, {{10, 2, 90, 0, 2, 0},
{3.2, 2, -51.3, -38.7, 2, 10},
{3.2, 2, -128.7, 38.7, 4, 7.5},
{3.2, 2, -51.3, -38.7, 2, 5},
{3.2, 2, -128.7, 38.7, 4, 2.5},
}
},
{'C', 3, 6, {{6, 2, 0, 0, 0, 8},
{6, 2, 180, 0, 6, 2},
{6, 2, 90, 0, 2, 2},
}
},
{'D', 4, 6, {{10, 2, 90, 0, 2, 0},
{4, 2, 0, 45, 2, 8},
{6, 2, -90, 0, 4, 8},
{4, 2, 0, -45, 0, 0},
}
},
{'E', 4, 6, {{6, 2, 0, 0, 0, 8},
{6, 2, 0, 0, 0, 0},
{4, 2, 0, 0, 2, 4},
{6, 2, 90, 0, 2, 2},
}
},
{'F', 3, 6, {{6, 2, 0, 0, 0, 8},
{4, 2, 0, 0, 2, 4},
{8, 2, 90, 0, 2, 0},
}
},
{'G', 5, 7, {{7, 2, 0, 0, 0, 8},
{6, 2, 90, 0, 2, 2},
{5, 2, 0, 0, 0, 0},
{3, 2, 90, 0, 7, 0},
{4, 2, 0, 0, 3, 3},
}
},
{'H', 5, 6, {{4, 2, 90, 0, 2, 0},
{4, 2, 90, 0, 2, 6},
{6, 2, 0, 0, 0, 4},
{4, 2, -90, 0, 4, 10},
{4, 2, -90, 0, 4, 4},
}
},
{'I', 1, 2, {{10, 2, 90, 0, 2, 0},
}
},
{'J', 3, 6, {{8, 2, -90, 0, 4, 10},
{4, 2, 180, 0, 6, 2},
{4, 2, 90, 0, 2, 0},
}
},
{'K', 3, 6, {{10, 2, 90, 0, 2, 0},
{5.4, 2, 68.2, 21.8, 4, 5},
{5.4, 2, 111.8, -21.8, 6, 0},
}
},
{'L', 2, 6, {{8, 2, 90, 0, 2, 2},
{6, 2, 0, 0, 0, 0},
}
},
{'M', 4, 10, {{10, 2, 90, 0, 2, 0},
{10.2, 2, -68.2, -21.8, 0, 10},
{10.2, 2, 68.2, 21.8, 6, 0},
{10, 2, 90, 0, 10, 0},
}
},
{'N', 3, 8, {{10, 2, 90, 0, 2, 0},
{10.2, 2, -68.2, -21.8, 1, 10},
{10, 2, 90, 0, 8, 0},
}
},
{'O', 4, 6, {{6, 2, 0, 0, 0, 8},
{6, 2, 180, 0, 6, 2},
{6, 2, 90, 0, 2, 2},
{6, 2, -90, 0, 4, 8},
}
},
{'P', 4, 6, {{8.5, 2, 90, 0, 2, 0},
{4.5, 1.5, 0, 0, 0, 8.5},
{3.5, 1.5, -90, 0, 4.5, 10},
{4, 1.5, 0, 0, 2, 5},
}
},
{'Q', 5, 7.5, {{6, 2, 0, 0, 0, 8},
{6, 2, 180, 0, 6, 2},
{6, 2, 90, 0, 2, 2},
{6, 2, -90, 0, 4, 8},
{4, 2, -45, 0, 2.5, 1.5},
}
},
{'R', 5, 6, {{8.5, 2, 90, 0, 2, 0},
{4.5, 1.5, 0, 0, 0, 8.5},
{3.5, 1.5, -90, 0, 4.5, 10},
{4, 1.5, 0, 0, 2, 5},
{5.47, 2, -66, -24, 2, 5},
}
},
{'S', 5, 6, {{6, 2, 0, 0, 0, 0},
{4, 2, 90, 0, 6, 2},
{4, 2 ,180, 0, 4, 6},
{4, 2, 90, 0, 2, 6},
{4, 2, 0, 0, 2, 8},
}
},
{'T', 2, 6, {{8, 2, 90, 0, 4, 0},
{6, 2, 0, 0, 0, 8},
}
},
{'U', 3, 6, {{8, 2, -90, 0, 4, 10},
{6, 2, 180, 0, 6, 2},
{8, 2, 90, 0, 2, 2},
}
},
{'V', 2, 8, {{10.4, 2, -73.3, -16.7, 0, 10},
{10.4, 2, 73.3, 16.7, 5, 0},
}
},
{'W', 4, 12, {{10.2, 2, -78.7, -11.3, 0, 10},
{6.7, 2, 63.4, 26.6, 4, 0},
{6.7, 2, -63.4, -26.6, 5, 6},
{10.2, 2, 78.7, 11.3, 10, 0},
}
},
{'X', 2, 7, {{11.2, 2, 63.4, 26.6, 2, 0},
{11.2, 2, -63.4, -26.6, 0, 10},
}
},
{'Y', 3, 8, {{5, 2, 90, 0, 5, 0},
{5.83, 2, 59, 31, 5, 5},
{5.83, 2, -59, -31, 0, 10},
}
},
{'Z', 3, 6, {{6, 2, 0, 0, 0, 0},
{6, 2, 0, 0, 0, 8},
{7.2, 2, 56.3, 33.7, 2, 2},
}
},
{'-', 1, 6, {{6, 2, 0, 0, 0, 4},
}
},
{'+', 2, 6, {{6, 2, 0, 0, 0, 4},
{6, 2, 90, 0, 4, 2},
}
},
{'=', 2, 6, {{6, 2, 0, 0, 0, 6},
{6, 2, 0, 0, 0, 2},
}
},
{'/', 1, 7, {{11.2, 2, 63.4, 26.6, 2, 0},
}
},
{'\\', 1, 7, {{11.2, 2, -63.4, -26.6, 0, 10},
}
},
{'!', 2, 2, {{6, 2, 90, 0, 2, 4},
{2, 2, 0, 0, 0, 0},
}
},
{'?', 5, 6, {{2, 2, 90, 0, 2, 6},
{4, 2, 0, 0, 0, 8},
{4, 2, -90, 0, 4, 10},
{3.6, 2, -123.7, 33.7, 4, 6},
{2, 2, 0, 0, 2, 0},
}
},
{'_', 0, 4}, /* to be used as a space character */
{'\0' /* terminating character */
}
};
/* these could be all calculated at compile time, but I'm much too lazy. */
void init_letters(void)
{
int l, a;
l=0;
while (letters[l].letter != '\0')
{
letters[l].area = 0;
for (a=0; a<letters[l].affine_num; a++)
{
letters[l].affines[a].width /= FRACTINT_SCALING_FACTOR;
letters[l].affines[a].height /= FRACTINT_SCALING_FACTOR;
letters[l].affines[a].horiz_shift /= FRACTINT_SCALING_FACTOR;
letters[l].affines[a].vert_shift /= FRACTINT_SCALING_FACTOR;
letters[l].area += letters[l].affines[a].width * letters[l].affines[a].height;
}
letters[l].width /= FRACTINT_SCALING_FACTOR;
l++;
}
spacing /= FRACTINT_SCALING_FACTOR;
total_height /= FRACTINT_SCALING_FACTOR;
}
int get_letter(int c)
{
int l=0;
while (letters[l].letter != (char)c && letters[l].letter != '\0')
l++;
return letters[l].letter != '\0' ? l : NO_MATCH;
}
void get_totals(void)
{
int c;
int i, l;
total_area = 0;
total_width = 0;
i = 0;
while ((c=string[i]) != '\0')
{
l = get_letter(toupper(c));
if (l != NO_MATCH)
{
total_area += letters[l].area;
total_width += letters[l].width + spacing;
}
i++;
}
}
void process_string(void)
{
int c;
int i, l, a;
double pos, xscale, yscale, tan_phi, sin_theta, cos_theta, xshift, yshift, prob;
struct affine_struct af;
get_totals();
if (total_area == 0 || total_width == 0)
{
printf("Error: nothing to print\n");
exit (3);
}
pos = spacing/2;
fprintf(spell_ifs,"%s { ; generated by ifsspell\n",string);
i = 0;
while ((c=string[i]) !=0)
{
l = get_letter(toupper(c));
if (l != NO_MATCH)
{
for (a=0; a<letters[l].affine_num; a++)
{
af = letters[l].affines[a]; /* just to make life easier */
xscale = af.width / total_width;
yscale = af.height / total_height;
tan_phi = -tan(PI/180*af.skew_angle);
sin_theta = sin(PI/180*af.rot_angle);
cos_theta = cos(PI/180*af.rot_angle);
prob = af.width * af.height / total_area;
xshift = af.horiz_shift+pos;
yshift = af.vert_shift;
/* rotation_matrix * skew_matrix * scale_matrix * [x,y] + trans_matrix */
/* a term */
fprintf(spell_ifs,IFS_ENTRY_FORMAT, xscale * cos_theta);
/* b term */
fprintf(spell_ifs,IFS_ENTRY_FORMAT, yscale * (cos_theta*tan_phi - sin_theta));
/* c term */
fprintf(spell_ifs,IFS_ENTRY_FORMAT, xscale * sin_theta);
/* d term */
fprintf(spell_ifs,IFS_ENTRY_FORMAT, yscale * (sin_theta*tan_phi + cos_theta));
/* e term */
fprintf(spell_ifs,IFS_ENTRY_FORMAT, xshift);
/* f term */
fprintf(spell_ifs,IFS_ENTRY_FORMAT, yshift);
/* p term */
fprintf(spell_ifs,IFS_ENTRY_FORMAT"\n", prob);
}
pos += letters[l].width + spacing;
}
fprintf(spell_ifs,"\n"); /* separate letters with an extra line */
i++;
}
fprintf(spell_ifs,"}\n\n");
}
void init_spell_ifs_file(void)
{
#ifdef DEBUG
spell_ifs = fopen(SPELL_IFS_FILENAME, "wt");
#else
spell_ifs = fopen(SPELL_IFS_FILENAME, "at");
#endif
if (spell_ifs == NULL)
{
printf("Error opening %s\n", SPELL_IFS_FILENAME);
exit (2);
}
}
void close_spell_ifs_file(void)
{
fclose(spell_ifs);
}
main(int argc, char *argv[])
{
int c;
int l;
if (argc < 2)
{
printf("Usage: ifsspell string\n"
"available characters: ");
l = 0;
while ((c=letters[l++].letter) != '\0')
putchar(c);
putchar('\n');
return 1;
}
init_letters();
string = argv[1];
init_spell_ifs_file();
process_string();
close_spell_ifs_file();
return 0;
}