Example #1
0
bool DropCutter::isinside(const GTri &t, const double *p)
{
	// point in triangle test

	// a new Tri projected onto the xy plane:
	double p1[3] = {t.m_p[0], t.m_p[1], 0};
	double p2[3] = {t.m_p[3], t.m_p[4], 0};
	double p3[3] = {t.m_p[6], t.m_p[7], 0};
	double pt[3] = {p[0], p[1], 0};

	bool b1 = isright(p1, p2, pt);
	bool b2 = isright(p3, p1, pt);
	bool b3 = isright(p2, p3, pt);

	if ((b1) && (b2) && (b3))
	{
		return true;
	}
	else if ((!b1) && (!b2) && (!b3))
	{
		return true;
	}
	else
	{
		return false;
	}

}
Example #2
0
    bool isValid(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if(s.size()==0)
            return false;
        stack<char> sck;
        sck.push(s[0]);
        int cur = 1;
        while(cur<s.size())
        {
            char curchar = s[cur];
            if(isright(curchar))
            {

    			if(sck.empty())	//Need to return false if the right parenthese is entered when sck is empty, we need to this case on the top because the second case need the stack to be not empty
					return false;

				if(!ispair(sck.top(),curchar))	//Need to check if sck is empty before peek, or the empty stack has been checked and returned if empty
				{
                    return false;
				}

				if(!sck.empty())	//Need to pop in the valid case, cannot be on top of the second case
					sck.pop();
            }
            else if(isleft(curchar))
                sck.push(curchar);
            else
                return false;
            cur++;
        }
        if(cur!=s.size() || !sck.empty())
            return false;
        return true;
    }
