/* directVis:
 * Given two points, return true if the points can directly see each other.
 * If a point is associated with a polygon, the edges of the polygon
 * are ignored when checking visibility.
 */
int directVis (Ppoint_t p, int pp, Ppoint_t q, int qp, vconfig_t *conf)
{
    int    V = conf->N;
    Ppoint_t* pts = conf->P;
    int*   nextPt = conf->next;
    /* int*   prevPt = conf->prev; */
    int   k;
    int   s1, e1;
    int   s2, e2;

    if (pp < 0) {
      s1 = 0;
      e1 = 0;
      if (qp < 0) {
        s2 = 0;
        e2 = 0;
      }
      else {
        s2 = conf->start[qp];
        e2 = conf->start[qp+1];
      }
    }
    else if (qp < 0) {
      s1 = 0;
      e1 = 0;
      s2 = conf->start[pp];
      e2 = conf->start[pp+1];
    }
    else if (pp <= qp) {
      s1 = conf->start[pp];
      e1 = conf->start[pp+1];
      s2 = conf->start[qp];
      e2 = conf->start[qp+1];
    }
    else {
      s1 = conf->start[qp];
      e1 = conf->start[qp+1];
      s2 = conf->start[pp];
      e2 = conf->start[pp+1];
    }

    for (k=0; k < s1; k++) {
      if (INTERSECT(p,q,pts [k], pts[nextPt [k]], pts[prevPt [k]]))
        return 0;
    }
    for (k=e1; k < s2; k++) {
      if (INTERSECT(p,q,pts [k], pts[nextPt [k]], pts[prevPt [k]]))
        return 0;
    }
    for (k=e2; k < V; k++) {
      if (INTERSECT(p,q,pts [k], pts[nextPt [k]], pts[prevPt [k]]))
        return 0;
    }
    return 1;
}
/* clear:
 * Return true if no polygon line segment non-trivially intersects
 * the segment [pti,ptj], ignoring segments in [start,end).
 */
