home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gdead.berkeley.edu
/
gdead.berkeley.edu.tar
/
gdead.berkeley.edu
/
pub
/
cad-tools
/
ciftomann.tar
/
poly2mann.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-10
|
8KB
|
314 lines
/*
* poly2mann - Converts polygons in kic/cif format to mann format for
* the GCA 3600 pattern generator
*
* Copyright (c) 1988 David Giandomenico
* University of California, Berkeley
* gian@argon.Berkeley.EDU
*
* slighty modified by William Tang 4/4/89
* University of California, Berkeley
* tang@janus.Berkeley.EDU
*
* modified again by William Tang 11/21/89
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
* The author makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
/* To compile:
cc poly2mann.c -lm -o poly2mann
*/
#include <stdio.h>
#include <math.h>
#define MAXLINE 512
#define MAX_APER 9500 /* .95 mm on mask */
#define MIN_APER 20 /* 2 microns on mask */
#define MAX_STAGE 500000 /* +/-50mm */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define ABS(X) ((X)<0? -(X):(X))
char *progname;
char xxl;
char yyl;
char xxc;
char yyc;
double scale = 0; /* reduction factor */
FILE *fp = stdin;
main(argc,argv)
int argc;
char *argv[];
{
char line[MAXLINE];
progname = argv[0];
getargs(argc,argv);
while(fgets(line,MAXLINE,stdin) != NULL) poly_to_box(line);
}
getargs(argc, argv)
int argc;
char *argv[];
{
float mpl=0, reduction=0;
extern double scale;
while ( --argc > 0 ) {
if ( (*++argv)[0] == '-') {
switch ( (*argv)[1] ) {
case 'L':
--argc;
if (sscanf(*++argv, "%f", &mpl) != 1) usage();
break;
case 'S':
--argc;
if (sscanf(*++argv, "%f", &reduction) != 1) usage();
break;
default:
fprintf(stderr,"Unknown option %s\n", *argv);
usage();
}
} else if ( freopen(*argv,"r", stdin) == NULL) usage();
}
scale = mpl * reduction;
scale *= 10; /* units of p.g. are tenths of microns */
scale /= 100; /* cif units are 100/micron */
/* fprintf(stderr, " this is line 87 scale is %f\n", scale);
printf(" this is line 87 scale is %f\n", scale); */
if (scale == 0) usage();
}
usage()
{
fprintf(stderr,
"usage: %s file -L mic/lambda -S photo_reduction_factor\n",
progname);
exit(1);
}
error(ln,line,message)
int ln;
char *line, *message;
{
static int count = 0;
count++;
fprintf(stderr, "ERROR #%d: %s\nline %d: %s\n", count, message, ln, line);
printf("ERROR #%d: %s\nline %d: %s\n", count, message, ln, line);
/*
* if (count > 20) {
* fprintf(stderr, "More than 20 errors; quitting\n");
*
* printf("More than 20 errors; quitting\n");
*
* fflush(stdout);
* fflush(stderr);
* exit(1);
* }
*/
}
poly_to_box(line)
char *line;
{
static int ln =0;
char key[16], semi[16];
struct XY {
long int x,y;
}p1,p2,p3,p4,p5;
long int x,y;
ln++; /* line count */
if (sscanf(line, "%s %d %d %d %d %d %d %d %d %d %d %s",
key,
&p1.x, &p1.y,
&p2.x, &p2.y,
&p3.x, &p3.y,
&p4.x, &p4.y,
&p5.x, &p5.y, semi) == 12) {
if ((p1.x != p5.x) || (p1.y != p5.y)) {
error(ln,line,"fifth coordinate must match first coordinate");
return;
}
} else if (sscanf(line, "%s %d %d %d %d %d %d %d %d %s",
key,
&p1.x, &p1.y,
&p2.x, &p2.y,
&p3.x, &p3.y,
&p4.x, &p4.y, semi) != 10) {
error(ln,line,"wrong format for polygon-box");
return;
}
if ((strcmp("P", key) != 0) || (strcmp(";", semi) != 0)) {
error(ln,line,"wrong format for polygon-box");
return;
}
conv_to_box(&p1,&p2,&p3,&p4,ln,line);
}
conv_to_box(p1,p2,p3,p4,ln,line)
struct XY {
long int x,y;
} *p1,*p2,*p3,*p4;
int ln; /* line number */
char *line;
{
extern double scale;
long int x,y;
double mag, dot;
long int vx1,vx2,vy1,vy2;
int xdir, ydir;
int decimal, sign;
double angle, fl;
double xc,yc,xl,yl;
int xic, yic, xil, yil;
char xxc, yyc, xxl, yyl;
struct XY mid1,mid2;
/* p3 - p2 <- Arrangement of points, p1-p4
* | |
* p4 - p1
*/
/* Check if parallel sides */
vx1 = p2->x - p1->x; vy1 = p2->y - p1->y;
vx2 = p3->x - p4->x; vy2 = p3->y - p4->y;
/*
* printf("vx1 is %d, vy1 is %d, vx2 is %d, vy2 is %d\n", vx1, vy1, vx2, vy2);
* fprintf(stderr, "vx1 is %d, vy1 is %d, vx2 is %d, vy2 is %d\n", vx1, vy1, vx2, vy2);
*/
yl = sqrt((double) vx1*vx1+ (double) vy1*vy1);
yl += sqrt((double) vx2*vx2+ (double) vy2*vy2);
yl /= 2.0;
/*
* fprintf(stderr," this is line 189 : yl = %f\n", yl);
* printf(" this is line 189 : yl = %f\n", yl);
*/
if ((ABS(vx1 - vx2) > 2) || (ABS(vy1 - vy2) > 2)) {
error(ln, line, "sides aren't parallel");
return;
}
vx1 = p3->x - p2->x; vy1 = p3->y - p2->y;
vx2 = p4->x - p1->x; vy2 = p4->y - p1->y;
xl = sqrt((double) vx1*vx1+ (double) vy1*vy1);
xl += sqrt((double) vx2*vx2+ (double) vy2*vy2);
xl /= 2.0;
/*
* fprintf(stderr," this is line 204 : xl = %f\n", xl);
* printf(" this is line 204 : xl = %f\n", xl);
*/
if ((ABS(vx1 - vx2) > 2) || (ABS(vy1 - vy2) > 2)) {
error(ln, line, "sides aren't parallel");
return;
}
/* Check if rectangular using dot product */
vx1 = (p2->x - p1->x); vy1 = (p2->y - p1->y);
vx2 = (p4->x - p1->x); vy2 = (p4->y - p1->y);
mag = (double) vx1 * vx1 + (double) vy1 * vy1;
mag *= ((double) vx2 * vx2 + (double) vy2 * vy2);
mag = sqrt(mag);
dot = ((double) vx1 * vx2 + (double) vy1 * vy2) / mag;
if ( ABS(dot) > 0.01 )
{
angle = (180.0 / M_PI) * acos(dot);
/* fprintf(stderr, "dot product is %9.3e\n", dot);
*/
fprintf(stderr, "angle = %5.2f\n", angle);
error(ln, line, "polygon not square enough");
return;
/*
fprintf(stderr, "[%d] %5.2f ",ln, angle);
return;
*/
}
/* Make a box */
xc = ((double) p1->x + p2->x + p3->x + p4->x )/4.0;
yc = ((double) p1->y + p2->y + p3->y + p4->y )/4.0;
xc *= scale; yc *= scale;
xl *= scale; yl *= scale;
/*
* fprintf(stderr," this is line 236 : yl = %f\n", yl);
* printf(" this is line 236 : yl = %f\n", yl);
*
* fprintf(stderr," this is line 239 : xl = %f\n", xl);
* printf(" this is line 239 : xl = %f\n", xl);
*/
/* xc = rint(xc); yc = rint(yc); */
/* xl = rint(xl); yl = rint(yl); */
if (xc < 0) { fl = -0.5;} else { fl = 0.5;}
xic = xc + fl;
if (xl < 0) { fl = -0.5;} else { fl = 0.5;}
xil = xl + fl;
if (yc < 0) { fl = -0.5;} else { fl = 0.5;}
yic = yc + fl;
if (yl < 0) { fl = -0.5;} else { fl = 0.5;}
yil = yl + fl;
/* Check box is smaller than maximum aperature of pattern generator
* If not, subdivide the box
*/
if ( xl > MAX_APER ) {
/* p3 - mid1 - p2
* p4 - mid2 - p1
*/
mid1.x = (p3->x + p2->x)/2; mid1.y = (p3->y + p2->y)/2;
mid2.x = (p4->x + p1->x)/2; mid2.y = (p4->y + p1->y)/2;
conv_to_box(&mid2,&mid1,p3,p4,ln,line); /* left box */
conv_to_box(p1,p2,&mid1,&mid2,ln,line); /* right box */
return;
}
else if ( yl > MAX_APER ) {
/* p3 - p2
* mid2 - mid1
* p4 - p1
*/
mid1.x = (p1->x + p2->x)/2; mid1.y = (p1->y + p2->y)/2;
mid2.x = (p3->x + p4->x)/2; mid2.y = (p3->y + p4->y)/2;
conv_to_box(&mid1,p2,p3,&mid2,ln,line); /* upper box */
conv_to_box(p1,&mid1,&mid2,p4,ln,line); /* lower box */
return;
}
/* Check dimensions to make sure they fit pattern gernerator */
if ( xl < MIN_APER || yl < MIN_APER ) {
fprintf(stderr," this is line 256 , xl = %f and yl = %f\n", xl, yl);
printf(" this is line 256 , xl = %f and yl = %f\n", xl, yl);
error(ln, line,
"polygon is smaller than minimum aperature size of 20");
return;
}
if ( ABS(xc) > MAX_STAGE || ABS(yc) > MAX_STAGE ) {
error(ln, line,
"polygon extends beyond maximum stage position");
return;
}
xdir = ((p1->x - p4->x) + (p2->x - p3->x));
ydir = ((p1->y - p4->y) + (p2->y - p3->y));
printf("B %d %d %d %d %d %d;\n\0",
(int)xil, (int)yil, (int)xic, (int)yic, xdir, ydir);
}