|
|
researchv10 Norman
#include "ideal.h"
#include "y.tab.h"
void linecall (linefax)
LINEPTR linefax;
{
printf ("...line %g %g %g %g\n",
linefax->x0, linefax->y0,
linefax->x1, linefax->y1
);
}
void circcall (circfax)
CIRCPTR circfax;
{
printf ("...circle %g %g %g\n",
circfax->x0, circfax->y0, circfax->r
);
}
void arccall (arcfax)
ARCPTR arcfax;
{
printf ("...arc %g %g %g %g %g %g %g %g %g\n",
arcfax->x0, arcfax->y0,
arcfax->x1, arcfax->y1,
arcfax->x2, arcfax->y2,
arcfax->theta1, arcfax->theta2,
fabs(arcfax->radius)
);
}
void textcall (textfax)
TEXTPTR textfax;
{
switch (textfax->command) {
case LEFT:
printf ("...left %g %g '%s\n",
textfax->x0,
textfax->y0,
textfax->string
);
break;
case CENTER:
printf ("...center %g %g '%s\n",
textfax->x0,
textfax->y0,
textfax->string
);
break;
case RIGHT:
printf ("...right %g %g '%s\n",
textfax->x0,
textfax->y0,
textfax->string
);
break;
default:
fprintf (stderr, "ideal: textcall: can't happen\n");
break;
}
}
void splcall (knotlist)
EXPRPTR knotlist;
{
printf ("...spline %g %g\n",
Re(((INTLPTR) knotlist->expr)),
Im(((INTLPTR) knotlist->expr))
);
knotlist = knotlist->next;
while (knotlist) {
printf ("...knot %g %g\n",
Re(((INTLPTR) knotlist->expr)),
Im(((INTLPTR) knotlist->expr))
);
knotlist = knotlist->next;
}
printf ("...endspline\n");
}
#define maxx bounds[MAXX]
#define maxy bounds[MAXY]
#define minx bounds[MINX]
#define miny bounds[MINY]
void boundscall (bounds)
double bounds[4];
{
printf ("...maxx %g\n", maxx);
printf ("...maxy %g\n", maxy);
printf ("...minx %g\n", minx);
printf ("...miny %g\n", miny);
}
void bbline (lineseg, bounds)
LINEPTR lineseg;
double bounds[4];
{
maxx = max(maxx, max(lineseg->x0, lineseg->x1));
maxy = max(maxy, max(lineseg->y0, lineseg->y1));
minx = min(minx, min(lineseg->x0, lineseg->x1));
miny = min(miny, min(lineseg->y0, lineseg->y1));
}
void bbcirc (circle, bounds)
CIRCPTR circle;
double bounds[4];
{
maxx = max(maxx, circle->x0 + fabs(circle->r));
minx = min(minx, circle->x0 - fabs(circle->r));
maxy = max(maxy, circle->y0 + fabs(circle->r));
miny = min(miny, circle->y0 - fabs(circle->r));
}
void bbstring (text, bounds)
TEXTPTR text;
double bounds[4];
{
maxx = max(maxx, text->x0);
minx = min(minx, text->x0);
maxy = max(maxy, text->y0);
miny = min(miny, text->y0);
}
/***************************************************************************
bounding box of a circular arc Eric Grosse 24 May 84
Conceptually, this routine generates a list consisting of the start,
end, and whichever north, east, south, and west points lie on the arc.
The bounding box is then the range of this list.
list = {start,end}
j = quadrant(start)
k = quadrant(end)
if( j==k && long way 'round ) append north,west,south,east
else
while( j != k )
append center+radius*[j-th of north,west,south,east unit vectors]
j += 1 (mod 4)
return( bounding box of list )
The following code implements this, with simple optimizations.
***********************************************************************/
bbarc(arc, bounds)
ARCPTR arc;
double bounds[4];
{
double x0, y0, x1, y1, xc, yc; /* start, end, center */
double xmin, xmax, ymin, ymax;
/* assumes center isn't too far out */
double r, x, y;
int j, k;
int quadrant();
x0 = arc->x1;
y0 = arc->y1;
x1 = arc->x2;
y1 = arc->y2;
xc = arc->x0;
yc = arc->y0;
x0 -= xc; y0 -= yc;
x1 -= xc; y1 -= yc;
xmin = (x0<x1)?x0:x1; ymin = (y0<y1)?y0:y1;
xmax = (x0>x1)?x0:x1; ymax = (y0>y1)?y0:y1;
r = sqrt(x0*x0+y0*y0);
if(r>0.){
j = quadrant(x0,y0);
k = quadrant(x1,y1);
if((j==k)&&(y1*x0<x1*y0)){
/* viewed as complex numbers, if Im(z1/z0)<0, arc is big */
if( xmin > -r) xmin = -r; if( ymin > -r) ymin = -r;
if( xmax < r) xmax = r; if( ymax < r) ymax = r;
}else{
while(j!=k){
switch(j){
case 1: if( ymax < r) ymax = r; break; /* north */
case 2: if( xmin > -r) xmin = -r; break; /* west */
case 3: if( ymin > -r) ymin = -r; break; /* south */
case 4: if( xmax < r) xmax = r; break; /* east */
}
j = j%4 + 1;
}
}
}
xmin += xc; ymin += yc;
xmax += xc; ymax += yc;
maxx = max(maxx,xmax);
minx = min(minx,xmin);
maxy = max(maxy,ymax);
miny = min(miny,ymin);
}
int
quadrant(x,y)
double x,y;
{
double z=0.;
if( (x>=z)&&(y> z) ){ return(1); }
else if( (x< z)&&(y>=z) ){ return(2); }
else if( (x<=z)&&(y< z) ){ return(3); }
else if( (x> z)&&(y<=z) ){ return(4); }
else{ fprintf(stderr,"can't happen: x,y=%g,%g",x,y); exit(1);}
}
void bbspline (knotlist, bounds)
EXPRPTR knotlist;
double bounds[4];
{
double xmin, xmax, ymin, ymax, x, y;
xmin = xmax = Re(((INTLPTR) knotlist->expr));
ymin = ymax = Im(((INTLPTR) knotlist->expr));
knotlist = knotlist->next;
while (knotlist) {
x = Re(((INTLPTR) knotlist->expr));
xmin = min(xmin, x);
xmax = max(xmax, x);
y = Im(((INTLPTR) knotlist->expr));
ymin = min(ymin, y);
ymax = max(ymax, y);
knotlist = knotlist->next;
}
minx = min(minx, xmin);
maxx = max(maxx, xmax);
miny = min(miny, ymin);
maxy = max(maxy, ymax);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.