static int clear (Ppoint_t pti, Ppoint_t ptj, 
                  int start, int end,
                  int V, Ppoint_t pts[], int nextPt[], int prevPt[])
{
    int   k;

    for (k=0; k < start; k++) {
      if (INTERSECT(pti,ptj,pts [k], pts[nextPt [k]], pts[prevPt [k]]))
        return 0;
    }
    for (k=end; k < V; k++) {
      if (INTERSECT(pti,ptj,pts [k], pts[nextPt [k]], pts[prevPt [k]]))
        return 0;
    }
    return 1;
}
Beispiel #3
0
// find the dimensions of the monitor displaying point x,y
void monitor_dimensions ( Display *display, Screen *screen, int x, int y, workarea *mon )
{
    memset ( mon, 0, sizeof ( workarea ) );
    mon->w = WidthOfScreen ( screen );
    mon->h = HeightOfScreen ( screen );

    // locate the current monitor
    if ( XineramaIsActive ( display ) ) {
        int                monitors;
        XineramaScreenInfo *info = XineramaQueryScreens ( display, &monitors );

        if ( info ) {
            for ( int i = 0; i < monitors; i++ ) {
                if ( INTERSECT ( x, y, 1, 1, info[i].x_org, info[i].y_org, info[i].width, info[i].height ) ) {
                    mon->x = info[i].x_org;
                    mon->y = info[i].y_org;
                    mon->w = info[i].width;
                    mon->h = info[i].height;
                    break;
                }
            }
        }

        XFree ( info );
    }
}
Beispiel #4
0
void
shortprune(set *set1, set *set2, int m)
{
    register int i;

    for (i = 0; i < M; ++i) INTERSECT(set1[i],set2[i]);
}
Beispiel #5
0
// find the dimensions of the monitor displaying point x,y
void monitor_dimensions ( int x, int y, workarea *mon )
{
    xcb_generic_error_t *error = NULL;
    memset ( mon, 0, sizeof ( workarea ) );
    mon->w = xcb->screen->width_in_pixels;
    mon->h = xcb->screen->height_in_pixels;

    if ( !xcb->has_xinerama ) {
        return;
    }

    xcb_xinerama_query_screens_cookie_t cookie_screen;
    cookie_screen = xcb_xinerama_query_screens ( xcb->connection );
    xcb_xinerama_query_screens_reply_t  *query_screens;
    query_screens = xcb_xinerama_query_screens_reply ( xcb->connection, cookie_screen, &error );
    if ( error ) {
        fprintf ( stderr, "Error getting screen info\n" );
        return;
    }
    xcb_xinerama_screen_info_t *screens = xcb_xinerama_query_screens_screen_info ( query_screens );
    int                        len      = xcb_xinerama_query_screens_screen_info_length ( query_screens );
    for ( int i = 0; i < len; i++ ) {
        xcb_xinerama_screen_info_t *info = &screens[i];
        if ( INTERSECT ( x, y, 1, 1, info->x_org, info->y_org, info->width, info->height ) ) {
            mon->w = info->width;
            mon->h = info->height;
            mon->x = info->x_org;
            mon->y = info->y_org;
            break;
        }
    }
    free ( query_screens );
}
void intersect (gleDouble sect[3],	/* returned */
                gleDouble p[3],	/* input */
                gleDouble n[3],	/* input */
                gleDouble v1[3],	/* input */
                gleDouble v2[3])	/* input */
{
   INTERSECT (sect, p, n, v1, v2);
}
Beispiel #7
0
/* Yes I stole this from dmenu */
void
updategeom() {
	int a, j, di, i = 0, area = 0, x, y;
	unsigned int du;
	Window w, pw, dw, *dws;
	XWindowAttributes wa;
	int n;
	XineramaScreenInfo *info;

	if((info = XineramaQueryScreens(dpy, &n))) {

		XGetInputFocus(dpy, &w, &di);
		if(w != root && w != PointerRoot && w != None) {
			/* find top-level window containing current input focus */
			do {
				if(XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
					XFree(dws);
			} while(w != root && w != pw);
			/* find xinerama screen with which the window intersects most */
			if(XGetWindowAttributes(dpy, pw, &wa))
				for(j = 0; j < n; j++)
					if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
						area = a;
						i = j;
					}
		}
		/* no focused window is on screen, so use pointer location instead */
		if(!area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
			for(i = 0; i < n; i++)
				if(INTERSECT(x, y, 1, 1, info[i]))
					break;

		xoff = info[i].x_org;
		yoff = info[i].y_org;
		sw = info[i].width;
		sh = info[i].height;
		XFree(info);
	}
	else {
		xoff = 0;
		yoff = 0;
		sw = DisplayWidth(dpy, screen);
		sh = DisplayHeight(dpy, screen);
	}
}
Beispiel #8
0
static void
check_bool2_init (enum tree_code code, tree exp0, tree exp1,
		  words before, words when_false, words when_true)
{
  word buf[2*4];
  words tmp = num_current_words <= 2 ? buf
    : ALLOC_WORDS (4 * num_current_words);
  words when_false_0 = tmp;
  words when_false_1 = tmp+num_current_words;
  words when_true_0 = tmp+2*num_current_words;
  words when_true_1 = tmp+3*num_current_words;
  check_bool_init (exp0, before, when_false_0, when_true_0);
  INTERSECT (before, when_false_0, when_true_0);
  check_bool_init (exp1, before, when_false_1, when_true_1);

  INTERSECT (before, when_false_1, when_true_1);

  if (code == EQ_EXPR)
    {
      /* Now set:
       * when_true = (when_false_1 INTERSECTION when_true_1)
       *   UNION (when_true_0 INTERSECTION when_false_1)
       *   UNION (when_false_0 INTERSECTION when_true_1);
       * using when_false and before as temporary working areas.  */
      INTERSECT (when_true, when_true_0, when_false_1);
      INTERSECT (when_false, when_true_0, when_false_1);
      UNION (when_true, when_true, when_false);
      UNION (when_true, when_true, before);

      /* Now set:
       * when_false = (when_false_1 INTERSECTION when_true_1)
       *   UNION (when_true_0 INTERSECTION when_true_1)
       *   UNION (when_false_0 INTERSECTION when_false_1);
       * using before as a temporary working area.  */
      INTERSECT (when_false, when_true_0, when_true_1);
      UNION (when_false, when_false, before);
      INTERSECT (before, when_false_0, when_false_1);
      UNION (when_false, when_false, before);
    }
  else if (code == BIT_AND_EXPR || code == TRUTH_AND_EXPR)
    {
      UNION (when_true, when_true_0, when_true_1);
      INTERSECT (when_false, when_false_0, when_false_1);
      UNION (when_false, when_false, before);
    }
  else /* if (code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) */
    {
      UNION (when_false, when_false_0, when_false_1);
      INTERSECT (when_true, when_true_0, when_true_1);
      UNION (when_true, when_true, before);
    }

  if (tmp != buf)
    FREE_WORDS (tmp);
}
Beispiel #9
0
static int range_cmp_for_search(const void *l, const void *r) {
    range_t *left = (range_t *)l, *right = (range_t *)r;
    if (INTERSECT(left, right) ||
        CONTAINS(left, right) ||
        CONTAINS(right, left)) {
        return 0;
    }
    return left->start - right->start;
}
Beispiel #10
0
int intersect (gleDouble sect[3],	/* returned */
                gleDouble p[3],	/* input */
                gleDouble n[3],	/* input */
                gleDouble v1[3],	/* input */
                gleDouble v2[3])	/* input */
{
   int valid;

   INTERSECT (valid, sect, p, n, v1, v2);
   return (valid);
}
Beispiel #11
0
static void
check_cond_init (tree test_exp, tree then_exp, tree else_exp,
		 words before, words when_false, words when_true)
{
  int save_start_current_locals = start_current_locals;
  DECLARE_BUFFERS(test_false, 6);
  words test_true = test_false + num_current_words;
  words then_false = test_true + num_current_words;
  words then_true = then_false + num_current_words;
  words else_false = then_true + num_current_words;
  words else_true = else_false + num_current_words;
  start_current_locals = num_current_locals;

  check_bool_init (test_exp, before, test_false, test_true);
  check_bool_init (then_exp, test_true, then_false, then_true);
  check_bool_init (else_exp, test_false, else_false, else_true);
  INTERSECT (when_false, then_false, else_false);
  INTERSECT (when_true, then_true, else_true);
  RELEASE_BUFFERS(test_false);
  start_current_locals = save_start_current_locals;
}
Beispiel #12
0
range_list_t* subtract_ranges(const range_list_t *r, const range_list_t *s)
{
    ASSERT(r);  ASSERT(r->is_sorted);
    ASSERT(s);  ASSERT(s->is_sorted);

    range_list_t *result = init_range_list();

    int r_num_ranges, r_idx;
    range_t *r_ranges = get_sorted_ranges(r, &r_num_ranges);
    ASSERT(r_ranges);

    int s_num_ranges, s_idx;
    range_t *s_ranges = get_sorted_ranges(s, &s_num_ranges);
    ASSERT(s_ranges);

    s_idx = 0;
    for (r_idx = 0; r_idx < r_num_ranges; r_idx++) {
        GElf_Off last_start = r_ranges[r_idx].start;
        for (; s_idx < s_num_ranges; s_idx++) {
            if (CONTAINS(&r_ranges[r_idx], &s_ranges[s_idx])) {
                if (last_start == 
                    r_ranges[r_idx].start + r_ranges[r_idx].length) {
                    break;
                }
                if (last_start == s_ranges[s_idx].start) {
                    last_start += s_ranges[s_idx].length;
                    continue;
                }
                INFO("Adding subtracted range [%lld, %lld)\n",
                     last_start,
                     s_ranges[s_idx].start);
                add_unique_range_nosort(
                    result, 
                    last_start,
                    s_ranges[s_idx].start - last_start,
                    NULL,
                    NULL,
                    NULL);
                last_start = s_ranges[s_idx].start + s_ranges[s_idx].length;
            } else {
                ASSERT(!INTERSECT(&r_ranges[r_idx], &s_ranges[s_idx]));
                break;
            }
        } /* while (s_idx < s_num_ranges) */
    } /* for (r_idx = 0; r_idx < r_num_ranges; r_idx++) */

    return result;
}
Beispiel #13
0
void
longprune(set *tcell, set *fix, set *bottom, set *top, int m)
{
    register int i;

    while (bottom < top)
    {
        for (i = 0; i < M; ++i)
            if (NOTSUBSET(fix[i],bottom[i])) break;
        bottom += M;

        if (i == M)
            for (i = 0; i < M; ++i) INTERSECT(tcell[i],bottom[i]);
        bottom += M;
    }
}
Beispiel #14
0
int smBallGather(SMX smx,float fBall2,float *ri)
{
	KDN *c;
	PARTICLE *p;
	int pj,nCnt,cp,nSplit;
	float dx,dy,dz,x,y,z,lx,ly,lz,sx,sy,sz,fDist2;

	c = smx->kd->kdNodes;
	p = smx->kd->p;
	nSplit = smx->kd->nSplit;
	lx = smx->fPeriod[0];
	ly = smx->fPeriod[1];
	lz = smx->fPeriod[2];
	x = ri[0];
	y = ri[1];
	z = ri[2];
	nCnt = 0;
	cp = ROOT;
	while (1) {
		INTERSECT(c,cp,fBall2,lx,ly,lz,x,y,z,sx,sy,sz);
		/*
		 ** We have an intersection to test.
		 */
		if (cp < nSplit) {
			cp = LOWER(cp);
			continue;
			}
		else {
			for (pj=c[cp].pLower;pj<=c[cp].pUpper;++pj) {
				dx = sx - p[pj].r[0];
				dy = sy - p[pj].r[1];
				dz = sz - p[pj].r[2];
				fDist2 = dx*dx + dy*dy + dz*dz;
				if (fDist2 < fBall2) {
					smx->fList[nCnt] = fDist2;
					smx->pList[nCnt++] = pj;
					}
				}
			}
	GetNextCell:
		SETNEXT(cp);
		if (cp == ROOT) break;
		}
	assert(nCnt <= smx->nListSize);
	return(nCnt);
	}
Beispiel #15
0
static inline void run_checks(const void *l, const void *r) {
    range_t *left = (range_t *)l, *right = (range_t *)r;
    if (CONTAINS(left, right)) {
        if (left->err_fn)
            left->err_fn(ERROR_CONTAINS, left, right);
        FAILIF(1, "Range sorting error: [%lld, %lld) contains [%lld, %lld)!\n",
               left->start, left->start + left->length,
               right->start, right->start + right->length);
    }
    if (CONTAINS(right, left)) {
        if (right->err_fn)
            right->err_fn(ERROR_CONTAINS, left, right);
        FAILIF(1, "Range sorting error: [%lld, %lld) contains [%lld, %lld)!\n",
               right->start, right->start + right->length,
               left->start, left->start + left->length);
    }
    if (INTERSECT(left, right)) {
        if (left->err_fn)
            left->err_fn(ERROR_OVERLAPS, left, right);
        FAILIF(1, "Range sorting error: [%lld, %lld)and [%lld, %lld) intersect!\n",
               left->start, left->start + left->length,
               right->start, right->start + right->length);
    }
}
Beispiel #16
0
void
setup(void) {
	int x, y, screen = DefaultScreen(dc->dpy);
	Window root = RootWindow(dc->dpy, screen);
	XSetWindowAttributes swa;
	XIM xim;
#ifdef XINERAMA
	int n;
	XineramaScreenInfo *info;
#endif

	clip = XInternAtom(dc->dpy, "CLIPBOARD",   False);
	utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False);

	/* calculate menu geometry */
	bh = (line_height > dc->font.height + 2) ? line_height : dc->font.height + 2;
	lines = MAX(lines, 0);
	mh = (lines + 1) * bh;
#ifdef XINERAMA
	if((info = XineramaQueryScreens(dc->dpy, &n))) {
		int a, j, di, i = 0, area = 0;
		unsigned int du;
		Window w, pw, dw, *dws;
		XWindowAttributes wa;

		XGetInputFocus(dc->dpy, &w, &di);
		if(w != root && w != PointerRoot && w != None) {
			/* find top-level window containing current input focus */
			do {
				if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws)
					XFree(dws);
			} while(w != root && w != pw);
			/* find xinerama screen with which the window intersects most */
			if(XGetWindowAttributes(dc->dpy, pw, &wa))
				for(j = 0; j < n; j++)
					if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
						area = a;
						i = j;
					}
		}
		/* no focused window is on screen, so use pointer location instead */
		if(!area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
			for(i = 0; i < n; i++)
				if(INTERSECT(x, y, 1, 1, info[i]))
					break;

		x = info[i].x_org;
		y = info[i].y_org + (topbar ? yoffset : info[i].height - mh - yoffset);
		mw = info[i].width;
		XFree(info);
	}
	else