Example #3
0
JRB lprev(JRB n)
{
  if (ishead(n)) return n;
  while (!isroot(n)) {
    if (isright(n)) return n->parent;
    n = n->parent;
  }
  return n->parent;
}
Example #4
0
Rb_node lprev(Rb_node n)
{
  if (ishead(n)) return n;
  while (!isroot(n)) {
    if (isright(n)) return n->p.parent;
    n = n->p.parent;
  }
  return n->p.parent;
}
Example #5
0
int hpi(int cnt) {
	//step1. 将所有半平面按极角排序,对于极角相同的,选择性的保留一个
	sort(Planes, Planes + cnt);
	int len = 1 ;
	for (int i = 1; i < cnt; i++)
		if (sig(Planes[i].ang - Planes[i-1].ang) != 0)
			Planes[len++] = Planes[i];
	//step2. 使用一个双端队列(deque),加入最开始2个半平面
	cnt = len;
	Q[0] = Planes[0];
	Q[1] = Planes[1];
	//step3. 每次考虑一个新的半平面:
	//	  a.while deque顶端的两个半平面的交点在当前半平面外:删除deque顶端的半平面
	//	  b.while deque底部的两个半平面的交点在当前半平面外:删除deque底部的半平面
	//	  c.将新半平面加入deque顶端
	int l = 0, r = 1;
	for (int i = 2; i < cnt; i++) {
		while (l < r && isright(Planes[i], Q[r].cross(Q[r-1]))) r--;
		while (l < r && isright(Planes[i], Q[l].cross(Q[l+1]))) l++;
		Q[++r] = Planes[i];
	}
	//step4.删除两端多余的半平面。
	//	具体方法是:
	//	a.while deque顶端的两个半平面的交点在底部半平面外:删除deque顶端的半平面
	//	b.while deque底部的两个半平面的交点在顶端半平面外:删除deque底部的半平面
	//	重复a,b直到不能删除为止。
	while (l < r && isright(Q[l], Q[r].cross(Q[r-1]))) r--;
	while (l < r && isright(Q[r], Q[l].cross(Q[l+1]))) l++;
	//step5.计算出deque顶端和底部的交点即可。
	if (r <= l + 1) return 0;
	len = 0;
	for (int i = l; i < r; i++)
		Anss[len++] = Q[i].cross(Q[i+1]);
	Anss[len++] = Q[l].cross(Q[r]);
	//step6. 去除共线的点
	int tcnt = 1;
	for (int i = 1; i < len; i++)
		if (!(Anss[i] == Anss[i-1])) Anss[tcnt++] = Anss[i];
	if (tcnt != 1 && Anss[tcnt-1] == Anss[0]) tcnt--;
	return tcnt;
}
Example #6
0
int grammarAnalyze(const char* line)
{
	int ret = 0;
	if (line == NULL)
		return -1;
	int i = 0;
	LinkStack *stack = NULL;
	stack = LinkStack_Create();
	if (stack == NULL)
		return -2;
	while (*(line + i) != '\0')
	{
		if (isalpha(line[i]))
		{
			i++;
			continue;
		}
		else if (isleft(line[i]))
		{
			LinkStack_Push(stack, (void *)&line[i]);
		}
		else if (isright(line[i]))
		{
			char *tmp;
			tmp = (char *)LinkStack_Pop(stack);
			if (tmp == NULL || !ismatch(*tmp, line[i]))
			{
				break;
			}
		}

		i++;
	}
	if (LinkStack_Size(stack) == 0 && line[i] == '\0')
	{
		ret = 1;
	}
	LinkList_Destroy(stack);
	return ret;
}
Example #7
0
void jrb_delete_node(JRB n)
{
  JRB s, p, gp;
  char ir;

  if (isint(n)) {
    fprintf(stderr, "Cannot delete an internal node: 0x%p\n", (void *)n);
    exit(1);
  }
  if (ishead(n)) {
    fprintf(stderr, "Cannot delete the head of an jrb_tree: 0x%p\n", (void *)n);
    exit(1);
  }
  delete_item(n); /* Delete it from the list */
  p = n->parent;  /* The only node */
  if (isroot(n)) {
    p->parent = p;
    free(n);
    return;
  }
  s = sibling(n);    /* The only node after deletion */
  if (isroot(p)) {
    s->parent = p->parent;
    s->parent->parent = s;
    setroot(s);
    free(p);
    free(n);
    return;
  }
  gp = p->parent;  /* Set parent to sibling */
  s->parent = gp;
  if (isleft(p)) {
    gp->flink = s;
    setleft(s);
  } else {
    gp->blink = s;
    setright(s);
  }
  ir = isred(p);
  free(p);
  free(n);

  if (isext(s)) {      /* Update proper rext and lext values */
    p = lprev(s);
    if (!ishead(p)) setrext(p, s);
    p = rprev(s);
    if (!ishead(p)) setlext(p, s);
  } else if (isblack(s)) {
    fprintf(stderr, "DELETION PROB -- sib is black, internal\n");
    exit(1);
  } else {
    p = lprev(s);
    if (!ishead(p)) setrext(p, s->flink);
    p = rprev(s);
    if (!ishead(p)) setlext(p, s->blink);
    setblack(s);
    return;
  }

  if (ir) return;

  /* Recolor */

  n = s;
  p = n->parent;
  s = sibling(n);
  while(isblack(p) && isblack(s) && isint(s) &&
        isblack(s->flink) && isblack(s->blink)) {
    setred(s);
    n = p;
    if (isroot(n)) return;
    p = n->parent;
    s = sibling(n);
  }

  if (isblack(p) && isred(s)) {  /* Rotation 2.3b */
    single_rotate(p, isright(n));
    setred(p);
    setblack(s);
    s = sibling(n);
  }

  { JRB x, z; char il;

    if (isext(s)) {
      fprintf(stderr, "DELETION ERROR: sibling not internal\n");
      exit(1);
    }

    il = isleft(n);
    x = il ? s->flink : s->blink ;
    z = sibling(x);

    if (isred(z)) {  /* Rotation 2.3f */
      single_rotate(p, !il);
      setblack(z);
      if (isred(p)) setred(s); else setblack(s);
      setblack(p);
    } else if (isblack(x)) {   /* Recoloring only (2.3c) */
      if (isred(s) || isblack(p)) {
        fprintf(stderr, "DELETION ERROR: 2.3c not quite right\n");
        exit(1);
      }
      setblack(p);
      setred(s);
      return;
    } else if (isred(p)) { /* 2.3d */
      single_rotate(s, il);
      single_rotate(p, !il);
      setblack(x);
      setred(s);
      return;
    } else {  /* 2.3e */
      single_rotate(s, il);
      single_rotate(p, !il);
      setblack(x);
      return;
    }
  }
}
Example #8
0
// only use this if logic 1 and 2 can not solve the sudoku
// it guesses random values and
// uses logic to test if those values are possible
// this is done through recursion
int recurbrute (int (*sudoku)[9][9], int (*value)[9][9], int depth){
  // create a new copy of sudoku and value along with the pointers to pass on when recuring
	int copy[9][9];
	int (*copypointer)[9][9] = &copy;

	int valuecopy[9][9];
	int (*vcpointer)[9][9] = &valuecopy;
	
	copythis(copypointer, sudoku);
	copythis(vcpointer, value);

  	// set up all the prime values and ultimate break
	int ultimatebreak = 0;
	int primes[9] = {2,3,5,7,11,13,17,19,23};
	int totalerror = 0;
	int recurvalue;

  	// find the an unknown location
 	for (int i = 0; i < 9; i++){
  		for (int i2 = 0; i2 < 9; i2++){
  			if (vcpointer[0][i][i2]==0){
        		// testing if each prime can work in that location
        		for (int pi = 0; pi < 9; pi++){
	        		if (sudoku[0][i][i2]%primes[pi] ==0){ 
            			// change the values of the copy to match the test value
		        		copypointer[0][i][i2] = primes[pi];
		        		vcpointer[0][i][i2] = depth;
            			// apply logic to the copy leaving the original intact
		        		totallogic(copypointer, vcpointer, depth);
            			//check for error and completetion
            			// if there is error, move on to next test value
           				// if error and no more test values, then return 0;
            			// if there is no error and incomplete, then start recurbrute again
            			// checks to see if recurbrute value is complete. if complete break, otherwise move on to next value
            			// if there is no error and complete break out of all the loops
		        		if (isright(copypointer, vcpointer)){
              				if (issudokucomplete(vcpointer)){
				    	    	    ultimatebreak = 1;
				    	    	    break;
              				}else{	
				    	    	depth ++;
                				//printf("next depth = %d", depth);
				    	    	recurvalue = recurbrute( copypointer, vcpointer, depth);
				    	    	if (recurvalue){
                  					ultimatebreak = 1;
				    	    	}
			        		}
		        		}else{
		       		 		// start fresh from because the previous testing value is incorrect
              				copythis(copypointer, sudoku);
              				copythis(vcpointer, value);
            			}
	        		}
        		}// testing primes end here
        		if (ultimatebreak = 0){
	    		    return 0;
        		}
			}
			if (ultimatebreak){
				break;
			}
		}	
		if (ultimatebreak){
		  	break;
		}
	} // finding unknown locations end here

  	// modify the old sudoku to the new sodoku
	copythis(sudoku, copypointer);
	copythis(value, vcpointer);
	
	return 1;
}
Example #9
0
obj*
blockgen(obj *p, obj *q)	/* handles [...] */
{
	int i, invis, at, with;
	double ddval, h, w, xwith, ywith;
	double x0, y0, x1, y1, cx, cy;
	obj *ppos;
	Attr *ap;

	invis = at = 0;
	with = xwith = ywith = 0;
	ddval = 0;
	w = p->o_val[2] - p->o_val[0];
	h = p->o_val[3] - p->o_val[1];
	cx = (p->o_val[2] + p->o_val[0]) / 2;	/* geom ctr of [] wrt local orogin */
	cy = (p->o_val[3] + p->o_val[1]) / 2;
	dprintf("cx,cy=%g,%g\n", cx, cy);
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case HEIGHT:
			h = ap->a_val.f;
			break;
		case WIDTH:
			w = ap->a_val.f;
			break;
		case WITH:
			with = ap->a_val.i;	/* corner */
			break;
		case PLACE:	/* actually with position ... */
			ppos = ap->a_val.o;
			xwith = cx - ppos->o_x;
			ywith = cy - ppos->o_y;
			with = PLACE;
			break;
		case AT:
		case FROM:
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			at++;
			break;
		case INVIS:
			invis = INVIS;
			break;
		case TEXTATTR:
			savetext(ap->a_sub, ap->a_val.p);
			break;
		}
	}
	if (with) {
		switch (with) {
		case NORTH:	ywith = -h / 2; break;
		case SOUTH:	ywith = h / 2; break;
		case EAST:	xwith = -w / 2; break;
		case WEST:	xwith = w / 2; break;
		case NE:	xwith = -w / 2; ywith = -h / 2; break;
		case SE:	xwith = -w / 2; ywith = h / 2; break;
		case NW:	xwith = w / 2; ywith = -h / 2; break;
		case SW:	xwith = w / 2; ywith = h / 2; break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += w / 2;
		else if (isleft(hvmode))
			curx -= w / 2;
		else if (isup(hvmode))
			cury += h / 2;
		else
			cury -= h / 2;
	}
	x0 = curx - w / 2;
	y0 = cury - h / 2;
	x1 = curx + w / 2;
	y1 = cury + h / 2;
	extreme(x0, y0);
	extreme(x1, y1);
	p->o_x = curx;
	p->o_y = cury;
	p->o_nt1 = ntext1;
	p->o_nt2 = ntext;
	ntext1 = ntext;
	p->o_val[0] = w;
	p->o_val[1] = h;
	p->o_val[2] = cx;
	p->o_val[3] = cy;
	p->o_val[5] = q->o_nobj - 1;		/* last item in [...] */
	p->o_ddval = ddval;
	p->o_attr = invis;
	dprintf("[] %g %g %g %g at %g %g, h=%g, w=%g\n", x0, y0, x1, y1, curx, cury, h, w);
	if (isright(hvmode))
		curx = x1;
	else if (isleft(hvmode))
		curx = x0;
	else if (isup(hvmode))
		cury = y1;
	else
		cury = y0;
	for (i = 0; i <= 5; i++)
		q->o_val[i] = p->o_val[i];
	stack[nstack+1].p_symtab = NULL;	/* so won't be found again */
	blockadj(p);	/* fix up coords for enclosed blocks */
	return(p);
}
Example #10
0
obj *circgen(type)
{
	static float rad[2] = { HT2, WID2 };
	static float rad2[2] = { HT2, HT2 };
	static float x0, y0, x1, y1, x2, y2;
	int i, at, t, invis, ddtype, with;
	float xwith, ywith;
	float r, r2, ddval;
	obj *p, *ppos;
	Attr *ap;

	at = invis = ddtype = 0;
	with = xwith = ywith = 0;
	t = (type == CIRCLE) ? 0 : 1;
	if (type == CIRCLE)
		r = r2 = getfval("circlerad");
	else if (type == ELLIPSE) {
		r = getfval("ellipsewid") / 2;
		r2 = getfval("ellipseht") / 2;
	}
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case TEXTATTR:
			savetext(ap->a_sub, ap->a_val.p);
			break;
		case RADIUS:
			r = ap->a_val.f;
			break;
		case DIAMETER:
		case WIDTH:
			r = ap->a_val.f / 2;
			break;
		case HEIGHT:
			r2 = ap->a_val.f / 2;
			break;
		case SAME:
			r = rad[t];
			r2 = rad2[t];
			break;
		case WITH:
			with = ap->a_val.i;
			break;
		case AT:
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			at++;
			break;
		case INVIS:
			invis = INVIS;
			break;
		case DOT:
		case DASH:
			ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT;
			if (ap->a_sub == DEFAULT)
				ddval = getfval("dashwid");
			else
				ddval = ap->a_val.f;
			break;
		}
	}
	if (type == CIRCLE)
		r2 = r;	/* probably superfluous */
	if (with) {
		switch (with) {
		case NORTH:	ywith = -r2; break;
		case SOUTH:	ywith = r2; break;
		case EAST:	xwith = -r; break;
		case WEST:	xwith = r; break;
		case NE:	xwith = -r * 0.707; ywith = -r2 * 0.707; break;
		case SE:	xwith = -r * 0.707; ywith = r2 * 0.707; break;
		case NW:	xwith = r * 0.707; ywith = -r2 * 0.707; break;
		case SW:	xwith = r * 0.707; ywith = r2 * 0.707; break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += r;
		else if (isleft(hvmode))
			curx -= r;
		else if (isup(hvmode))
			cury += r2;
		else
			cury -= r2;
	}
	p = makenode(type, 2);
	p->o_val[0] = rad[t] = r;
	p->o_val[1] = rad2[t] = r2;
	if (r <= 0 || r2 <= 0) {
		yyerror("%s has invalid radius %g\n", (type==CIRCLE) ? "circle" : "ellipse", r<r2 ? r : r2);
	}
	p->o_attr = invis | ddtype;
	extreme(curx+r, cury+r2);
	extreme(curx-r, cury-r2);
	if (type == CIRCLE)
		dprintf("C %g %g %g\n", curx, cury, r);
	if (type == ELLIPSE)
		dprintf("E %g %g %g %g\n", curx, cury, r, r2);
	if (isright(hvmode))
		curx += r;
	else if (isleft(hvmode))
		curx -= r;
	else if (isup(hvmode))
		cury += r2;
	else
		cury -= r2;
	return(p);
}
Example #11
0
obj *textgen(void)
{
	int i, sub, nstr, at, with, hset, invis;
	double xwith, ywith, h, w, x0, y0, x1, y1;
	obj *p, *ppos;
	Attr *ap;

	at = with = nstr = hset = invis = 0;
	h = getfval("textht");
	w = getfval("textwid");
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case HEIGHT:
			h = ap->a_val.f;
			hset++;
			break;
		case WIDTH:
			w = ap->a_val.f;
			break;
		case WITH:
			with = ap->a_val.i;
			break;
		case INVIS:
			invis = INVIS;
			break;
		case AT:
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			at++;
			break;
		case TEXTATTR:
			sub = ap->a_sub;
			if (ap->a_val.p == NULL)	/* an isolated modifier */
				text[ntext-1].t_type = sub;
			else {
				savetext(sub, ap->a_val.p);
				nstr++;
			}
			break;
		}
	}
	if (hset == 0)		/* no explicit ht cmd */
		h *= nstr;
	if (with) {
		xwith = ywith = 0.0;
		switch (with) {
		case NORTH:	ywith = -h / 2; break;
		case SOUTH:	ywith = h / 2; break;
		case EAST:	xwith = -w / 2; break;
		case WEST:	xwith = w / 2; break;
		case NE:	xwith = -w / 2; ywith = -h / 2; break;
		case SE:	xwith = -w / 2; ywith = h / 2; break;
		case NW:	xwith = w / 2; ywith = -h / 2; break;
		case SW:	xwith = w / 2; ywith = h / 2; break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += w / 2;
		else if (isleft(hvmode))
			curx -= w / 2;
		else if (isup(hvmode))
			cury += h / 2;
		else
			cury -= h / 2;
	}
	x0 = curx - w / 2;
	y0 = cury - h / 2;
	x1 = curx + w / 2;
	y1 = cury + h / 2;
	extreme(x0, y0);
	extreme(x1, y1);
	dprintf("Text h %g w %g at %g,%g\n", h, w, curx, cury);
	p = makenode(TEXT, 2);
	p->o_attr = invis;
	p->o_val[0] = w;
	p->o_val[1] = h;
	if (isright(hvmode))
		curx = x1;
	else if (isleft(hvmode))
		curx = x0;
	else if (isup(hvmode))
		cury = y1;
	else
		cury = y0;
	return(p);
}
Example #12
0
print()
{
	obj *p;
	int i, j, k, m;
	float x0, y0, x1, y1, ox, oy, dx, dy, ndx, ndy;

	for (i = 0; i < nobj; i++) {
		p = objlist[i];
		ox = p->o_x;
		oy = p->o_y;
		if (p->o_count >= 1)
			x1 = p->o_val[0];
		if (p->o_count >= 2)
			y1 = p->o_val[1];
		m = p->o_mode;
		switch (p->o_type) {
		case TROFF:
			troff(text[p->o_nt1].t_val);
			break;
		case BOX:
		case BLOCK:
			move(ox, oy);
			dotext(p);	/* if there are any text strings */
			x0 = ox - x1 / 2;
			y0 = oy - y1 / 2;
			x1 = ox + x1 / 2;
			y1 = oy + y1 / 2;
			if (p->o_attr & INVIS || p->o_type == BLOCK)
				;	/* nothing at all */
			else if (p->o_attr & (DOTBIT|DASHBIT))
				dotbox(x0, y0, x1, y1, p->o_attr, p->o_ddval);
			else
				box(x0, y0, x1, y1);
			if (ishor(m))
				move(isright(m) ? x1 : x0, oy);	/* right side */
			else
				move(ox, isdown(m) ? y0 : y1);	/* bottom */
			break;
		case BLOCKEND:
			break;
		case CIRCLE:
			move(ox, oy);
			dotext(p);
			if ((p->o_attr & INVIS) == 0)
				circle(ox, oy, x1);
			if (ishor(m))
				move(ox + isright(m) ? x1 : -x1, oy);
			else
				move(ox, oy + isup(m) ? x1 : -x1);
			break;
		case ELLIPSE:
			move(ox, oy);
			dotext(p);
			if ((p->o_attr & INVIS) == 0)
				ellipse(ox, oy, x1, y1);
			if (ishor(m))
				move(ox + isright(m) ? x1 : -x1, oy);
			else
				move(ox, oy - isdown(m) ? y1 : -y1);
			break;
		case ARC:
			move(ox, oy);
			dotext(p);
			if (p->o_attr & HEAD1)
				arrow(x1 - (y1 - oy), y1 + (x1 - ox),
				      x1, y1, p->o_val[4], p->o_val[5], p->o_val[5]/p->o_val[6]/2, p->o_nhead);
                        if (p->o_attr & INVIS)
                                /* probably wrong when it's cw */
                                move(x1, y1);
                        else
				arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3]);
			if (p->o_attr & HEAD2)
				arrow(p->o_val[2] + p->o_val[3] - oy, p->o_val[3] - (p->o_val[2] - ox),
				      p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5], -p->o_val[5]/p->o_val[6]/2, p->o_nhead);
			if (p->o_attr & CW_ARC)
				move(x1, y1);	/* because drawn backwards */
			break;
		case LINE:
		case ARROW:
		case SPLINE:
			move((ox + x1)/2, (oy + y1)/2);	/* center */
			dotext(p);
			if (p->o_attr & HEAD1)
				arrow(ox + p->o_val[5], oy + p->o_val[6], ox, oy, p->o_val[2], p->o_val[3], 0.0, p->o_nhead);
                        if (p->o_attr & INVIS)
                                move(x1, y1);
			else if (p->o_type == SPLINE)
				spline(ox, oy, p->o_val[4], &p->o_val[5], p->o_attr & (DOTBIT|DASHBIT), p->o_ddval);
			else {
				dx = ox;
				dy = oy;
				for (k=0, j=5; k < p->o_val[4]; k++, j += 2) {
					ndx = dx + p->o_val[j];
					ndy = dy + p->o_val[j+1];
					if (p->o_attr & (DOTBIT|DASHBIT))
						dotline(dx, dy, ndx, ndy, p->o_attr, p->o_ddval);
					else
						line(dx, dy, ndx, ndy);
					dx = ndx;
					dy = ndy;
				}
			}
			if (p->o_attr & HEAD2) {
				dx = ox;
				dy = oy;
				for (k = 0, j = 5; k < p->o_val[4] - 1; k++, j += 2) {
					dx += p->o_val[j];
					dy += p->o_val[j+1];
				}
				arrow(dx, dy, x1, y1, p->o_val[2], p->o_val[3], 0.0, p->o_nhead);
			}
			break;
		case MOVE:
		case TEXT:
			move(ox, oy);
			dotext(p);
			break;
		}
	}
}
Example #13
0
obj *boxgen(void)
{
	static double prevh = HT;
	static double prevw = WID;	/* golden mean, sort of */
	int i, at, battr, with;
	double ddval, fillval, xwith, ywith;
	double h, w, x0, y0, x1, y1;
	obj *p, *ppos;
	Attr *ap;

	h = getfval("boxht");
	w = getfval("boxwid");
	at = battr = with = 0;
	ddval = fillval = xwith = ywith = 0;
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case HEIGHT:
			h = ap->a_val.f;
			break;
		case WIDTH:
			w = ap->a_val.f;
			break;
		case SAME:
			h = prevh;
			w = prevw;
			break;
		case WITH:
			with = ap->a_val.i;	/* corner */
			break;
		case AT:
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			at++;
			break;
		case INVIS:
			battr |= INVIS;
			break;
		case NOEDGE:
			battr |= NOEDGEBIT;
			break;
		case DOT:
		case DASH:
			battr |= ap->a_type==DOT ? DOTBIT : DASHBIT;
			if (ap->a_sub == DEFAULT)
				ddval = getfval("dashwid");
			else
				ddval = ap->a_val.f;
			break;
		case FILL:
			battr |= FILLBIT;
			if (ap->a_sub == DEFAULT)
				fillval = getfval("fillval");
			else
				fillval = ap->a_val.f;
			break;
		case TEXTATTR:
			savetext(ap->a_sub, ap->a_val.p);
			break;
		}
	}
	if (with) {
		switch (with) {
		case NORTH:	ywith = -h / 2; break;
		case SOUTH:	ywith = h / 2; break;
		case EAST:	xwith = -w / 2; break;
		case WEST:	xwith = w / 2; break;
		case NE:	xwith = -w / 2; ywith = -h / 2; break;
		case SE:	xwith = -w / 2; ywith = h / 2; break;
		case NW:	xwith = w / 2; ywith = -h / 2; break;
		case SW:	xwith = w / 2; ywith = h / 2; break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += w / 2;
		else if (isleft(hvmode))
			curx -= w / 2;
		else if (isup(hvmode))
			cury += h / 2;
		else
			cury -= h / 2;
	}
	x0 = curx - w / 2;
	y0 = cury - h / 2;
	x1 = curx + w / 2;
	y1 = cury + h / 2;
	extreme(x0, y0);
	extreme(x1, y1);
	p = makenode(BOX, 2);
	p->o_val[0] = w;
	p->o_val[1] = h;
	p->o_attr = battr;
	p->o_ddval = ddval;
	p->o_fillval = fillval;
	dprintf("B %g %g %g %g at %g %g, h=%g, w=%g\n", x0, y0, x1, y1, curx, cury, h, w);
	if (isright(hvmode))
		curx = x1;
	else if (isleft(hvmode))
		curx = x0;
	else if (isup(hvmode))
		cury = y1;
	else
		cury = y0;
	prevh = h;
	prevw = w;
	return(p);
}
Example #14
0
obj *
circgen(int type) {
static	double	rad[2]	= { HT2, WID2 };
static	double	rad2[2]	= { HT2, HT2 };

struct	objattr	obat;
	double	xwith, ywith, r, r2;
	int	i, at, t, with;
	obj	*p, *ppos;
	Attr	*ap;

	obat.a_layer = (int)getfval("curlayer");
	obat.a_flags = EDGED;
	obat.a_weight = obat.a_lcolor = obat.a_pcolor = obat.a_tcolor = -1;
	obat.a_dashpat.a = (float *)0;
	at = with = xwith = ywith = 0;
	if ((t = (type == CIRCLE) ? 0 : 1)) {
		r = getfval("ellipsewid") / 2;
		r2 = getfval("ellipseht") / 2;
	}
	else
		r = r2 = getfval("circlerad");
	set_text();
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		default:
			miscattrs(ap, &obat);
			break;
		case RADIUS:
			r = ap->a_val.f;
			break;
		case DIAMETER:
		case WIDTH:
			r = ap->a_val.f / 2;
			break;
		case HEIGHT:
			r2 = ap->a_val.f / 2;
			break;
		case SAME:
			r = rad[t];
			r2 = rad2[t];
			break;
		case WITH:
			with = ap->a_val.i;
			break;
		case AT:
			ppos = ap->a_val.o;
			curx = Xformx(ppos, 1, ppos->o_x, ppos->o_y);
			cury = Xformy(ppos, 0, ppos->o_x, ppos->o_y);
			at++;
			break;
		}
	}
	if (type == CIRCLE)
		r2 = r;	/* probably superfluous */
	if (with) {
		if (pic_compat)		/* map NE to 2nd, etc. */
			with =	with == NE ? 2 :
				with == NW ? 4 :
				with == SW ? 6 :
				with == SE ? 8 : with;
		switch (with) {
		case NORTH:	ywith = -r2;			break;
		case SOUTH:	ywith = r2;			break;
		case EAST:	xwith = -r;			break;
		case WEST:	xwith = r;			break;
		case NE:	xwith = -r;	ywith = -r2;	break;
		case SE:	xwith = -r;	ywith =  r2;	break;
		case NW:	xwith =  r;	ywith = -r2;	break;
		case SW:	xwith =  r;	ywith =  r2;	break;
		case CENTER:
		case START:
		case END:					break;
		default:	xwith =  -r * xdelta[with % 8];
				ywith = -r2 * ydelta[with % 8];
				if (with % 2 == 0) {
					xwith *= M_SQRT1_2;
					ywith *= M_SQRT1_2;
				}
				break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += r;
		else if (isleft(hvmode))
			curx -= r;
		else if (isup(hvmode))
			cury += r2;
		else
			cury -= r2;
	}
	if (r <= 0 || r2 <= 0)
		yyerror("%s has invalid radius %g",
			(type==CIRCLE) ? "circle" : "ellipse", r<r2 ? r : r2);
	p = makenode(type, N_VAL, obat.a_layer);
	p->o_wid = 2 * (rad[t]  = r);
	p->o_ht  = 2 * (rad2[t] = r2);
	primattrs(p, &obat);
	text_bounds(p);
	if (isright(hvmode))
		curx += r;
	else if (isleft(hvmode))
		curx -= r;
	else if (isup(hvmode))
		cury += r2;
	else
		cury -= r2;
	r  += p->o_weight/2;
	r2 += p->o_weight/2;
	track_bounds (p->o_x - r, p->o_y - r2, p->o_x + r, p->o_y + r2);
	return(p);
}