V10/cmd/ideal/piece.c

Compare this file to the similar file:
Show the results in this format:

#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);
}