#endif
	{
		x = 0;
		y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh - yoffset;
		mw = DisplayWidth(dc->dpy, screen);
	}

	x += xoffset;
	mw = width ? width : mw;
	promptw = (prompt && *prompt) ? textw(dc, prompt) : 0;
	inputw = MIN(inputw, mw/3);
	match();

	/* create menu window */
	swa.override_redirect = True;
	swa.background_pixel = normcol->BG;
	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
	win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0,
	                    DefaultDepth(dc->dpy, screen), CopyFromParent,
	                    DefaultVisual(dc->dpy, screen),
	                    CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);

	/* open input methods */
	xim = XOpenIM(dc->dpy, NULL, NULL, NULL);
	xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
	                XNClientWindow, win, XNFocusWindow, win, NULL);

	XMapRaised(dc->dpy, win);
	resizedc(dc, mw, mh);
	drawmenu();
}
Beispiel #17
0
int kdFoF(KD kd,float fEps)
{
	PARTICLE *p;
	KDN *c;
	int pi,pj,pn,cp;

	int iGroup;

	int *Fifo,iHead,iTail,nFifo;
	float fEps2;
	float dx,dy,dz,x,y,z,lx,ly,lz,sx,sy,sz,fDist2;
#ifdef _OPENMP
    int idSelf;
    omp_lock_t *locks;

	for (pn=0;pn<kd->nActive;++pn) kd->p[pn].iTouched = -1;
    /* We really want to make an independent lock for each particle.  However, each lock
     * seems to use a buttload of memory (something like 312 bytes per lock).  Therefore,
     * to ensure that we don't use too much memory, only use 1 lock per 100 particles.
     * This should still provide very low lock contention while not using oodles of 
     * memory at the same time, since it is extremely rare that two threads will be looking
     * two particles that map to the same lock at the same time.*/
    kd->nHash = (int)(kd->nActive/100);
    locks = (omp_lock_t *)malloc(kd->nHash*sizeof(omp_lock_t));
    assert(locks != NULL);
    for (pn=0;pn<kd->nHash;++pn) omp_init_lock(&locks[pn]);
#endif

	p = kd->p;
	c = kd->kdNodes;
	lx = kd->fPeriod[0];
	ly = kd->fPeriod[1];
	lz = kd->fPeriod[2];
	fEps2 = fEps*fEps;
	for (pn=0;pn<kd->nActive;++pn) p[pn].iGroup = 0;
#pragma omp parallel default(none) shared(kd,locks,p,c,lx,ly,lz,fEps2) \
    private(pi,pj,pn,cp,iGroup,Fifo,iHead,iTail,dx,dy,dz,x,y,z,sx,sy,sz,fDist2,idSelf,nFifo)
  {
#ifdef _OPENMP
    nFifo = kd->nActive/omp_get_num_threads();
    idSelf = omp_get_thread_num();
#else
    nFifo = kd->nActive;
#endif
	Fifo = (int *)malloc(nFifo*sizeof(int));
	assert(Fifo != NULL);
	iHead = 0;
	iTail = 0;
	iGroup = 0;
#pragma omp for schedule(runtime)
	for (pn=0;pn<kd->nActive;++pn) {
		if (p[pn].iGroup) continue;
		/*
		 ** Mark it and add to the do-fifo.
		 */
#ifdef _OPENMP
        omp_set_lock(&locks[_hashLock(kd,pn)]);
        if (p[pn].iTouched >= 0 && p[pn].iTouched < idSelf ) {
            assert(p[pn].iGroup > 0);
            omp_unset_lock(&locks[_hashLock(kd,pn)]);
            continue;
        }
        p[pn].iTouched = idSelf;
        iGroup = pn+1;
		p[pn].iGroup = iGroup;
        omp_unset_lock(&locks[_hashLock(kd,pn)]);
#else
		++iGroup;
		p[pn].iGroup = iGroup;
#endif
		Fifo[iTail++] = pn;
		if (iTail == nFifo) iTail = 0;
		while (iHead != iTail) {
			pi = Fifo[iHead++];
			if (iHead == nFifo) iHead = 0;
			/*
			 ** Now do an fEps-Ball Gather!
			 */
			x = p[pi].r[0];
			y = p[pi].r[1];
			z = p[pi].r[2];
			cp = ROOT;
			while (1) {
				INTERSECT(c,cp,fEps2,lx,ly,lz,x,y,z,sx,sy,sz);
				/*
				 ** We have an intersection to test.
				 */
				if (c[cp].iDim >= 0) {
					cp = LOWER(cp);
					continue;
					}
				else {
					for (pj=c[cp].pLower;pj<=c[cp].pUpper;++pj) {
#ifdef _OPENMP
                        if (p[pj].iGroup == iGroup) {
                            /* We have already looked at this particle */
                            //assert(p[pj].iTouched == idSelf);  particle is not locked.
                            continue;
                        }
                        if (p[pj].iTouched >= 0 && p[pj].iTouched < idSelf) {
                            /* Somebody more important than us is already looking at this
                             * particle.  However, we do not yet know if this particle belongs
                             * in our group, so just skip it to save time but don't restart the
                             * entire group. */
                            // assert(p[pj].iGroup > 0); particle is not locked
                            continue;
                        }
#else
						if (p[pj].iGroup) continue;
#endif
						dx = sx - p[pj].r[0];
						dy = sy - p[pj].r[1];
						dz = sz - p[pj].r[2];
						fDist2 = dx*dx + dy*dy + dz*dz;
						if (fDist2 < fEps2) {
							/*
							 ** Mark it and add to the do-fifo.
							 */
#ifdef _OPENMP
                            omp_set_lock(&locks[_hashLock(kd,pj)]);
                            if (p[pj].iTouched >= 0 && p[pj].iTouched < idSelf) {
                                /* Now we know this particle should be in our group.  If somebody more
                                 * important than us touched it, about the entire group. */
                                assert(p[pj].iGroup > 0);
                                omp_unset_lock(&locks[_hashLock(kd,pj)]);
                                iHead = iTail;
                                /*printf("Thread %d: Aborting group %d. p[%d].iOrder  p.iGroup=%d  p.iTouched=%d (Per-Particle2)\n",
                                  idSelf, iGroup, pj, p[pj].iOrder, p[pj].iGroup, p[pj].iTouched);*/
                                goto RestartSnake;
                            }
                            p[pj].iTouched = idSelf;
							p[pj].iGroup = iGroup;
                            omp_unset_lock(&locks[_hashLock(kd,pj)]);
#else
							p[pj].iGroup = iGroup;
#endif
							Fifo[iTail++] = pj;
							if (iTail == nFifo) iTail = 0;
							}
						}
					SETNEXT(cp);
					if (cp == ROOT) break;
					continue;
					}
			ContainedCell:
				for (pj=c[cp].pLower;pj<=c[cp].pUpper;++pj) {
#ifdef _OPENMP
                    if (p[pj].iGroup == iGroup) continue;
                    if (p[pj].iTouched >= 0 && p[pj].iTouched < idSelf) {
                        /* Somebody more important that us is already looking at this
                         * group.  Abort this entire group! */
                        //assert(p[pj].iGroup > 0); particle is not locked
                        iHead = iTail;
                        /*printf("Thread %d: Aborting group %d. p[%d].iOrder=%d  p.iGroup=%d  p.iTouched=%d (Per-Cell1)\n",
                          idSelf, iGroup, pj, p[pj].iOrder, p[pj].iGroup, p[pj].iTouched);*/
                        goto RestartSnake;
                    }
#else
					if (p[pj].iGroup) continue;
#endif                    
					/*
					 ** Mark it and add to the do-fifo.
					 */
#ifdef _OPENMP
                    omp_set_lock(&locks[_hashLock(kd,pj)]);
                    if (p[pj].iTouched >= 0 && p[pj].iTouched < idSelf) {
                        /* Check again in case somebody touched it before the lock. */
                        assert(p[pj].iGroup > 0);
                        omp_unset_lock(&locks[_hashLock(kd,pj)]);
                        iHead = iTail;
                        /*printf("Thread %d: Aborting group %d.  p[%d].iGroup=%d  p[%d].iTouched=%d (Per-Cell2)\n",
                          idSelf, iGroup, pj, p[pj].iGroup, pj, p[pj].iTouched);*/
                        goto RestartSnake;
                    }
                    p[pj].iTouched = idSelf;
                    p[pj].iGroup = iGroup;
                    omp_unset_lock(&locks[_hashLock(kd,pj)]);
#else
					p[pj].iGroup = iGroup;
#endif
					Fifo[iTail++] = pj;
					if (iTail == nFifo) iTail = 0;
					}
			GetNextCell:
				SETNEXT(cp);
				if (cp == ROOT) break;
            }
        } /* End while(iHead != iTail) */
#ifdef _OPENMP
    RestartSnake:
#endif
        assert(iHead == iTail);
    }
	free(Fifo);
  }  /* End of the OpenMP PARALLEL section */

#ifdef _OPENMP
    /* Now we have count how many groups there are.  This is straightforward,
     * since the number of groups is the number of particles whose groupID equals
     * their particleID+1. */
    pj = 0;
	for (pn=0;pn<kd->nActive;++pn)
        if (p[pn].iGroup == pn+1) ++pj;
    kd->nGroup = (kd->nActive)+1;
    free(locks);
#else
	kd->nGroup = iGroup+1;
#endif
	return(kd->nGroup-1);
	}
