Beispiel #1
0
void cart_makecart(double *pointx, double *pointy, int npoints,
		   int xsize, int ysize, double blur)
{
  int s,sp;
  int step;
  double t,h;
  double error,dr;
  double desiredratio;

  /* Calculate the initial density and velocity for snapshot zero */

  cart_density(0.0,0,xsize,ysize);
  cart_vgrid(0,xsize,ysize);
  s = 0;

  /* Now integrate the points in the polygons */

  step = 0;
  t = 0.5*blur*blur;
  h = INITH;

  do {

    /* Do a combined (triple) integration step */

    cart_twosteps(pointx,pointy,npoints,t,h,s,xsize,ysize,&error,&dr,&sp);

    /* Increase the time by 2h and rotate snapshots */

    t += 2.0*h;
    step += 2;
    s = sp;

    /* Adjust the time-step.  Factor of 2 arises because the target for
     * the two-step process is twice the target for an individual step */

    desiredratio = pow(2*TARGETERROR/error,0.2);
    if (desiredratio>MAXRATIO) h *= MAXRATIO;
    else h *= desiredratio;

    /* If no point moved then we are finished */

  } while (dr>0.0);

}
Beispiel #2
0
void cart_twosteps(double *pointx, double *pointy, int npoints,
		   double t, double h, int s, int xsize, int ysize,
		   double *errorp, double *drp, int *spp)
{
  int s0,s1,s2,s3,s4;
  int p;
  double rx1,ry1;
  double rx2,ry2;
  double rx3,ry3;
  double v1x,v1y;
  double v2x,v2y;
  double v3x,v3y;
  double v4x,v4y;
  double k1x,k1y;
  double k2x,k2y;
  double k3x,k3y;
  double k4x,k4y;
  double dx1,dy1;
  double dx2,dy2;
  double dx12,dy12;
  double dxtotal,dytotal;
  double ex,ey;
  double esq,esqmax;
  double drsq,drsqmax;

  s0 = s;
  s1 = (s+1)%5;
  s2 = (s+2)%5;
  s3 = (s+3)%5;
  s4 = (s+4)%5;

  /* Calculate the density field for the four new time slices */

  cart_density(s0, 0.5*h, s1, xsize, ysize);
  cart_density(s1, 0.5*h, s2, xsize, ysize);
  cart_density(s2, 0.5*h, s3, xsize, ysize);
  cart_density(s3, 0.5*h, s4, xsize, ysize);

  /* Do all three RK steps for each point in turn */

  esqmax = drsqmax = 0.0;

  for (p=0; p<npoints; p++) {

    rx1 = pointx[p];
    ry1 = pointy[p];

    /* Do the big combined (2h) RK step */

    cart_velocity(rx1,ry1,s0,xsize,ysize,&v1x,&v1y);
    k1x = 2*h*v1x;
    k1y = 2*h*v1y;
    cart_velocity(rx1+0.5*k1x,ry1+0.5*k1y,s2,xsize,ysize,&v2x,&v2y);
    k2x = 2*h*v2x;
    k2y = 2*h*v2y;
    cart_velocity(rx1+0.5*k2x,ry1+0.5*k2y,s2,xsize,ysize,&v3x,&v3y);
    k3x = 2*h*v3x;
    k3y = 2*h*v3y;
    cart_velocity(rx1+k3x,ry1+k3y,s4,xsize,ysize,&v4x,&v4y);
    k4x = 2*h*v4x;
    k4y = 2*h*v4y;

    dx12 = (k1x+k4x+2.0*(k2x+k3x))/6.0;
    dy12 = (k1y+k4y+2.0*(k2y+k3y))/6.0;

    /* Do the first small RK step.  No initial call to cart_velocity() is done
     * because it would be the same as the one above, so there's no need
     * to do it again */

    k1x = h*v1x;
    k1y = h*v1y;
    cart_velocity(rx1+0.5*k1x,ry1+0.5*k1y,s1,xsize,ysize,&v2x,&v2y);
    k2x = h*v2x;
    k2y = h*v2y;
    cart_velocity(rx1+0.5*k2x,ry1+0.5*k2y,s1,xsize,ysize,&v3x,&v3y);
    k3x = h*v3x;
    k3y = h*v3y;
    cart_velocity(rx1+k3x,ry1+k3y,s2,xsize,ysize,&v4x,&v4y);
    k4x = h*v4x;
    k4y = h*v4y;

    dx1 = (k1x+k4x+2.0*(k2x+k3x))/6.0;
    dy1 = (k1y+k4y+2.0*(k2y+k3y))/6.0;

    /* Do the second small RK step */

    rx2 = rx1 + dx1;
    ry2 = ry1 + dy1;

    cart_velocity(rx2,ry2,s2,xsize,ysize,&v1x,&v1y);
    k1x = h*v1x;
    k1y = h*v1y;
    cart_velocity(rx2+0.5*k1x,ry2+0.5*k1y,s3,xsize,ysize,&v2x,&v2y);
    k2x = h*v2x;
    k2y = h*v2y;
    cart_velocity(rx2+0.5*k2x,ry2+0.5*k2y,s3,xsize,ysize,&v3x,&v3y);
    k3x = h*v3x;
    k3y = h*v3y;
    cart_velocity(rx2+k3x,ry2+k3y,s4,xsize,ysize,&v4x,&v4y);
    k4x = h*v4x;
    k4y = h*v4y;

    dx2 = (k1x+k4x+2.0*(k2x+k3x))/6.0;
    dy2 = (k1y+k4y+2.0*(k2y+k3y))/6.0;

    /* Calculate the (squared) error */

    ex = (dx1+dx2-dx12)/15;
    ey = (dy1+dy2-dy12)/15;
    esq = ex*ex + ey*ey;
    if (esq>esqmax) esqmax = esq;

    /* Update the position of the vertex using the more accurate (two small
     * steps) result, and deal with the boundary conditions.  This code
     * does 5th-order "local extrapolation" (which just means taking
     * the estimate of the 5th-order term above and adding it to our
     * 4th-order result get a result accurate to the next highest order) */

    dxtotal = dx1 + dx2 + ex;   // Last term is local extrapolation
    dytotal = dy1 + dy2 + ey;   // Last term is local extrapolation
    drsq = dxtotal*dxtotal + dytotal*dytotal;
    if (drsq>drsqmax) drsqmax = drsq;

    rx3 = rx1 + dxtotal;
    ry3 = ry1 + dytotal;

    if (rx3<0) rx3 = 0;
    else if (rx3>xsize) rx3 = xsize;
    if (ry3<0) ry3 = 0;
    else if (ry3>ysize) ry3 = ysize;

    pointx[p] = rx3;
    pointy[p] = ry3;

  }

  *errorp = sqrt(esqmax);
  *drp =  sqrt(drsqmax);
  *spp = s4;
}
/* Function to do the transformation of the given set of points
 * to the cartogram */
