Example #1
0
/* Compute and insert migration along directed edge (may fork child) */
static MIGRATION *
create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
{
	const double	end_thresh = 5e-6;
	PRICEMAT	pmtx;
	MIGRATION	*newmig;
	double		*src_rem, *dst_rem;
	double		total_rem = 1., move_amt;
	int		i, j;
						/* check if exists already */
	for (newmig = from_rbf->ejl; newmig != NULL;
			newmig = nextedge(from_rbf,newmig))
		if (newmig->rbfv[1] == to_rbf)
			return(NULL);
						/* else allocate */
#ifdef DEBUG
	fprintf(stderr, "Building path from (theta,phi) (%.0f,%.0f) ",
			get_theta180(from_rbf->invec),
			get_phi360(from_rbf->invec));
	fprintf(stderr, "to (%.0f,%.0f) with %d x %d matrix\n",
			get_theta180(to_rbf->invec),
			get_phi360(to_rbf->invec), 
			from_rbf->nrbf, to_rbf->nrbf);
#endif
	newmig = new_migration(from_rbf, to_rbf);
	if (run_subprocess())
		return(newmig);			/* child continues */
	price_routes(&pmtx, from_rbf, to_rbf);
	src_rem = (double *)malloc(sizeof(double)*from_rbf->nrbf);
	dst_rem = (double *)malloc(sizeof(double)*to_rbf->nrbf);
	if ((src_rem == NULL) | (dst_rem == NULL)) {
		fprintf(stderr, "%s: Out of memory in create_migration()\n",
				progname);
		exit(1);
	}
						/* starting quantities */
	memset(newmig->mtx, 0, sizeof(float)*from_rbf->nrbf*to_rbf->nrbf);
	for (i = from_rbf->nrbf; i--; )
		src_rem[i] = rbf_volume(&from_rbf->rbfa[i]) / from_rbf->vtotal;
	for (j = to_rbf->nrbf; j--; )
		dst_rem[j] = rbf_volume(&to_rbf->rbfa[j]) / to_rbf->vtotal;

	do {					/* move a bit at a time */
		move_amt = migration_step(newmig, src_rem, dst_rem, &pmtx);
		total_rem -= move_amt;
	} while ((total_rem > end_thresh) & (move_amt > 0));

	for (i = from_rbf->nrbf; i--; ) {	/* normalize final matrix */
	    double	nf = rbf_volume(&from_rbf->rbfa[i]);
	    if (nf <= FTINY) continue;
	    nf = from_rbf->vtotal / nf;
	    for (j = to_rbf->nrbf; j--; )
		mtx_coef(newmig,i,j) *= nf;	/* row now sums to 1.0 */
	}
	end_subprocess();			/* exit here if subprocess */
	free_routes(&pmtx);			/* free working arrays */
	free(src_rem);
	free(dst_rem);
	return(newmig);
}
Example #2
0
/* Find vertices completing triangles on either side of the given edge */
int
get_triangles(RBFNODE *rbfv[2], const MIGRATION *mig)
{
	const MIGRATION	*ej1, *ej2;
	RBFNODE		*tv;

	rbfv[0] = rbfv[1] = NULL;
	if (mig == NULL)
		return(0);
	for (ej1 = mig->rbfv[0]->ejl; ej1 != NULL;
				ej1 = nextedge(mig->rbfv[0],ej1)) {
		if (ej1 == mig)
			continue;
		tv = opp_rbf(mig->rbfv[0],ej1);
		for (ej2 = tv->ejl; ej2 != NULL; ej2 = nextedge(tv,ej2))
			if (opp_rbf(tv,ej2) == mig->rbfv[1]) {
				rbfv[is_rev_tri(mig->rbfv[0]->invec,
						mig->rbfv[1]->invec,
						tv->invec)] = tv;
				break;
			}
	}
	return((rbfv[0] != NULL) + (rbfv[1] != NULL));
}
Example #3
0
/* Compute and insert migration along directed edge (may fork child) */
static MIGRATION *
create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
{
	MIGRATION	*newmig;
	int		i, j;
						/* check if exists already */
	for (newmig = from_rbf->ejl; newmig != NULL;
			newmig = nextedge(from_rbf,newmig))
		if (newmig->rbfv[1] == to_rbf)
			return(NULL);
						/* else allocate */
#ifdef DEBUG
	fprintf(stderr, "Building path from (theta,phi) (%.1f,%.1f) ",
			get_theta180(from_rbf->invec),
			get_phi360(from_rbf->invec));
	fprintf(stderr, "to (%.1f,%.1f) with %d x %d matrix\n",
			get_theta180(to_rbf->invec),
			get_phi360(to_rbf->invec), 
			from_rbf->nrbf, to_rbf->nrbf);
#endif
	newmig = new_migration(from_rbf, to_rbf);
	if (run_subprocess())
		return(newmig);			/* child continues */

						/* compute transport plan */
	compute_nDSFs(from_rbf, to_rbf);
	plan_transport(newmig);

	for (i = from_rbf->nrbf; i--; ) {	/* normalize final matrix */
	    double	nf = rbf_volume(&from_rbf->rbfa[i]);
	    if (nf <= FTINY) continue;
	    nf = from_rbf->vtotal / nf;
	    for (j = to_rbf->nrbf; j--; )
		mtx_coef(newmig,i,j) *= nf;	/* row now sums to 1.0 */
	}
	end_subprocess();			/* exit here if subprocess */
	return(newmig);
}
Example #4
0
/* Check if prospective vertex would create overlapping triangle */
static int
overlaps_tri(const RBFNODE *bv0, const RBFNODE *bv1, const RBFNODE *pv)
{
	const MIGRATION	*ej;
	RBFNODE		*vother[2];
	int		im_rev;
						/* find shared edge in mesh */
	for (ej = pv->ejl; ej != NULL; ej = nextedge(pv,ej)) {
		const RBFNODE	*tv = opp_rbf(pv,ej);
		if (tv == bv0) {
			im_rev = is_rev_tri(ej->rbfv[0]->invec,
					ej->rbfv[1]->invec, bv1->invec);
			break;
		}
		if (tv == bv1) {
			im_rev = is_rev_tri(ej->rbfv[0]->invec,
					ej->rbfv[1]->invec, bv0->invec);
			break;
		}
	}
	if (!get_triangles(vother, ej))		/* triangle on same side? */
		return(0);
	return(vother[im_rev] != NULL);
}
Example #5
0
void impCubeTables::makeTriStripPatterns(){
	int i, j, k;
	int currentvertex;
	int currentedge;
	bool vertices[8];  // true if on low side of gradient (outside of surface)
	bool edges[12];
	bool edgesdone[12];
	int edgelist[7];  // final list of egdes used in a triangle strip
	int edgecount;

	// Set cubetable values to zero
	// A zero will indicate that there are no more triangle strips to build
	for(i=0; i<256; i++){
		for(j=0; j<17; j++){
			triStripPatterns[i][j] = 0;
		}
	}
    
	// For each vertex combination
	for(i=0; i<256; i++){
		// identify the vertices on the low side of the gradient
		int andbit;
		for(j=0; j<8; j++){
			andbit = 1;
			for(k=0; k<j; k++)
				andbit *= 2;
			if(i & andbit)
				vertices[j] = 1;
			else
				vertices[j] = 0;
		}

		// Identify the edges that cross threshold value
		// These are edges that connect 1 turned-on and 1 turned-off vertex
		for(j=0; j<12; j++){
			if((vertices[ec[j][0]] + vertices[ec[j][1]]) == 1)
				edges[j] = 1;
			else
				edges[j] = 0;
			edgesdone[j] = 0;  // no edges have been used yet
		}

		// Construct lists of edges that form triangle strips
		// try starting from each edge (no need to try last 2 edges)
		for(j=0; j<10; j++){
			currentedge = j;
			edgecount = 0;
			// if this edge contains a surface vertex and hasn't been used
			while(edges[currentedge] && !edgesdone[currentedge]){
				// add edge to list
				edgelist[edgecount] = currentedge;
				edgecount ++;
				edgesdone[currentedge] = 1;
				// find that edge's vertex on low side of gradient
				if(vertices[ec[currentedge][0]])
					currentvertex = ec[currentedge][0];
				else
					currentvertex = ec[currentedge][1];
				// move along gradiant boundary to find next edge
				currentedge = nextedge(currentvertex, currentedge);
				while(!edges[currentedge]){
					if(currentvertex != ec[currentedge][0])
						currentvertex = ec[currentedge][0];
					else
						currentvertex = ec[currentedge][1];
					currentedge = nextedge(currentvertex, currentedge);
				}
			}
			// if a surface has been created add it to the table
			// and start over to try to make another surface
			if(edgecount)
				addtotable(i, edgecount, edgelist);
		}
	}
}