Beispiel #18
0
static void
setup(void)
{
	int x, y;
	XSetWindowAttributes swa;
	XIM xim;
#ifdef XINERAMA
	XineramaScreenInfo *info;
	Window w, pw, dw, *dws;
	XWindowAttributes wa;
	int a, j, di, n, i = 0, area = 0;
	unsigned int du;
#endif

	/* init appearance */
	scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor);
	scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor);
	scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor);
	scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor);
	scheme[SchemeOut].bg = drw_clr_create(drw, outbgcolor);
	scheme[SchemeOut].fg = drw_clr_create(drw, outfgcolor);

	clip = XInternAtom(dpy, "CLIPBOARD",   False);
	utf8 = XInternAtom(dpy, "UTF8_STRING", False);

	/* calculate menu geometry */
	bh = drw->fonts[0]->h + 2;
	lines = MAX(lines, 0);
	mh = (lines + 1) * bh;
#ifdef XINERAMA
	if ((info = XineramaQueryScreens(dpy, &n))) {
		XGetInputFocus(dpy, &w, &di);
		if (mon != -1 && mon < n)
			i = mon;
		if (!i && w != root && w != PointerRoot && w != None) {
			/* find top-level window containing current input focus */
			do {
				if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
					XFree(dws);
			} while (w != root && w != pw);
			/* find xinerama screen with which the window intersects most */
			if (XGetWindowAttributes(dpy, pw, &wa))
				for (j = 0; j < n; j++)
					if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
						area = a;
						i = j;
					}
		}
		/* no focused window is on screen, so use pointer location instead */
		if (mon == -1 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
			for (i = 0; i < n; i++)
				if (INTERSECT(x, y, 1, 1, info[i]))
					break;

		x = info[i].x_org;
		y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
		mw = info[i].width;
		XFree(info);
	} else