void cart_makecart(double *pointx, double *pointy, int npoints,
				   int xsize, int ysize, double blur)
{
	int i;
	int s,sp;
	int step;
	int done;
	double t,h;
	double error,dr;
	double desiredratio;
	
	/* Calculate the initial density and velocity for snapshot zero */
	
	cart_density(0.0,0,xsize,ysize);
	cart_vgrid(0,xsize,ysize);
	s = 0;
	
	/* Now integrate the points in the polygons */
	
	step = 0;
	t = 0.5*blur*blur;
	h = INITH;
	
	do {
		
		/* Do a combined (triple) integration step */
		
		cart_twosteps(pointx,pointy,npoints,t,h,s,xsize,ysize,&error,&dr,&sp);
		
		/* Increase the time by 2h and rotate snapshots */
		
		t += 2.0*h;
		step += 2;
		s = sp;
		
		/* Adjust the time-step.  Factor of 2 arises because the target for
		 * the two-step process is twice the target for an individual step */
		
		desiredratio = pow(2*TARGETERROR/error,0.2);
		if (desiredratio>MAXRATIO) h *= MAXRATIO;
		else h *= desiredratio;
		
		done = cart_complete(t);
#ifdef PERCENT
		fprintf(stdout,"%i\n",done);
#endif
#ifndef NOPROGRESS
		fprintf(stderr,"  %3i%%  |",done);
		for (i=0; i<done/2; i++) fprintf(stderr,"=");
		for (i=done/2; i<50; i++) fprintf(stderr," ");
		fprintf(stderr,"|\r");
#endif
		
		/* If no point moved then we are finished */
		
	} while (dr>0.0);
	
#ifdef PERCENT
	fprintf(stdout,"\n");
#endif
#ifndef NOPROGRESS
	fprintf(stderr,"  100%%  |==================================================|\n");
#endif
}