#endif
	{
		x = 0;
		y = topbar ? 0 : sh - mh;
		mw = sw;
	}
	promptw = (prompt && *prompt) ? TEXTW(prompt) : 0;
	inputw = MIN(inputw, mw/3);
	match();

	/* create menu window */
	swa.override_redirect = True;
	swa.background_pixel = scheme[SchemeNorm].bg->pix;
	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
	                    DefaultDepth(dpy, screen), CopyFromParent,
	                    DefaultVisual(dpy, screen),
	                    CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);

	/* open input methods */
	xim = XOpenIM(dpy, NULL, NULL, NULL);
	xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
	                XNClientWindow, win, XNFocusWindow, win, NULL);

	XMapRaised(dpy, win);
	drw_resize(drw, mw, mh);
	drawmenu();
}
Beispiel #19
0
void smBallSearch(SMX smx,float fBall2,float *ri)
{
	KDN *c;
	PARTICLE *p;
	int cell,cp,ct,pj;
	float fDist2,dx,dy,dz,lx,ly,lz,sx,sy,sz,x,y,z;
	PQ *pq;

	c = smx->kd->kdNodes;
	p = smx->kd->p;
	pq = smx->pqHead;
	x = ri[0];
	y = ri[1];
	z = ri[2];
	lx = smx->fPeriod[0];
	ly = smx->fPeriod[1];
	lz = smx->fPeriod[2];
	cell = ROOT;
	/*
	 ** First find the "local" Bucket.
	 ** This could mearly be the closest bucket to ri[3].
	 */
	while (cell < smx->kd->nSplit) {
		if (ri[c[cell].iDim] < c[cell].fSplit) cell = LOWER(cell);
		else cell = UPPER(cell);
		}
	/*
	 ** Now start the search from the bucket given by cell!
	 */
	for (pj=c[cell].pLower;pj<=c[cell].pUpper;++pj) {
		dx = x - p[pj].r[0];
		dy = y - p[pj].r[1];
		dz = z - p[pj].r[2];
		fDist2 = dx*dx + dy*dy + dz*dz;
		if (fDist2 < fBall2) {
			if (smx->iMark[pj]) continue;
			smx->iMark[pq->p] = 0;
			smx->iMark[pj] = 1;
			pq->fKey = fDist2;
			pq->p = pj;
			pq->ax = 0.0;
			pq->ay = 0.0;
			pq->az = 0.0;
			PQ_REPLACE(pq);
			fBall2 = pq->fKey;
			}
		}
	while (cell != ROOT) {
		cp = SIBLING(cell);
		ct = cp;
		SETNEXT(ct);
		while (1) {
			INTERSECT(c,cp,fBall2,lx,ly,lz,x,y,z,sx,sy,sz);
			/*
			 ** We have an intersection to test.
			 */
			if (cp < smx->kd->nSplit) {
				cp = LOWER(cp);
				continue;
				}
			else {
				for (pj=c[cp].pLower;pj<=c[cp].pUpper;++pj) {
					dx = sx - p[pj].r[0];
					dy = sy - p[pj].r[1];
					dz = sz - p[pj].r[2];
					fDist2 = dx*dx + dy*dy + dz*dz;
					if (fDist2 < fBall2) {
						if (smx->iMark[pj]) continue;
						smx->iMark[pq->p] = 0;
						smx->iMark[pj] = 1;
						pq->fKey = fDist2;
						pq->p = pj;
						pq->ax = sx - x;
						pq->ay = sy - y;
						pq->az = sz - z;
						PQ_REPLACE(pq);
						fBall2 = pq->fKey;
						}
					}
				}
		GetNextCell:
			SETNEXT(cp);
			if (cp == ct) break;
			}
		cell = PARENT(cell);
		}
	smx->pqHead = pq;
	}
Beispiel #20
0
static void
check_init (tree exp, words before)
{
  tree tmp;
 again:
  switch (TREE_CODE (exp))
    {
    case VAR_DECL:
    case PARM_DECL:
      if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE
	  && DECL_NAME (exp) != this_identifier_node)
	{
	  int index = DECL_BIT_INDEX (exp);
	  /* We don't want to report and mark as non-initialized class
	     initialization flags. */
	  if (! LOCAL_CLASS_INITIALIZATION_FLAG_P (exp)
	      && index >= 0 && ! ASSIGNED_P (before, index))
	    {
	      parse_error_context 
		(wfl, "Variable %qs may not have been initialized",
		 IDENTIFIER_POINTER (DECL_NAME (exp)));
	      /* Suppress further errors. */
	      DECL_BIT_INDEX (exp) = -2;
	    }
	}
      break;

    case COMPONENT_REF:
      check_init (TREE_OPERAND (exp, 0), before);
      if ((tmp = get_variable_decl (exp)) != NULL_TREE)
	{
	  int index = DECL_BIT_INDEX (tmp);
	  if (index >= 0 && ! ASSIGNED_P (before, index))
	    {
	      parse_error_context 
		(wfl, "variable %qs may not have been initialized",
		 IDENTIFIER_POINTER (DECL_NAME (tmp)));
	      /* Suppress further errors. */
	      DECL_BIT_INDEX (tmp) = -2;
	    }
	}
      break;
      
    case MODIFY_EXPR:
      tmp = TREE_OPERAND (exp, 0);
      /* We're interested in variable declaration and parameter
         declaration when they're declared with the `final' modifier. */
      if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
	{
	  int index;
	  check_init (TREE_OPERAND (exp, 1), before);
	  check_final_reassigned (tmp, before);
	  index = DECL_BIT_INDEX (tmp);
	  if (index >= 0)
	    {
	      SET_ASSIGNED (before, index);
	      CLEAR_UNASSIGNED (before, index);
	    }
	  /* Minor optimization.  See comment for start_current_locals.
	     If we're optimizing for class initialization, we keep
	     this information to check whether the variable is
	     definitely assigned when once we checked the whole
	     function. */
	  if (! STATIC_CLASS_INIT_OPT_P () /* FIXME */
	      && ! DECL_FINAL (tmp)
	      && index >= start_current_locals
	      && index == num_current_locals - 1)
	    {
	      num_current_locals--;
	      DECL_BIT_INDEX (tmp) = -1;
	    }
	 break;
       }
      else if (TREE_CODE (tmp = TREE_OPERAND (exp, 0)) == COMPONENT_REF)
	{
	  tree decl;
	  check_init (tmp, before);
	  check_init (TREE_OPERAND (exp, 1), before);
	  decl = TREE_OPERAND (tmp, 1);
	  if (DECL_FINAL (decl))
	    final_assign_error (DECL_NAME (decl));
	  break;
	}
      else if (TREE_CODE (tmp) == COMPONENT_REF && IS_ARRAY_LENGTH_ACCESS (tmp))
	{
	  /* We can't emit a more specific message here, because when
	     compiling to bytecodes we don't get here. */
	  final_assign_error (length_identifier_node);
	}
     else
       goto binop;
    case BLOCK:
      if (BLOCK_EXPR_BODY (exp))
	{
	  tree decl = BLOCK_EXPR_DECLS (exp);
	  int words_needed;
	  word* tmp;
	  int i;
	  int save_start_current_locals = start_current_locals;
	  int save_num_current_words = num_current_words;
	  start_current_locals = num_current_locals;
	  for (;  decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	    {
	      DECL_BIT_INDEX (decl) = num_current_locals++;
	    }
	  words_needed = WORDS_NEEDED (2 * num_current_locals);
	  if (words_needed > num_current_words)
	    {
	      tmp = ALLOC_WORDS (words_needed);
	      COPY (tmp, before);
	      num_current_words = words_needed;
	    }
	  else
	    tmp = before;
	  for (i = start_current_locals;  i < num_current_locals;  i++)
	    {
	      CLEAR_ASSIGNED (tmp, i);
	      SET_UNASSIGNED (tmp, i);
	    }
	  check_init (BLOCK_EXPR_BODY (exp), tmp);

	  /* Re-set DECL_BIT_INDEX since it is also DECL_POINTER_ALIAS_SET. */
	  for (decl = BLOCK_EXPR_DECLS (exp);
	       decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	    {
	      if (LOCAL_CLASS_INITIALIZATION_FLAG_P (decl))
		{
		  int index = DECL_BIT_INDEX (decl);
		  tree fndecl = DECL_CONTEXT (decl);
		  if (fndecl && METHOD_STATIC (fndecl)
		      && (DECL_INITIAL (decl) == boolean_true_node
			  || (index >= 0 && ASSIGNED_P (tmp, index))))
		    *(htab_find_slot 
		      (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
		       DECL_FUNCTION_INIT_TEST_CLASS (decl), INSERT)) =
		      DECL_FUNCTION_INIT_TEST_CLASS (decl);
		}
	      DECL_BIT_INDEX (decl) = -1;
	    }

	  num_current_locals = start_current_locals;
	  start_current_locals = save_start_current_locals;
	  if (tmp != before)
	    {
	      num_current_words = save_num_current_words;
	      COPY (before, tmp);
	      FREE_WORDS (tmp);
	    }
	}
      break;
    case LOOP_EXPR:
      {
	/* The JLS 2nd edition discusses a complication determining
	   definite unassignment of loop statements.  They define a
	   "hypothetical" analysis model.  We do something much
	   simpler: We just disallow assignments inside loops to final
	   variables declared outside the loop.  This means we may
	   disallow some contrived assignments that the JLS allows, but I
	   can't see how anything except a very contrived testcase (a
	   do-while whose condition is false?) would care. */

	struct alternatives alt;
	int save_loop_current_locals = loop_current_locals;
	int save_start_current_locals = start_current_locals;
	loop_current_locals = num_current_locals;
	start_current_locals = num_current_locals;
	BEGIN_ALTERNATIVES (before, alt);
	alt.block = exp;
	check_init (TREE_OPERAND (exp, 0), before);
	END_ALTERNATIVES (before, alt);
	loop_current_locals = save_loop_current_locals;
	start_current_locals = save_start_current_locals;
	return;
      }
    case EXIT_EXPR:
      {
	struct alternatives *alt = alternatives;
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
#ifdef ENABLE_JC1_CHECKING
	if (TREE_CODE (alt->block) != LOOP_EXPR)
	  abort ();
#endif
	check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true);
	done_alternative (when_true, alt);
	COPY (before, when_false);
	RELEASE_BUFFERS(when_true);
	return;
      }
    case LABELED_BLOCK_EXPR:
      {
	struct alternatives alt;
	BEGIN_ALTERNATIVES (before, alt);
	alt.block = exp;
	if (LABELED_BLOCK_BODY (exp))
	  check_init (LABELED_BLOCK_BODY (exp), before);
	done_alternative (before, &alt);
	END_ALTERNATIVES (before, alt);
	return;
      }
    case EXIT_BLOCK_EXPR:
      {
	tree block = TREE_OPERAND (exp, 0);
	struct alternatives *alt = alternatives;
	while (alt->block != block)
	  alt = alt->outer;
	done_alternative (before, alt);
	SET_ALL (before);
	return;
      }
    case SWITCH_EXPR:
      {
	struct alternatives alt;
	word buf[2];
	check_init (TREE_OPERAND (exp, 0), before);
	BEGIN_ALTERNATIVES (before, alt);
	alt.saved = ALLOC_BUFFER(buf, num_current_words);
	COPY (alt.saved, before);
	alt.block = exp;
	check_init (TREE_OPERAND (exp, 1), before);
	done_alternative (before, &alt);
	if (! SWITCH_HAS_DEFAULT (exp))
	  done_alternative (alt.saved, &alt);
	FREE_BUFFER(alt.saved, buf);
	END_ALTERNATIVES (before, alt);
	return;
      }
    case CASE_EXPR:
    case DEFAULT_EXPR:
      {
	int i;
	struct alternatives *alt = alternatives;
	while (TREE_CODE (alt->block) != SWITCH_EXPR)
	  alt = alt->outer;
	COPYN (before, alt->saved, WORDS_NEEDED (2 * alt->num_locals));
	for (i = alt->num_locals;  i < num_current_locals;  i++)
	  CLEAR_ASSIGNED (before, i);
	break;
      }

    case TRY_EXPR:
      {
	tree try_clause = TREE_OPERAND (exp, 0);
	tree clause = TREE_OPERAND (exp, 1);
	word buf[2*2];
	words tmp = (num_current_words <= 2 ? buf
		    : ALLOC_WORDS (2 * num_current_words));
	words save = tmp + num_current_words;
	struct alternatives alt;
	BEGIN_ALTERNATIVES (before, alt);
	COPY (save, before);
	COPY (tmp, save);
	check_init (try_clause, tmp);
	done_alternative (tmp, &alt);
	for ( ; clause != NULL_TREE;  clause = TREE_CHAIN (clause))
	  {
	    tree catch_clause = TREE_OPERAND (clause, 0);
	    COPY (tmp, save);
	    check_init (catch_clause, tmp);
	    done_alternative (tmp, &alt);
	  }
	if (tmp != buf)
	  {
	    FREE_WORDS (tmp);
	  }
	END_ALTERNATIVES (before, alt);
      }
    return;

    case TRY_FINALLY_EXPR:
      {
	DECLARE_BUFFERS(tmp, 1);
	COPY (tmp, before);
	check_init (TREE_OPERAND (exp, 0), before);
	check_init (TREE_OPERAND (exp, 1), tmp);
	UNION (before, before, tmp);
	RELEASE_BUFFERS(tmp);
      }
      return;

    case RETURN_EXPR:
    case THROW_EXPR:
      if (TREE_OPERAND (exp, 0))
	check_init (TREE_OPERAND (exp, 0), before);
      goto never_continues;

    case ERROR_MARK:
    never_continues:
      SET_ALL (before);
      return;
      
    case COND_EXPR:
    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
      {
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
	check_bool_init (exp, before, when_false, when_true);
	INTERSECT (before, when_false, when_true);
	RELEASE_BUFFERS(when_true);
      }
      break;

    case NOP_EXPR:
      if (IS_EMPTY_STMT (exp))
	break;
      /* ... else fall through ... */
    case UNARY_PLUS_EXPR:
    case NEGATE_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
    case TRUTH_NOT_EXPR:
    case BIT_NOT_EXPR:
    case CONVERT_EXPR:
    case BIT_FIELD_REF:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
    case INDIRECT_REF:
    case ADDR_EXPR:
    case NON_LVALUE_EXPR:
    case INSTANCEOF_EXPR:
    case FIX_CEIL_EXPR:
    case FIX_FLOOR_EXPR:
    case FIX_ROUND_EXPR:
    case ABS_EXPR:
      /* Avoid needless recursion. */
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case PREDECREMENT_EXPR:
    case PREINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
      tmp = get_variable_decl (TREE_OPERAND (exp, 0));
      if (tmp != NULL_TREE && DECL_FINAL (tmp))
	final_assign_error (DECL_NAME (tmp));      

      /* Avoid needless recursion.  */
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case SAVE_EXPR:
      if (IS_INIT_CHECKED (exp))
	return;
      IS_INIT_CHECKED (exp) = 1;
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case COMPOUND_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case RDIV_EXPR:
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case URSHIFT_EXPR:
    case BIT_AND_EXPR:
    case BIT_XOR_EXPR:
    case BIT_IOR_EXPR:
    case EQ_EXPR: 
    case NE_EXPR:
    case GT_EXPR:
    case GE_EXPR:
    case LT_EXPR:
    case LE_EXPR:
    case MAX_EXPR:
    case MIN_EXPR:
    case ARRAY_REF:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case EXACT_DIV_EXPR:
    case UNLT_EXPR:
    case UNLE_EXPR:
    case UNGT_EXPR:
    case UNGE_EXPR:
    case UNEQ_EXPR:
    case LTGT_EXPR:
    binop:
      check_init (TREE_OPERAND (exp, 0), before);
      /* Avoid needless recursion, especially for COMPOUND_EXPR. */
      exp = TREE_OPERAND (exp, 1);
      goto again;

    case RESULT_DECL:
    case FUNCTION_DECL:
    case INTEGER_CST:
    case REAL_CST:
    case STRING_CST:
    case JAVA_EXC_OBJ_EXPR:
      break;

    case NEW_CLASS_EXPR:
    case CALL_EXPR:
      {
	tree func = TREE_OPERAND (exp, 0);
	tree x = TREE_OPERAND (exp, 1);
	if (TREE_CODE (func) == ADDR_EXPR)
	  func = TREE_OPERAND (func, 0);
	check_init (func, before);

	for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
	  check_init (TREE_VALUE (x), before);
	if (func == throw_node)
	  goto never_continues;
      }
      break;

    case NEW_ARRAY_INIT:
      {
	tree x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
	for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
	  check_init (TREE_VALUE (x), before);
      }
      break;

    case EXPR_WITH_FILE_LOCATION:
      {
	location_t saved_location = input_location;
	tree saved_wfl = wfl;
	tree body = EXPR_WFL_NODE (exp);
	if (IS_EMPTY_STMT (body))
	  break;
	wfl = exp;
#ifdef USE_MAPPED_LOCATION
	input_location = EXPR_LOCATION (exp);
#else
	input_filename = EXPR_WFL_FILENAME (exp);
	input_line = EXPR_WFL_LINENO (exp);
#endif
	check_init (body, before);
	input_location = saved_location;
	wfl = saved_wfl;
      }
      break;
      
    default:
      internal_error
	("internal error in check-init: tree code not implemented: %s",
	 tree_code_name [(int) TREE_CODE (exp)]);
    }
}
Beispiel #21
0
/* Plotting procedure. 
 * X-axis is segmented according to 'delta' distance, that is distance between
 * consecutive x's (x_i to x_{i + 1} distance). Infinity and NaN checks are 
 * performed and corresponding action is taken to prevent mess. 
 * Infinity case is handled by computing intersect with plot-box. NaNs
 * are not plotted at all.
 * Adaptive smoothing is performed at the end of plot loop.
 */
static void plot(FILE * out, parsed_expr p)
{
    double delta = (x_high - x_low) / SMOOTHNESS;
    double x_1 = x_low;
    double x_2 = x_low + delta;
    double y_1 = evaluate(p, x_1);
    double y_2 = evaluate(p, x_2);
    double old_x;
    double old_y;
    /* if y-value out of box, compute intersection of line with box */
    double x_intersect;
    int last_out = 1, last_nan = 0;
    int SMOOTHNESS_LVL = MAX_SMOOTHNESS_LVL;



/* Transformation of real number coordinates to plot box coordinates.
 * Plot is in lanscape mode, real x-coordinates are mappend to plot 
 * y-coordinate and vice versa.
 * Plot y-coordinates are flipped vertically
 */
#define COORD_X(x) (((x) - x_low) * scale_x + LLY + BLANK)
#define COORD_Y(y) (URX - BLANK - (((y) - y_low) * scale_y))

/* Redefine postscript lineto and moveto commands, such that there is 
 * no need to take care of coordinate transformations.
 * x and y coordinates are swapped here.
 */
#define LINETO(x, y) fprintf(out, "%.3f %.3f lineto\n", \
                             COORD_Y(y), COORD_X(x))
#define MOVETO(x, y) fprintf(out, "%.3f %.3f moveto\n", \
                             COORD_Y(y), COORD_X(x))

/* find intersection with y-boundary */
#define INTERSECT(boundary) (x_1 + ((boundary) - y_1) * \
                            (x_2 - x_1) / (y_2 - y_1));

    if (y_1 < y_low)
        y_1 = y_low;
    else if (y_1 > y_high)
        y_1 = y_high;
    else
        last_out = 0;

    /* New path exclusively for function plot */
    fprintf(out, "newpath\n");
    if (!IS_NAN(y_1))
        MOVETO(x_1, y_1);
    else
        last_nan = 1;


    old_x = x_1;
    old_y = y_1;

    /* plotting loop */
    while (x_2 <= x_high) {
        if (IS_NAN(y_2))
            last_nan = 1;
        /* next point is in bounding box, thus can be plotted */
        else if (y_low <= y_2 && y_2 <= y_high) {
            /* handle case where last point was NaN */
            if (last_nan) {
                MOVETO(x_2, y_2);
                last_nan = 0;
                /* handle case where last point was out of box, 
                 * find intersections with box. Next line will start
                 * from this point 
                 */
            } else if (last_out) {
                /* point is too high or too low? */
                if (y_2 > y_1) {
                    x_intersect = INTERSECT(y_low);
                    if (IS_NAN(x_intersect))
                        x_intersect = x_1;
                    MOVETO(x_intersect, y_low);
                } else {
                    x_intersect = INTERSECT(y_high);
                    if (IS_NAN(x_intersect))
                        x_intersect = x_1;
                    MOVETO(x_intersect, y_high);
                }
            }
            /* Draw a valid line. This plots most of the lines. */
            LINETO(x_2, y_2);

            last_out = 0;
            /* case where next point is out of the box */
        } else {
            /* if last point was in the box, stroke a line to the intersection
             * with y-boundary */
            if (!last_out && !last_nan) {
                if (y_2 > y_1) {
                    x_intersect = INTERSECT(y_high);
                    if (IS_NAN(x_intersect))
                        x_intersect = x_1;
                    LINETO(x_intersect, y_high);
                } else {
                    x_intersect = INTERSECT(y_low);
                    if (IS_NAN(x_intersect))
                        x_intersect = x_1;
                    LINETO(x_intersect, y_low);
                }
            }

            last_out = 1;
        }

/** smoothing procedure **/
/* SLOPE_JUMP is numerically evaluated second derivative, that is 
 * difference of first derivatives. Expression is simplified algebraically
 */
#define SLOPE_JUMP (y_2 - y_1 - ((y_1 - old_y)*(x_2 - x_1))/(x_1 - old_x))
#define TOO_SHARP() (fabs(SLOPE_JUMP) > THRESHOLD)
#define TOO_SMOOTH() (fabs(SLOPE_JUMP) < THRESHOLD / 4)

        old_x = x_1;
        old_y = y_1;
        x_1 = x_2;
        y_1 = y_2;
        x_2 = x_1 + delta;
        y_2 = evaluate(p, x_2);

        /* If the plot is too sharp or too smooth, 
         * find appropriate smoothness lvl 
         * by increasing/decreasing smoothness until right one is found.
         */
        if (TOO_SHARP()) {
            while (SMOOTHNESS_LVL < MAX_SMOOTHNESS_LVL && TOO_SHARP()) {
                delta /= 2;
                x_2 = x_1 + delta;
                y_2 = evaluate(p, x_2);
                SMOOTHNESS_LVL++;
            }
        } else {
            while (SMOOTHNESS_LVL > 0 && TOO_SMOOTH()) {
                delta *= 2;
                x_2 = x_1 + delta;
                y_2 = evaluate(p, x_2);
                SMOOTHNESS_LVL--;
            }
        }

        /* make sure the last point is on the right boundary */
        if (x_1 < x_high && x_1 + delta > x_high) {
            x_2 = x_high;
            y_2 = evaluate(p, x_2);
        }
    }

    /* stroke the path */
    fprintf(out, "%s setrgbcolor\n", PLOT_COLOR);
    fprintf(out, "0.5 setlinewidth\n");
    fprintf(out, "stroke\n\n\n");
}