Exemple #1
0
void compute_new_heading(int which)
{
  int i, j, k, numcent = 0;
  double xa, ya, xb, yb, xc, yc, xd, yd, xt, yt;
  double mindist, mx = 0, my = 0, d;
  double cosangle, cosvangle, costemp;
  double xtemp, ytemp, maxr, u, v;

  /* This is the maximum distance in which any rule is activated. */
  maxr = MAX(rviso, MAX(rcopy, MAX(rcent, rvoid)));

  /* These two values are used to see if a boid can "see" another
   * boid in various ways.
   */
  cosangle = cos(angle / 2);
  cosvangle = cos(vangle / 2);

  /* These are the accumulated change vectors for the four rules. */
  xa = ya = xb = yb = xc = yc = xd = yd = 0;

  /* For every boid... */
  for(i = 0; i < num; i++) {

    /* Don't include self for computing new heading. */
    if(i == which) continue;

    /* Since we want boids to "see" each other around the borders of
     * the screen, we need to check if a boid on the left edge is
     * actually "close" to a boid on the right edge, etc.  We do this
     * by searching over nine relative displacements of boid(i) and
     * pick the one that is closest to boid(which).  These coordinates
     * are then used for all remaining calculations.
     */
    mindist = 10e10;
    for(j = -width; j <= width; j += width)
      for(k = -height; k <= height; k += height) {
        d = DIST(xp[i] + j, yp[i] + k, xp[which], yp[which]);
        if(d < mindist) {
          mindist = d;
          mx = xp[i] + j;
          my = yp[i] + k;
        }
      }

    /* If that distance is farther than any of the rule radii,
     * then skip.
     */
    if(mindist > maxr) continue;

    /* Make a vector from boid(which) to boid(i). */
    xtemp = mx - xp[which]; ytemp = my - yp[which];
    
    /* Calculate the cosine of the velocity vector of boid(which)
     * and the vector from boid(which) to boid(i).
     */
    costemp = DOT(xv[which], yv[which], xtemp, ytemp) /
      (LEN(xv[which], yv[which]) * LEN(xtemp, ytemp));

    /* If this cosine is less than the cosine of one half
     * of the boid's eyesight, i.e., boid(which) cannot see
     * boid(i), then skip.
     */
    if(costemp < cosangle) continue;

    /* If the distance between the two boids is within the radius
     * of the centering rule, but outside of the radius of the
     * avoidance rule, then attempt to center in on boid(i).
     */
    if(mindist <= rcent && mindist > rvoid) {
      xa += mx - xp[which];
      ya += my - yp[which]; 
      numcent++;
    }

    /* If we are close enough to copy, but far enough to avoid,
     * then copy boid(i)'s velocity.
     */
    if(mindist <= rcopy && mindist > rvoid) {
      xb += xv[i];
      yb += yv[i];
    }

    /* If we are within collision range, then try to avoid boid(i). */
    if(mindist <= rvoid) {

      /* Calculate the vector which moves boid(which) away from boid(i). */
      xtemp = xp[which] - mx;
      ytemp = yp[which] - my;

      /* Make the length of the avoidance vector inversely proportional
       * to the distance between the two boids.
       */
      d = 1 / LEN(xtemp, ytemp);
      xtemp *= d; ytemp *= d; 
      xc += xtemp; yc += ytemp;
    }

    /* If boid(i) is within rviso distance and the angle between this boid's
     * velocity vector and the boid(i)'s position relative to this boid is
     * less than vangle, then try to move so that vision is restored.
     */
    if(mindist <= rviso && cosvangle < costemp) {

      /* Calculate the vector which moves boid(which) away from boid(i). */
      xtemp = xp[which] - mx;
      ytemp = yp[which] - my;

      /* Calculate another vector that is orthogonal to the previous,
       * But try to make it in the same general direction of boid(which)'s
       * direction of movement.
       */
      u = v = 0;
      if(xtemp != 0 && ytemp != 0) {
        u = sqrt(SQR(ytemp / xtemp) / (1 + SQR(ytemp / xtemp)));
        v = -xtemp * u / ytemp;
      }
      else if(xtemp != 0)
        u = 1;
      else if(ytemp != 0)
        v = 1;
      if((xv[which] * u + yv[which] * v) < 0) {
        u = -u; v = -v;
      }

      /* Add the vector that moves away from boid(i). */
      u = xp[which] - mx + u;
      v = yp[which] - my + v;

      /* Make this vector's length inversely proportional to the
       * distance between the two boids.
       */
      d = LEN(xtemp, ytemp);
      if(d != 0) {
        u /= d; v /= d; 
      }
      xd += u; yd += v;
    }
  }

  /* Avoid centering on only one other boid;
   * it makes you look aggressive!
   */
  if(numcent < 2)
    xa = ya = 0;
  
  /* Normalize all big vectors. */
  if(LEN(xa, ya) > 1.0) norm(&xa, &ya);
  if(LEN(xb, yb) > 1.0) norm(&xb, &yb);
  if(LEN(xc, yc) > 1.0) norm(&xc, &yc);
  if(LEN(xd, yd) > 1.0) norm(&xd, &yd);

  /* Compute the composite trajectory based on all of the rules. */
  xt = xa * wcent + xb * wcopy + xc * wvoid + xd * wviso;
  yt = ya * wcent + yb * wcopy + yc * wvoid + yd * wviso;

  /* Optionally add some noise. */
  if(wrand > 0) {
    xt += random_range(-1, 1) * wrand;
    yt += random_range(-1, 1) * wrand;
  }

  /* Update the velocity and renormalize if it is too small. */
  xnv[which] = xv[which] * ddt + xt * (1 - ddt);
  ynv[which] = yv[which] * ddt + yt * (1 - ddt);
  d = LEN(xnv[which], ynv[which]);
  if(d < minv) {
    xnv[which] *= minv / d;
    ynv[which] *= minv / d;
  }    
}
int
main(int argc, char *argv[]) {
  char *me, *outS;
  hestOpt *hopt;
  hestParm *hparm;
  airArray *mop;

  char *err;
  Nrrd *nin, *nhist;
  double vmin, vmax, rmax, val, cent[2], rad;
  int bins[2], sx, sy, xi, yi, ridx, hidx, rbins, hbins;
  NrrdRange *range;
  double (*lup)(const void *v, size_t I), *hist;
  
  me = argv[0];
  mop = airMopNew();
  hparm = hestParmNew();
  hopt = NULL;
  airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways);
  hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL,
             "input image", NULL, NULL, nrrdHestNrrd);
  hestOptAdd(&hopt, "b", "rbins hbins", airTypeInt, 2, 2, bins, NULL,
             "# of histogram bins: radial and value");
  hestOptAdd(&hopt, "min", "value", airTypeDouble, 1, 1, &vmin, "nan",
             "Value at low end of histogram. Defaults to lowest value "
             "found in input nrrd.");
  hestOptAdd(&hopt, "max", "value", airTypeDouble, 1, 1, &vmax, "nan",
             "Value at high end of histogram. Defaults to highest value "
             "found in input nrrd.");
  hestOptAdd(&hopt, "rmax", "max radius", airTypeDouble, 1, 1, &rmax, "nan",
             "largest radius to include in histogram");
  hestOptAdd(&hopt, "c", "center x, y", airTypeDouble, 2, 2, cent, NULL,
             "The center point around which to build radial histogram");
  hestOptAdd(&hopt, "o", "filename", airTypeString, 1, 1, &outS, "-",
             "file to write histogram to");
  hestParseOrDie(hopt, argc-1, argv+1, hparm,
                 me, histradInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE);
  airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
  airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

  if (2 != nin->dim) {
    fprintf(stderr, "%s: need 2-D input (not %d-D)\n", me, nin->dim);
    airMopError(mop); return 1;
  }

  rbins = bins[0];
  hbins = bins[1];
  nhist = nrrdNew();
  airMopAdd(mop, nhist, (airMopper)nrrdNuke, airMopAlways);
  if (nrrdMaybeAlloc_va(nhist, nrrdTypeDouble, 2,
                        AIR_CAST(size_t, rbins),
                        AIR_CAST(size_t, hbins))) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: couldn't allocate histogram:\n%s", me, err);
    airMopError(mop); return 1;
  }

  if (!( AIR_EXISTS(vmin) && AIR_EXISTS(vmax) )) {
    range = nrrdRangeNewSet(nin, nrrdStateBlind8BitRange);
    airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
    vmin = AIR_EXISTS(vmin) ? vmin : range->min;
    vmax = AIR_EXISTS(vmax) ? vmax : range->max;
  }

#define DIST(x0, y0, x1, y1) (sqrt((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1)))

  sx = nin->axis[0].size;
  sy = nin->axis[1].size;
  if (!AIR_EXISTS(rmax)) {
    rmax = 0;
    rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], 0, 0));
    rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], sx-1, 0));
    rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], 0, sy-1));
    rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], sx-1, sy-1));
  }
  
  lup = nrrdDLookup[nin->type];
  hist = (double*)(nhist->data);
  for (xi=0; xi<sx; xi++) {
    for (yi=0; yi<sy; yi++) {
      rad = DIST(cent[0], cent[1], xi, yi);
      if (!AIR_IN_OP(0, rad, rmax)) {
        continue;
      }
      val = lup(nin->data, xi + sx*yi);
      if (!AIR_IN_OP(vmin, val, vmax)) {
        continue;
      }
      ridx = airIndex(0, rad, rmax, rbins);
      hidx = airIndex(vmin, val, vmax, hbins);
      hist[ridx + rbins*hidx] += 1;
    }
  }
  
  nhist->axis[0].min = 0;
  nhist->axis[0].max = rmax;
  nhist->axis[1].min = vmin;
  nhist->axis[1].max = vmax;
  if (nrrdSave(outS, nhist, NULL)) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: couldn't save output:\n%s", me, err);
    airMopError(mop); return 1;
  }

  airMopOkay(mop);
  exit(0);
}
Exemple #3
0
void src3d(float *time0, float *slow0, int nz, int nx, int ny, float h, float ox, float oy, float oz, int *pxs, int *pys, int *pzs, int *cube)
{
	int
		srctype=1,	/* if 1, source is a point;
						2, source is on the walls of the data volume;
						3, source on wall, time field known; */
		srcwall,	/* if 1, source on x=0 wall, if 2, on x=nx-1 wall
						if 3, source on y=0 wall, if 4, on y=ny-1 wall
						if 5, source on z=0 wall, if 6, on z=nz-1 wall */
		xs,			/* shot x position (in grid points) */
		ys,			/* shot y position */
		zs,			/* shot depth */
		xx, yy, zz,	/* Used to loop around xs, ys, zs coordinates	*/
		ii, i, j, k, 
		wfint, ofint,
		nxy, nyz, nxz, nxyz, nwall,
		NCUBE=2;
	float
		fxs,	/* shot position in X (in real units)*/
		fys,	/* shot position in Y (in real units)*/
		fzs,	/* shot position in Z (in real units)*/
		*wall,
		/* maximum offset (real units) to compute */
		/* used in linear velocity gradient cube source */
		rx, ry, rz, dvz, dv, v0,
		rzc, rxyc, rz1, rxy1, rho, theta1, theta2,
		xsrc1, ysrc1, zsrc1;
	char
		*oldtfile,	/* file through which old travel times are input */
		*wallfile;   /* file containing input wall values of traveltimes */


	if(!getparint("NCUBE",&NCUBE)) NCUBE=2;

	if(!getparint("srctype",&srctype)) srctype=1;
	if(srctype==1) {
		if(!getparfloat("xsrc1",&xsrc1)) verr("xsrc1 not given");
		if(!getparfloat("ysrc1",&ysrc1)) verr("ysrc1 not given");
		if(!getparfloat("zsrc1",&zsrc1)) verr("zsrc1 not given");
		fxs = (xsrc1-ox)/h;
		fys = (ysrc1-oy)/h;
		fzs = (zsrc1-oz)/h;
		xs = (int)(fxs + 0.5);
		ys = (int)(fys + 0.5);
		zs = (int)(fzs + 0.5);
		if(xs<2 || ys<2 || zs<2 || xs>nx-3 || ys>ny-3 || zs>nz-3){
			vwarn("Source near an edge, beware of traveltime errors");
			vwarn("for raypaths that travel parallel to edge ");
			vwarn("while wavefronts are strongly curved, (JV, 8/17/88)\n");
		}
		*pxs = xs; *pys = ys, *pzs = zs, *cube = NCUBE;
	}
	else if (srctype==2)  {
		if (!getparint("srcwall",&srcwall)) verr("srcwall not given");
		if (!getparstring("wallfile",&wallfile)) verr("wallfile not given");
		if((wfint=open(wallfile,O_RDONLY,0664))<=1) {
			fprintf(stderr,"cannot open %s\n",wallfile);
			exit(-1);
		}
	}
	else if (srctype==3)  {
		if (!getparint("srcwall",&srcwall)) verr("srcwall not given");
		if (!getparstring("oldtfile",&oldtfile)) verr("oldtfile not given");
		if((ofint=open(oldtfile,O_RDONLY,0664))<=1) {
			fprintf(stderr,"cannot open %s\n",oldtfile);
			exit(-1);
		}
	}
	else  {
		verr("ERROR: incorrect value of srctype");
	}

	nxy = nx * ny;
	nyz = ny * nz;
	nxz = nx * nz;
	nxyz = nx * ny * nz;


	/* SET TIMES TO DUMMY VALUE */
	for(i=0;i<nxyz;i++) time0[i] = 1.0e10;

	if (srctype == 1) {			/*  VIDALE'S POINT SOURCE */
		/* FILL IN CUBE AROUND SOURCE POINT */
		/* HOLE'S NEW LINEAR VELOCITY GRADIENT CUBE (APRIL 1991)*/
		v0 = h/s0(xs,ys,zs);
		for (xx = xs-NCUBE; xx <= xs+NCUBE; xx++) {
			if (xx < 0 || xx >= nx)	continue; 
			for (yy = ys-NCUBE; yy <= ys+NCUBE; yy++) {
				if (yy < 0 || yy >= ny)	continue; 
				for (zz = zs-NCUBE; zz <= zs+NCUBE; zz++) {
					if (zz < 0 || zz >= nz)	continue; 
					if (zz == zs)
					  dvz = 1/s0(xx,yy,zz+1)-1/s0(xs,ys,zs);
					else
					  dvz = (1/s0(xx,yy,zz)-1/s0(xs,ys,zs))/(zz-zs);
					dv = fabs(dvz);
					if (dv == 0.)  {
					  t0(xx,yy,zz) = s0(xs,ys,zs)*DIST(fxs,fys,fzs,xx,yy,zz);
					  continue;
					}
					rzc = -v0/dv;
					rx = h*(xx - fxs);
					ry = h*(yy - fys);
					rz = h*(zz - fzs);
					rz1 = rz*dvz/dv;
					rxy1 = sqrt(rx*rx+ry*ry+rz*rz-rz1*rz1);
					if (rxy1<=h/1.e6)
					  t0(xx,yy,zz) = fabs(log((v0+dv*rz1)/v0)/dv);
					else {
					  rxyc = (rz1*rz1+rxy1*rxy1-2*rz1*rzc)/(2*rxy1);
					  rho = sqrt(rzc*rzc+rxyc*rxyc);
					  theta1 = asin(-rzc/rho);
					  /* can't handle asin(1.) ! */
					  if (fabs(rz1-rzc)>=rho)  rho=1.0000001*fabs(rz1-rzc);
					  theta2 = asin((rz1-rzc)/rho);
					  if (rxyc<0) theta1=M_PI-theta1;
					  if (rxyc<rxy1) theta2=M_PI-theta2;
					  t0(xx,yy,zz) = log(tan(theta2/2)/tan(theta1/2)) / dv;
				        }
				}
			}
		}
	}
	else if (srctype == 2) {		/*  HOLE'S EXTERNAL SOURCE */

		/* FILL IN WALLS' TIMES FROM EXTERNAL DATAFILE */
		read (wfint,wall,4*nwall);	/* READ X=0 WALL */
		if (wall[0]>-1.e-20) {
			ii = 0;
			for (k=0; k<nz; k++) {
				for (j=0; j<ny; j++) {
					t0(0,j,k) = wall[ii];
					ii++;
				}
			}
		}
		read (wfint,wall,4*nwall);	/* READ X=NX-1 WALL */
		if (wall[0]>-1.e-20) {
			ii = 0;
			for (k=0; k<nz; k++) {
				for (j=0; j<ny; j++) {
					t0(nx-1,j,k) = wall[ii];
					ii++;
				}
			}
		}
		read (wfint,wall,4*nwall);	/* READ Y=0 WALL */
		if (wall[0]>-1.e-20) {
			ii = 0;
			for (k=0; k<nz; k++) {
				for (i=0; i<nx; i++) {
					t0(i,0,k) = wall[ii];
					ii++;
				}
			}
		}
		read (wfint,wall,4*nwall);	/* READ Y=NY-1 WALL */
		if (wall[0]>-1.e-20) {
			ii = 0;
			for (k=0; k<nz; k++) {
				for (i=0; i<nx; i++) {
					t0(i,ny-1,k) = wall[ii];
					ii++;
				}
			}
		}
		read (wfint,wall,4*nwall);	/* READ Z=0 WALL */
		if (wall[0]>-1.e-20) {
			ii = 0;
			for (j=0; j<ny; j++) {
				for (i=0; i<nx; i++) {
					t0(i,j,0) = wall[ii];
					ii++;
				}
			}
		}
		read (wfint,wall,4*nwall);	/* READ Z=NZ-1 WALL */
		if (wall[0]>-1.e-20) {
			ii = 0;
			for (j=0; j<ny; j++) {
				for (i=0; i<nx; i++) {
					t0(i,j,nz-1) = wall[ii];
					ii++;
				}
			}
		}
	}
	else if (srctype == 3) {                /*  HOLE'S REDO OLD TIMES */
	        /* READ IN OLD TIME FILE */
	        if (srctype == 3)  read(ofint,time0,nxyz*4);
	}

	return;
}
Exemple #4
0
void
_pl_x_draw_elliptic_arc (R___(Plotter *_plotter) plPoint p0, plPoint p1, plPoint pc)
{
  double radius;
  double theta0, theta1;
  int startangle, anglerange;
  int x_orientation, y_orientation;
  int xorigin, yorigin;
  unsigned int squaresize_x, squaresize_y;

  /* axes flipped? (by default y-axis is, due to  X's flipped-y convention) */
  x_orientation = (_plotter->drawstate->transform.m[0] >= 0 ? 1 : -1);
  y_orientation = (_plotter->drawstate->transform.m[3] >= 0 ? 1 : -1);

  /* radius of circular arc in user frame is distance to p0, and also to p1 */
  radius = DIST(pc, p0);

  /* location of `origin' (upper left corner of bounding rect. on display)
     and width and height; X's flipped-y convention affects these values */
  xorigin = IROUND(XD(pc.x - x_orientation * radius, 
		      pc.y - y_orientation * radius));
  yorigin = IROUND(YD(pc.x - x_orientation * radius, 
		      pc.y - y_orientation * radius));
  squaresize_x = (unsigned int)IROUND(XDV(2 * x_orientation * radius, 0.0));
  squaresize_y = (unsigned int)IROUND(YDV(0.0, 2 * y_orientation * radius));

  theta0 = _xatan2 (-y_orientation * (p0.y - pc.y), 
		    x_orientation * (p0.x - pc.x)) / M_PI;
  theta1 = _xatan2 (-y_orientation * (p1.y - pc.y), 
		    x_orientation * (p1.x - pc.x)) / M_PI;
void calc_tidal_forces(struct halo_stash *h, double a1, double a2)
{
  int64_t i,j, num_halo_pos=0;
  float dt = (scale_to_years(a2) - scale_to_years(a1))/1.0e6; //In Myr
  float range, av_a = (a1+a2)/2.0;
  float inv_rs, r,m, dx, dy, dz, r3, acc;
  float rvir,nearest_range;
  struct fast3tree_results *nearest;
  struct tree_halo *h1, *h2;
  float acorr = 1; //pow(av_a, 0.7);
  float conv_const = av_a*av_a / h0 / h0 / h0;
  float vel_dt = dt * 1.02268944e-6 * h0 / av_a; //1 km/s to comoving Mpc/Myr/h
  struct tree_halo *halos = h->halos;
  float max_dist = box_size / 2.0;
  float mass_factor;

  gen_ff_cache();

  if (!tidal_tree) tidal_tree = fast3tree_init(0, NULL);

  hpos = check_realloc(hpos, sizeof(struct halo_pos)*h->num_halos, "Allocating tidal halo positions");
  nearest = fast3tree_results_init();
  vel_dt /= 2.0;
  for (i=0; i<h->num_halos; i++) {
    halos[i].tidal_force = 0;
    halos[i].tidal_id = -1;
    halos[i].pid = halos[i].upid = -1;
    halos[i].pid_vmax = halos[i].upid_vmax = 0;
    if (halos[i].flags & MERGER_FLUCTUATION_FLAG) continue;
    hpos[num_halo_pos].h = &(halos[i]);
    for (j=0; j<3; j++) {
      hpos[num_halo_pos].pos[j] = halos[i].pos[j] + vel_dt*halos[i].vel[j];
      IF_PERIODIC {
	if (hpos[num_halo_pos].pos[j] > box_size)
	  hpos[num_halo_pos].pos[j] -= box_size;
	else if (hpos[num_halo_pos].pos[j] < 0)
	  hpos[num_halo_pos].pos[j] += box_size;
      }
    }
    num_halo_pos++;
  }
  fast3tree_rebuild(tidal_tree, num_halo_pos, hpos);
  IF_PERIODIC _fast3tree_set_minmax(tidal_tree, 0, box_size);
  
  //Calculate accelerations
  for (i=0; i<num_halo_pos; i++) {
    h1 = hpos[i].h;
    range = halo_tidal_range(h1->mvir/h0, av_a)*h0; //In comoving Mpc/h
    rvir = h1->rvir / 1.0e3; //In comoving Mpc/h
    if (range > rvir) nearest_range = range;
    else nearest_range = rvir;
    IF_PERIODIC {
      if (nearest_range > max_dist) nearest_range = max_dist;
      fast3tree_find_sphere_periodic(tidal_tree, nearest, hpos[i].pos, nearest_range);
    } else {
      fast3tree_find_sphere(tidal_tree, nearest, hpos[i].pos, nearest_range);
    }

    inv_rs = 1000.0/h1->rs; //In comoving h/Mpc
    mass_factor = calculate_mass_factor(h1->mvir/h0, h1->rvir, h1->rs);
    for (j=0; j<nearest->num_points; j++) {
      //Calculate tidal forces
      h2 = nearest->points[j]->h;
      
#ifndef NO_PERIODIC
#define DIST(a,b) a = hpos[i].pos[b] - nearest->points[j]->pos[b];	\
      if (a > max_dist) a-=box_size;					\
      else if (a < -max_dist) a+=box_size;
#else
#define DIST(a,b) a = hpos[i].pos[b] - nearest->points[j]->pos[b];
#endif
      DIST(dx,0);
      DIST(dy,1);
      DIST(dz,2);
#undef DIST
      r = sqrtf(dx*dx + dy*dy + dz*dz); // in comoving Mpc/h

      //Including acorr slightly improves velocity results
      // as a function of redshift.
      m = mass_factor*ff_cached(r*inv_rs*acorr); //In Msun

      r3 = r * r * r * conv_const; //in (real Mpc)^3
      acc = r3 ? Gc*m/r3 : 0; //In km/s / Myr / (real Mpc)

      if (r < rvir && h1->vmax > h2->vmax) {
	if (h2->pid < 0) {
	  h2->pid = h2->upid = h1->id;
	  h2->pid_vmax = h2->upid_vmax = h1->vmax;
	}
	else {
	  if (h2->pid_vmax > h1->vmax) {
	    h2->pid = h1->id;
	    h2->pid_vmax = h1->vmax;
	  }
	  if (h2->upid_vmax < h1->vmax) {
	    h2->upid = h1->id;
	    h2->upid_vmax = h1->vmax;
	  }
	}
      }

      if ((acc > h2->tidal_force) && ((h2->mvir*MAJOR_MERGER) < h1->mvir)
	  && (!(h2->phantom))) {
	h2->tidal_force = acc;
	h2->tidal_id = h1->id;
      }
    }
  }
Exemple #6
0
 bool pose_dist_comp(geometry_msgs::Pose& p1, geometry_msgs::Pose& p2, geometry_msgs::Point& app_pt) {
     return DIST(p1.position.x, p1.position.y, app_pt.x, app_pt.y) < DIST(p2.position.x, p2.position.y, app_pt.x, app_pt.y);
 }
Exemple #7
0
void bullet_update(struct moag *m, int id)
{
    struct bullet *b = &m->bullets[id];

    if (!b->active)
        return;

    if (b->type == LADDER)
    {
        b->active--;
        b->obj.pos = VEC2_ADD(b->obj.pos, b->obj.vel);
        b->x = (int)b->obj.pos.x;
        b->y = (int)b->obj.pos.y;

        if (get_land_at(m, b->x, b->y) == 1)
        {
            explode(m, b->x, b->y + LADDER_LENGTH - b->active, 1, E_SAFE_EXPLODE);
            bullet_detonate(m, id);
        }
        return;
    }

    b->obj.pos = VEC2_ADD(b->obj.pos, b->obj.vel);
    b->obj.vel = VEC2_ADD(b->obj.vel, VEC2(0, GRAVITY));
    b->x = (int)b->obj.pos.x;
    b->y = (int)b->obj.pos.y;
    if (get_land_at(m, b->x, b->y))
    {
        bullet_detonate(m, id);
        return;
    }

    if (b->active > 1)
    {
        b->active--;
        return;
    }

    if (b->type == BOUNCER && b->active == 1)
        b->active = -BOUNCER_BOUNCES;
    if (b->type == TUNNELER && b->active == 1)
        b->active = -TUNNELER_TUNNELINGS;

    for (int i = 0; i < MAX_PLAYERS; i++)
    {
        if(DIST(m->players[i].tank.x, m->players[i].tank.y - 3,
                b->x, b->y) < 8.5)
        {
            bullet_detonate(m, id);
            return;
        }
    }

    if (m->crate.active && DIST(m->crate.x, m->crate.y - 4, b->x, b->y) < 5.5)
    {
        if (m->crate.type == TRIPLER) {
            float angle = -RAD2DEG(atan2(b->obj.vel.y, b->obj.vel.x));
            float speed = VEC2_MAG(b->obj.vel);
            fire_bullet_ang(m, b->type, b->x, b->y, angle - 20.0, speed);
            fire_bullet_ang(m, b->type, b->x, b->y, angle + 20.0, speed);
        } else if (m->crate.type == SHOTGUN) {
            bullet_detonate(m, id);
            float angle = -RAD2DEG(atan2(b->obj.vel.y, b->obj.vel.x));
            float speed = VEC2_MAG(b->obj.vel);
            int shots = SHOTGUN_PELLETS;
            for (int i = 0; i < shots; i++)
                fire_bullet_ang(m, m->crate.type, m->crate.x, m->crate.y - 4,
                        angle - (shots-1)*2 + i*4, speed*0.5);
        } else {
            bullet_detonate(m, id);
            fire_bullet(m, m->crate.type, m->crate.x, m->crate.y - 4,
                           m->crate.type != BOUNCER ? 0 :
                           b->obj.vel.x < 0 ? -0.2 :
                                               0.2, -0.2);
        }
        m->crate.active = false;
        return;
    }

    if (b->type == MIRV && b->obj.vel.y > 0)
    {
        bullet_detonate(m, id);
        return;
    }

    if (b->active)
        broadcast_bullet_chunk(m, MOVE, id);
}
Exemple #8
0
static void
rescale_layout_polarFocus(v_data * graph, int n,
	  double *x_coords, double *y_coords,
	  double x_focus, double y_focus, int interval, double distortion)
{
    // Polar distortion - auxiliary function
    int i;
    double *densities = NULL, *smoothed_densities = NULL;
    double *distances = N_NEW(n, double);
    double *orig_distances = N_NEW(n, double);
    int *ordering;
    double ratio;

    for (i = 0; i < n; i++) 
	{
		distances[i] = DIST(x_coords[i], y_coords[i], x_focus, y_focus);
    }
    cpvec(orig_distances, 0, n - 1, distances);

    ordering = N_NEW(n, int);
    for (i = 0; i < n; i++) 
	{
		ordering[i] = i;
    }
    quicksort_place(distances, ordering, 0, n - 1);

    densities = compute_densities(graph, n, x_coords, y_coords);
    smoothed_densities = smooth_vec(densities, ordering, n, interval, smoothed_densities);

    // rescale distances
    if (distortion < 1.01 && distortion > 0.99) 
	{
		for (i = 1; i < n; i++) 
		{
			distances[ordering[i]] =	distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
					      orig_distances[ordering
							     [i -
							      1]]) / smoothed_densities[ordering[i]];
		}
    } else 
	{
		double factor;
		// just to make milder behavior:
		if (distortion >= 0) 
		{
			factor = sqrt(distortion);
		} 
		else 
		{
			factor = -sqrt(-distortion);
		}
		for (i = 1; i < n; i++) 
		{
			distances[ordering[i]] =
				distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
					      orig_distances[ordering
							     [i -
							      1]]) /
			pow(smoothed_densities[ordering[i]], factor);
		}
    }

    // compute new coordinate:
    for (i = 0; i < n; i++) 
	{
		if (orig_distances[i] == 0) 
		{
			ratio = 0;
		} 
		else 
		{
			ratio = distances[i] / orig_distances[i];
		}
		x_coords[i] = x_focus + (x_coords[i] - x_focus) * ratio;
		y_coords[i] = y_focus + (y_coords[i] - y_focus) * ratio;
    }

    free(densities);
    free(smoothed_densities);
    free(distances);
    free(orig_distances);
    free(ordering);
}
Exemple #9
0
void
SimWingUpdate(tCar *car, int index, tSituation* s)
{
    tWing  *wing = &(car->wing[index]);
    tdble vt2 = car->DynGC.vel.x;
    tdble i_flow = 1.0;
    // rear wing should not get any flow.

    // compute angle of attack 
    // we don't  add ay anymore since DynGC.vel.x,z are now in the correct frame of reference (see car.cpp)
    tdble aoa = atan2(car->DynGC.vel.z, car->DynGC.vel.x); //+ car->DynGC.pos.ay;
    // The flow to the rear wing can get cut off at large negative
    // angles of attack.  (so it won't produce lift because it will be
    // completely shielded by the car's bottom)
    // The value -0.4 should depend on the positioning of the wing. 
    // we also make this be like that.
    if (index==1) {
        i_flow = PartialFlowSmooth (-0.4, aoa);
    } 
    // Flow to the wings gets cut off by other cars.
    tdble airSpeed = car->DynGC.vel.x;

    if (airSpeed > 10.0) {
	tdble yaw = car->DynGC.pos.az;
	tdble x = car->DynGC.pos.x + cos(yaw)*wing->staticPos.x;
	tdble y = car->DynGC.pos.y + sin(yaw)*wing->staticPos.x;
	tdble spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);

	int i;
	for (i = 0; i < s->_ncars; i++) {
	    if (i == car->carElt->index) {
		continue;
	    }
	    tdble tmpas = 1.00;
	    tCar* otherCar = &(SimCarTable[i]);
	    tdble otherYaw = otherCar->DynGC.pos.az;
	    tdble tmpsdpang = spdang - atan2(y - otherCar->DynGC.pos.y, x - otherCar->DynGC.pos.x);
	    NORM_PI_PI(tmpsdpang);
	    tdble dyaw = yaw - otherYaw;
	    NORM_PI_PI(dyaw);
	    if ((otherCar->DynGC.vel.x > 10.0) &&
		(fabs(dyaw) < 0.1396)) {
		if (fabs(tmpsdpang) > 2.9671) {	    /* 10 degrees */
		    /* behind another car - reduce overall airflow */
                    tdble factor = (fabs(tmpsdpang)-2.9671)/(M_PI-2.9671);
		    tmpas = 1.0 - factor*exp(- 2.0 * DIST(x, y, otherCar->DynGC.pos.x, otherCar->DynGC.pos.y) /
                                             (otherCar->aero.Cd * otherCar->DynGC.vel.x));
		    i_flow = i_flow * tmpas;
		} 
	    }
	}
    }
    //if (index==1) { -- thrown away so that we have different downforce
    // reduction for front and rear parts.
    if (1) {
        // downforce due to body and ground effect.
        tdble alpha = 0.0f;
        tdble vt2b = vt2 * (alpha+(1-alpha)*i_flow);
        vt2b = vt2b * vt2b;
        tdble hm = 1.5 * (car->wheel[0].rideHeight + car->wheel[1].rideHeight + car->wheel[2].rideHeight + car->wheel[3].rideHeight);
        hm = hm*hm;
        hm = hm*hm;
        hm = 1.0 + exp(-3.0*hm);
        car->aero.lift[index] = - car->aero.Clift[index] * vt2b * hm;
        //car->aero.lift[1] = - car->aero.Clift[1] * vt2b *  hm;
        //printf ("%f\n", car->aero.lift[0]+car->aero.lift[1]);
    }


    vt2=vt2*i_flow;
    vt2=vt2*vt2;
	
    aoa += wing->angle;
	
    // the sinus of the angle of attack
    tdble sinaoa = sin(aoa);
    tdble cosaoa = cos(aoa);


    if (car->DynGC.vel.x > 0.0f) {
        switch (car->options->aeroflow_model) {
        case SIMPLE:
            wing->forces.x = wing->Kx * vt2 * (1.0f + (tdble)car->dammage / 10000.0f) * sinaoa;
            wing->forces.z = wing->Kz * vt2 * sinaoa;
            break;
        case PLANAR:
            wing->forces.x = wing->Kx * vt2 * (1.0f + (tdble)car->dammage / 10000.0f) * sinaoa * sinaoa * sinaoa;
            wing->forces.z = wing->Kz * vt2 * sinaoa * sinaoa * cosaoa;
            break;
        case OPTIMAL:
            wing->forces.x = wing->Kx * vt2 * (1.0f + (tdble)car->dammage / 10000.0f) * (1.0f - cosaoa);
            wing->forces.x = wing->Kx * vt2 * (1.0f + (tdble)car->dammage / 10000.0f) * sinaoa;
            break;
	default:
            fprintf (stderr, "Unimplemented option %d for aeroflow model\n", car->options->aeroflow_model);
        }
    } else {
        wing->forces.x = wing->forces.z = 0.0f;
    }
}
Exemple #10
0
void Mutation::__mutateAddNode(Module *m, double probability, double max)
{
  if(m->e_size() == 0) return;
  if(Random::unit() >= probability) return;
  VLOG(50) << ">>>>> add node";
  LOG_MODULE;
  VLOG(50) << "    number of edges: " << m->e_size();
  VLOG(50) << "    will add one node";
  m->setModified(true);

  double probabilities[m->e_size()];
  double sum = 0;
  for(int i = 0; i < m->e_size(); i++)
  {
    double d = DIST(m->edge(i)->sourceNode()->position(),
                    m->edge(i)->destinationNode()->position());
    sum += d;
    probabilities[i] = d;
  }

  if(sum < 0.000001) return; // only self connections so far

  for(int i = 0; i < m->e_size(); i++) probabilities[i] /= sum;

  // if(VLOG_IS_ON(50))
  // {
    // cout << "probabilities:";
    // for(int i = 0; i < m->e_size(); i++) cout << " " << probabilities[i];
    // cout << endl;
  // }

  double p  = Random::unit();
  double s  = 0.0;
  int    ei = -1;

  for(int i = 0; i < m->e_size(); i++)
  {
    s += probabilities[i];
    if(p <= s)
    {
      ei = i;
      break;
    }
  }

  VLOG(50) << "    edge index into which a neuron will be inserted: " << ei;

  Node *n = new Node(NULL);

  Edge *e   = m->edge(ei);
  Node *src = e->sourceNode();
  Node *dst = e->destinationNode();

  P3D sp    = src->position();
  P3D dp    = dst->position();
  P3D np    = (sp + dp) * 0.5;

  stringstream oss;
  bool found = true;
  int newNodeIndex = -1;
  while(found == true)
  {
    newNodeIndex++;
    oss.str("");
    oss << "hidden " << newNodeIndex;
    found = m->nodeExists(oss.str());
  }
  VLOG(50) << "new node name: " << oss.str();
  n->setType("hidden");
  n->setPosition(np);
  n->setBias(Random::rand(-max, max));
  n->setLabel(oss.str());
  n->setTransferfunction("tanh");

  e->setSourceNode(n);
  m->addNode(n);
  Edge *ne = m->addEdge(src, n, 1.0);
  LOG_MODULE;

  VLOG(50) << "    node added with label " << n->label();
  VLOG(50) << "    adding edge from: " << src->label() << " " << n->label();
  VLOG(50) << "    source neuron's position " << src->position();
  VLOG(50) << "    destination neuron's position " << dst->position();
  VLOG(50) << "    new neuron's position " << n->position();
  VLOG(50) << "    new synapse goes from " << e->sourceNode()->label() << " -> "
           << e->destinationNode()->label() << " with " << e->weight();
  VLOG(50) << "    new synapse goes from " << ne->sourceNode()->label() << " -> "
           << ne->destinationNode()->label() << " with " << ne->weight();
  VLOG(50) << "<<<<< add node";
}
/* addEndpoint:
 * Add node to graph representing spline end point p inside obstruction obs_id.
 * For each side of obstruction, add edge from p to corresponding triangle.
 * The node id of the new node in the graph is v_id.
 * If p lies on the side of its node (sides != 0), we limit the triangles
 * to those within 45 degrees of each side of the natural direction of p.
 */
static void addEndpoint(router_t * rtr, pointf p, node_t* v, int v_id, int sides)
{
    int obs_id = ND_lim(v);
    int starti = rtr->obs[obs_id];
    int endi = rtr->obs[obs_id + 1];
    pointf* pts = rtr->ps;
    int i, t;
    double d;
    pointf vr, v0, v1;

    switch (sides) {
    case TOP :
	vr = add_pointf (p, north);
	v0 = add_pointf (p, northwest);
	v1 = add_pointf (p, northeast);
	break;
    case TOP|RIGHT :
	vr = add_pointf (p, northeast);
	v0 = add_pointf (p, north);
	v1 = add_pointf (p, east);
	break;
    case RIGHT :
	vr = add_pointf (p, east);
	v0 = add_pointf (p, northeast);
	v1 = add_pointf (p, southeast);
	break;
    case BOTTOM|RIGHT :
	vr = add_pointf (p, southeast);
	v0 = add_pointf (p, east);
	v1 = add_pointf (p, south);
	break;
    case BOTTOM :
	vr = add_pointf (p, south);
	v0 = add_pointf (p, southeast);
	v1 = add_pointf (p, southwest);
	break;
    case BOTTOM|LEFT :
	vr = add_pointf (p, southwest);
	v0 = add_pointf (p, south);
	v1 = add_pointf (p, west);
	break;
    case LEFT :
	vr = add_pointf (p, west);
	v0 = add_pointf (p, southwest);
	v1 = add_pointf (p, northwest);
	break;
    case TOP|LEFT :
	vr = add_pointf (p, northwest);
	v0 = add_pointf (p, west);
	v1 = add_pointf (p, north);
	break;
    case 0 :
	break;
    default :
	assert (0);
	break;
    }

    rtr->tg->nodes[v_id].ne = 0;
    rtr->tg->nodes[v_id].ctr = p;
    for (i = starti; i < endi; i++) {
	ipair seg;
	seg.i = i;
	if (i < endi - 1)
	    seg.j = i + 1;
	else
	    seg.j = starti;
	t = findMap(rtr->trimap, seg.i, seg.j);
	if (sides && !inCone (v0, p, v1, pts[seg.i]) && !inCone (v0, p, v1, pts[seg.j]) && !raySeg(p,vr,pts[seg.i],pts[seg.j]))
	    continue;
	d = DIST(p, (rtr->tg->nodes + t)->ctr);
	addTriEdge(rtr->tg, v_id, t, d, seg);
    }
}
Exemple #12
0
void Mutation::__mutateAddEdge(Module *m,
                               double probability,
                               double max,
                               double minDist)
{
  VLOG(50) << ">>>>> add edge";
  LOG_MODULE;
  CfgMutationEdge *dee = Data::instance()->specification()->mutation()->edge();

  double probabilities[m->n_size()][m->n_size()];
  double d   =  0.0;

  for(int s_index = 0; s_index < m->n_size(); s_index++)
  {
    for(int d_index = 0; d_index < m->n_size(); d_index++)
    {
      probabilities[s_index][d_index] = 0.0;
    }
  }

  for(int s_index = 0; s_index < m->n_size(); s_index++)
  {
    Node *src_node = m->node(s_index);
    if(src_node->isInactive()) continue;
    if(src_node->isSource())
    {
      for(int d_index = 0; d_index < m->n_size(); d_index++)
      {
        Node *dst_node = m->node(d_index);
        if(dst_node->isInactive()) continue;
        // if(src_node->type() == TAG_CONNECTOR && dst_node->type() == TAG_CONNECTOR)
        // {
        // continue;
        // }
        if(dst_node->isDestination())
        {
          if(dst_node->contains(src_node) == false)
          {
            // USE FIXED PROBABILITY FOR ALL EDGES
            d = MAX(minDist, DIST(src_node->position(), dst_node->position()));
            if(d < MIN_DIST) d = 0;
            // probabilities[s_index][d_index] = exp(-d);
            if(dee->mode() == EDGE_ADD_MODE_UNIFORM)
            {
              probabilities[s_index][d_index] = 1.0;
            }
            else
            {
              probabilities[s_index][d_index] = 1.0/d;
            }

            VLOG(50) << "    edge from "
              << src_node->label() << " to "
              << dst_node->label() << " does not exist. setting distance to " << d;
            // probabilities[s_index][d_index] = 1.0;
          }
        }
      }
    }
  }

  double pmax =  0.0;
  if(dee->mode() == EDGE_ADD_MODE_DISTANCE)
  {
    for(int s_index = 0; s_index < m->n_size(); s_index++)
    {
      for(int d_index = 0; d_index < m->n_size(); d_index++)
      {
        if(pmax < probabilities[s_index][d_index]) pmax = probabilities[s_index][d_index];
      }
    }
  }

  if(pmax > 0.0)
  {
    for(int s_index = 0; s_index < m->n_size(); s_index++)
    {
      for(int d_index = 0; d_index < m->n_size(); d_index++)
      {
        // cout << probabilities[s_index][d_index] << " -> ";
        probabilities[s_index][d_index] = probabilities[s_index][d_index] / pmax;
        // cout << probabilities[s_index][d_index] << endl;
      }
    }
  }

  if(VLOG_IS_ON(50))
  {
    stringstream sst;
    sst << "    probabilities " << m->n_size() << "x" << m->n_size();
    sst.precision(3);
    sst.setf(ios::fixed,ios::floatfield);
    sst << "[ ";
    for(int s_index = 0; s_index < m->n_size(); s_index++)
    {
      sst << " [ " << probabilities[s_index][0];
      for(int d_index = 0; d_index < m->n_size(); d_index++)
      {
        sst << ", " << probabilities[s_index][d_index];
      }
      sst << " ]";
    }
    sst << " ]";
    VLOG(50) << sst.str();
  }

  // double p  = Random::unit();
  // VLOG(50) << "    p = " << p;
  for(int s_index = 0; s_index < m->n_size(); s_index++)
  {
    for(int d_index = 0; d_index < m->n_size(); d_index++)
    {
      double p = probabilities[s_index][d_index] * probability;
      if(Random::unit() <= p)
      {
        Node *src = m->node(s_index);
        Node *dst = m->node(d_index);
        VLOG(50) << "    adding edge from " << src->label() << " -> " << dst->label();
        VLOG(50) << "    before number of edges: " << m->e_size();
        Edge *e   = m->addEdge(src, dst, Random::rand(-max, max));
        VLOG(50) << "    adding edge from "
          << m->node(s_index)->label() << " to "
          << m->node(d_index)->label() << " with "
          << e->weight();
        VLOG(50) << "    after number of edges: " << m->e_size();
        LOG_MODULE;
        VLOG(50) << "<<<<< add edge";
        m->setModified(true);
      }
    }
  }

  LOG_MODULE;
  VLOG(50) << "<<<<< add edge";
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *xgrad, *ygrad, *boundary, *dist;
    double dxp, dxm, dyp, dym, xns, yns, nrm;
    int m, n, i, j, nn;
    
    /* Check number of outputs */
    if (nlhs < 2)
        mexErrMsgTxt("At least 2 output argument needed.");
    else if (nlhs > 2)
        mexErrMsgTxt("At most 2 output argument needed.");
    
    /* Get inputs */
    if (nrhs < 2)
        mexErrMsgTxt("At least 2 input argument needed.");
    else if (nrhs > 2)
        mexErrMsgTxt("At most 2 input argument used.");
    
    
    
    /* Get boundary */
    if (!mxIsDouble(prhs[0]) || mxIsClass(prhs[0], "sparse"))
        mexErrMsgTxt("Boundary field needs to be a full double precision matrix.");
    
    boundary = mxGetPr(prhs[0]);
    m = mxGetM(prhs[0]);
    n = mxGetN(prhs[0]);
    
    /* Get distance field */
    if (!mxIsDouble(prhs[1]) || mxIsClass(prhs[1], "sparse") || mxGetM(prhs[1]) != m || mxGetN(prhs[1]) != n)
        mexErrMsgTxt("Distance field needs to be a full double precision matrix with same dimension as the boundary.");
    
    dist = mxGetPr(prhs[1]);
    m = mxGetM(prhs[1]);
    n = mxGetN(prhs[1]);
    
    /* create and init output (gradient) matrices */
    plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL);
    plhs[1] = mxCreateDoubleMatrix(m, n, mxREAL);
    xgrad = mxGetPr(plhs[0]);
    ygrad = mxGetPr(plhs[1]);
    
    
    
    for (j = 0; j < n; ++j)
        for (i = 0; i < m; ++i)
            if (INTERIOR(i,j))
            {
                if (i > 0)
                    dxm = INTERIOR(i-1,j) ? DIST(i-1,j) : DIST(i,j);
                else
                    dxm = DIST(i,j);
                
                if (i < m-1)
                    dxp = INTERIOR(i+1,j) ? DIST(i+1,j) : DIST(i,j);
                else
                    dxp = DIST(i,j);
                
                if (j > 0)
                    dym = INTERIOR(i,j-1) ? DIST(i,j-1) : DIST(i,j);
                else
                    dym = DIST(i,j);
                
                if (j < n-1)
                    dyp = INTERIOR(i,j+1) ? DIST(i,j+1) : DIST(i,j);
                else
                    dyp = DIST(i,j);
                
                XGRAD(i, j) = (dxp - dxm) / 2.0;
                YGRAD(i, j) = (dyp - dym) / 2.0;
                nrm = sqrt(XGRAD(i, j)*XGRAD(i, j) + YGRAD(i, j)*YGRAD(i, j));
                if (nrm > 1e-12)
                {
                    XGRAD(i, j) /= nrm;
                    YGRAD(i, j) /= nrm;
                }
            }
            else
            {
                XGRAD(i, j) = 0.0;
                YGRAD(i, j) = 0.0;
            }
    
    for (j = 0; j < n; ++j)
        for (i = 0; i < m; ++i)
            if (!INTERIOR(i, j))
            {
                xns = 0.0;
                yns = 0.0;
                nn = 0;
                if (i > 0 && INTERIOR(i-1,j))
                {
                    xns += XGRAD(i-1,j);
                    yns += YGRAD(i-1,j);
                    ++nn;
                }
                if (i < m-1 && INTERIOR(i+1,j))
                {
                    xns += XGRAD(i+1,j);
                    yns += YGRAD(i+1,j);
                    ++nn;
                }
                if (j > 0 && INTERIOR(i,j-1))
                {
                    xns += XGRAD(i,j-1);
                    yns += YGRAD(i,j-1);
                    ++nn;
                }
                if (j < n-1 && INTERIOR(i,j+1))
                {
                    xns += XGRAD(i,j+1);
                    yns += YGRAD(i,j+1);
                    ++nn;
                }
                
                if (nn > 0)
                {
                    XGRAD(i, j) = xns / nn;
                    YGRAD(i, j) = yns / nn;
                }
            }
}
Exemple #14
0
static void
RemoveCar(tCar *car, tSituation *s)
{
	int i;
	tCarElt *carElt;
	tTrkLocPos trkPos;
	int trkFlag;
	tdble travelTime;
	tdble dang;

	static tdble PULL_Z_OFFSET = 3.0;
	static tdble PULL_SPD = 0.5;

	carElt = car->carElt;

	if (carElt->_state & RM_CAR_STATE_PULLUP) {
		carElt->_pos_Z += car->restPos.vel.z * SimDeltaTime;
		carElt->_yaw += car->restPos.vel.az * SimDeltaTime;
		carElt->_roll += car->restPos.vel.ax * SimDeltaTime;
		carElt->_pitch += car->restPos.vel.ay * SimDeltaTime;
		sgMakeCoordMat4(carElt->pub.posMat, carElt->_pos_X, carElt->_pos_Y, carElt->_pos_Z - carElt->_statGC_z,
			(float) RAD2DEG(carElt->_yaw), (float) RAD2DEG(carElt->_roll), (float) RAD2DEG(carElt->_pitch));

		if (carElt->_pos_Z > (car->restPos.pos.z + PULL_Z_OFFSET)) {
			carElt->_state &= ~RM_CAR_STATE_PULLUP;
			carElt->_state |= RM_CAR_STATE_PULLSIDE;

			// Moved pullside velocity computation down due to floating point error accumulation.
		}
		return;
	}


	if (carElt->_state & RM_CAR_STATE_PULLSIDE) {
		// Recompute speed to avoid missing the parking point due to error accumulation (the pos might be
		// in the 0-10000 range, depending on the track and vel*dt is around 0-0.001, so basically all
		// but the most significant digits are lost under bad conditions, happens e.g on e-track-4).
		// Should not lead to a division by zero because the pullside process stops if the car is within
		// [0.5, 0.5]. Do not move it back.
		travelTime = DIST(car->restPos.pos.x, car->restPos.pos.y, carElt->_pos_X, carElt->_pos_Y) / PULL_SPD;
		car->restPos.vel.x = (car->restPos.pos.x - carElt->_pos_X) / travelTime;
		car->restPos.vel.y = (car->restPos.pos.y - carElt->_pos_Y) / travelTime;

		carElt->_pos_X += car->restPos.vel.x * SimDeltaTime;
		carElt->_pos_Y += car->restPos.vel.y * SimDeltaTime;
		sgMakeCoordMat4(carElt->pub.posMat, carElt->_pos_X, carElt->_pos_Y, carElt->_pos_Z - carElt->_statGC_z,
			(float) RAD2DEG(carElt->_yaw), (float) RAD2DEG(carElt->_roll), (float) RAD2DEG(carElt->_pitch));

		if ((fabs(car->restPos.pos.x - carElt->_pos_X) < 0.5) && (fabs(car->restPos.pos.y - carElt->_pos_Y) < 0.5)) {
			carElt->_state &= ~RM_CAR_STATE_PULLSIDE;
			carElt->_state |= RM_CAR_STATE_PULLDN;
		}
		return;
	}


	if (carElt->_state & RM_CAR_STATE_PULLDN) {
		carElt->_pos_Z -= car->restPos.vel.z * SimDeltaTime;
		sgMakeCoordMat4(carElt->pub.posMat, carElt->_pos_X, carElt->_pos_Y, carElt->_pos_Z - carElt->_statGC_z,
			(float) RAD2DEG(carElt->_yaw), (float) RAD2DEG(carElt->_roll), (float) RAD2DEG(carElt->_pitch));

		if (carElt->_pos_Z < car->restPos.pos.z) {
			carElt->_state &= ~RM_CAR_STATE_PULLDN;
			carElt->_state |= RM_CAR_STATE_OUT;
		}
		return;
	}


	if (carElt->_state & (RM_CAR_STATE_NO_SIMU & ~RM_CAR_STATE_PIT)) {
		return;
	}

	if (carElt->_state & RM_CAR_STATE_PIT) {
		if ((s->_maxDammage) && (car->dammage > s->_maxDammage)) {
			// Broken during pit stop.
			carElt->_state &= ~RM_CAR_STATE_PIT;
			carElt->_pit->pitCarIndex = TR_PIT_STATE_FREE;
		} else {
			return;
		}
	}

	if ((s->_maxDammage) && (car->dammage > s->_maxDammage)) {
		carElt->_state |= RM_CAR_STATE_BROKEN;
	} else {
		carElt->_state |= RM_CAR_STATE_OUTOFGAS;
	}

	carElt->_gear = car->transmission.gearbox.gear = 0;
	carElt->_enginerpm = car->engine.rads = 0;

	if (!(carElt->_state & RM_CAR_STATE_DNF)) {
		if (fabs(carElt->_speed_x) > 1.0) {
			return;
		}
	}

	carElt->_state |= RM_CAR_STATE_PULLUP;
	// RM_CAR_STATE_NO_SIMU evaluates to > 0 from here, so we remove the car from the
	// collision detection.
	SimCollideRemoveCar(car, s->_ncars);

	carElt->priv.collision = car->collision = 0;
	for(i = 0; i < 4; i++) {
		carElt->_skid[i] = 0;
		carElt->_wheelSpinVel(i) = 0;
		carElt->_brakeTemp(i) = 0;
	}

	carElt->pub.DynGC = car->DynGC;
	carElt->_speed_x = 0;

	// Compute the target zone for the wrecked car.
	trkPos = car->trkPos;
	if (trkPos.toRight >  trkPos.seg->width / 2.0) {
		while (trkPos.seg->lside != 0) {
			trkPos.seg = trkPos.seg->lside;
		}
		trkPos.toLeft = -3.0;
		trkFlag = TR_TOLEFT;
	} else {
		while (trkPos.seg->rside != 0) {
			trkPos.seg = trkPos.seg->rside;
		}
		trkPos.toRight = -3.0;
		trkFlag = TR_TORIGHT;
	}

	trkPos.type = TR_LPOS_SEGMENT;
	RtTrackLocal2Global(&trkPos, &(car->restPos.pos.x), &(car->restPos.pos.y), trkFlag);
	car->restPos.pos.z = RtTrackHeightL(&trkPos) + carElt->_statGC_z;
	car->restPos.pos.az = RtTrackSideTgAngleL(&trkPos);
	car->restPos.pos.ax = 0;
	car->restPos.pos.ay = 0;

	car->restPos.vel.z = PULL_SPD;
	travelTime = (car->restPos.pos.z + PULL_Z_OFFSET - carElt->_pos_Z) / car->restPos.vel.z;
	dang = car->restPos.pos.az - carElt->_yaw;
	FLOAT_NORM_PI_PI(dang);
	car->restPos.vel.az = dang / travelTime;
	dang = car->restPos.pos.ax - carElt->_roll;
	FLOAT_NORM_PI_PI(dang);
	car->restPos.vel.ax = dang / travelTime;
	dang = car->restPos.pos.ay - carElt->_pitch;
	FLOAT_NORM_PI_PI(dang);
	car->restPos.vel.ay = dang / travelTime;
}
Exemple #15
0
void 
SimAeroUpdate(tCar *car, tSituation *s)
{
    tdble	hm;
    int		i;	    
    tCar	*otherCar;
    tdble	x, y;
    tdble	yaw, otherYaw, airSpeed, tmpas, spdang, tmpsdpang, dyaw;
    tdble	dragK = 1.0;

    x = car->DynGCg.pos.x;
    y = car->DynGCg.pos.y;
    yaw = car->DynGCg.pos.az;
    airSpeed = car->DynGC.vel.x;
    spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);

    if (airSpeed > 10.0) {
		for (i = 0; i < s->_ncars; i++) {
			if (i == car->carElt->index) {
				continue;
			}
			otherCar = &(SimCarTable[i]);
			otherYaw = otherCar->DynGCg.pos.az;
			tmpsdpang = spdang - atan2(y - otherCar->DynGCg.pos.y, x - otherCar->DynGCg.pos.x);
			FLOAT_NORM_PI_PI(tmpsdpang);
			dyaw = yaw - otherYaw;
			FLOAT_NORM_PI_PI(dyaw);
			if ((otherCar->DynGC.vel.x > 10.0) &&
				(fabs(dyaw) < 0.1396)) {
				if (fabs(tmpsdpang) > 2.9671) {	    /* 10 degrees */
					/* behind another car */
					tmpas = (tdble) (1.0 - exp(- 2.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) /
									  (otherCar->aero.Cd * otherCar->DynGC.vel.x)));
					if (tmpas < dragK) {
						dragK = tmpas;
					}
				} else if (fabs(tmpsdpang) < 0.1396) {	    /* 8 degrees */
					/* before another car [not sure how much the drag should be reduced in this case. In no case it should be lowered more than 50% I think. - Christos] */
					tmpas = (tdble) (1.0 - 0.5f * exp(- 8.0 * DIST(x, y, otherCar->DynGCg.pos.x, otherCar->DynGCg.pos.y) / (car->aero.Cd * car->DynGC.vel.x)));
					if (tmpas < dragK) {
						dragK = tmpas;
					}
				}
			}
		}
    }
    car->airSpeed2 = airSpeed * airSpeed;
    tdble v2 = car->airSpeed2;

	// simulate ground effect drop off caused by non-frontal airflow (diffusor stops working etc.)

	// Never used : remove ?
	//tdble speed = sqrt(car->DynGC.vel.x*car->DynGC.vel.x + car->DynGC.vel.y*car->DynGC.vel.y);
	//tdble cosa = 1.0f;
	
    car->aero.drag = (tdble) (-SIGN(car->DynGC.vel.x) * car->aero.SCx2 * v2 * (1.0f + (tdble)car->dammage / 10000.0f) * dragK * dragK);

    hm = 1.5f * (car->wheel[0].rideHeight + car->wheel[1].rideHeight + car->wheel[2].rideHeight + car->wheel[3].rideHeight);
    hm = hm*hm;
    hm = hm*hm;
    hm = 2 * exp(-3.0f*hm);
    car->aero.lift[0] = - car->aero.Clift[0] * v2 * hm;
    car->aero.lift[1] = - car->aero.Clift[1] * v2 * hm;
}
Exemple #16
0
void 
SimAeroUpdate(tCar *car, tSituation *s)
{
    //tdble	hm;
    int		i;	    
    tdble	airSpeed;
    tdble	dragK = 1.0;

    airSpeed = car->DynGC.vel.x;

    if (airSpeed > 10.0) {
	tdble x = car->DynGC.pos.x;
	tdble y = car->DynGC.pos.y;
	//	tdble x = car->DynGC.pos.x + cos(yaw)*wing->staticPos.x;
	//	tdble y = car->DynGC.pos.y + sin(yaw)*wing->staticPos.x;
	tdble yaw = car->DynGC.pos.az;
	tdble spdang = atan2(car->DynGCg.vel.y, car->DynGCg.vel.x);
	for (i = 0; i < s->_ncars; i++) {
	    if (i == car->carElt->index) {
		continue;
	    }


	    tdble tmpas = 1.00;

	    tCar* otherCar = &(SimCarTable[i]);
	    tdble otherYaw = otherCar->DynGC.pos.az;
	    tdble tmpsdpang = spdang - atan2(y - otherCar->DynGC.pos.y, x - otherCar->DynGC.pos.x);
	    NORM_PI_PI(tmpsdpang);
	    tdble dyaw = yaw - otherYaw;
	    NORM_PI_PI(dyaw);

	    if ((otherCar->DynGC.vel.x > 10.0) &&
		(fabs(dyaw) < 0.1396)) {
		if (fabs(tmpsdpang) > 2.9671) {	    /* 10 degrees */
		    /* behind another car - reduce overall airflow */
                    tdble factor = (fabs(tmpsdpang)-2.9671)/(M_PI-2.9671);

		    tmpas = 1.0 - factor * exp(- 2.0 * DIST(x, y, otherCar->DynGC.pos.x, otherCar->DynGC.pos.y)/(otherCar->aero.Cd * otherCar->DynGC.vel.x));
		    airSpeed = airSpeed * tmpas;
		} else if (fabs(tmpsdpang) < 0.1396f) {	    /* 8 degrees */
                    tdble factor = 0.5f * (0.1396f-fabs(tmpsdpang))/(0.1396f);
		    /* before another car - breaks down rear eddies, reduces only drag*/
		    tmpas = 1.0f - factor * exp(- 8.0 * DIST(x, y, otherCar->DynGC.pos.x, otherCar->DynGC.pos.y) / (car->aero.Cd * car->DynGC.vel.x));
		    dragK = dragK * tmpas;
		}
	    }
	}
    }

    car->airSpeed2 = airSpeed * airSpeed;
    
    tdble v2 = car->airSpeed2;
    tdble dmg_coef = ((tdble)car->dammage / 10000.0);

    car->aero.drag = -SIGN(car->DynGC.vel.x) * car->aero.SCx2 * v2 * (1.0 + dmg_coef) * dragK * dragK;


    // Since we have the forces ready, we just multiply. 
    // Should insert constants here.
    // Also, no torque is produced since the effect can be
    // quite dramatic. Interesting idea to make all drags produce
    // torque when the car is damaged.
    car->aero.Mx = car->aero.drag * dmg_coef * car->aero.rot_front[0];
    car->aero.My = car->aero.drag * dmg_coef * car->aero.rot_front[1];
    car->aero.Mz = car->aero.drag * dmg_coef * car->aero.rot_front[2];


    v2 = car->DynGC.vel.y;
    car->aero.lateral_drag = -SIGN(v2)*v2*v2*0.7;
    car->aero.Mx += car->aero.lateral_drag * dmg_coef * car->aero.rot_lateral[0];
    car->aero.My += car->aero.lateral_drag * dmg_coef * car->aero.rot_lateral[1];
    car->aero.Mz += car->aero.lateral_drag * dmg_coef * car->aero.rot_lateral[2];

    v2 = car->DynGC.vel.z;
    car->aero.vertical_drag = -SIGN(v2)*v2*v2*1.5;
    car->aero.Mx += car->aero.vertical_drag * dmg_coef * car->aero.rot_vertical[0];
    car->aero.My += car->aero.vertical_drag * dmg_coef * car->aero.rot_vertical[1];
    car->aero.Mz += car->aero.vertical_drag * dmg_coef * car->aero.rot_vertical[2];



    

}
Exemple #17
0
static uint32_t
calc_edit_distance(grn_ctx *ctx, char *sx, char *ex, char *sy, char *ey, int flags)
{
  int d = 0;
  uint32_t cx, lx, cy, ly, *dists;
  char *px, *py;
  for (px = sx, lx = 0; px < ex && (cx = grn_charlen(ctx, px, ex)); px += cx, lx++);
  for (py = sy, ly = 0; py < ey && (cy = grn_charlen(ctx, py, ey)); py += cy, ly++);
  if ((dists = GRN_PLUGIN_MALLOC(ctx, (lx + 1) * (ly + 1) * sizeof(uint32_t)))) {
    uint32_t x, y;
    for (x = 0; x <= lx; x++) { DIST(x, 0) = x; }
    for (y = 0; y <= ly; y++) { DIST(0, y) = y; }
    for (x = 1, px = sx; x <= lx; x++, px += cx) {
      cx = grn_charlen(ctx, px, ex);
      for (y = 1, py = sy; y <= ly; y++, py += cy) {
        cy = grn_charlen(ctx, py, ey);
        if (cx == cy && !memcmp(px, py, cx)) {
          DIST(x, y) = DIST(x - 1, y - 1);
        } else {
          uint32_t a = DIST(x - 1, y) + 1;
          uint32_t b = DIST(x, y - 1) + 1;
          uint32_t c = DIST(x - 1, y - 1) + 1;
          DIST(x, y) = ((a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c));
          if (flags & GRN_TABLE_FUZZY_SEARCH_WITH_TRANSPOSITION &&
              x > 1 && y > 1 && cx == cy &&
              memcmp(px, py - cy, cx) == 0 &&
              memcmp(px - cx, py, cx) == 0) {
            uint32_t t = DIST(x - 2, y - 2) + 1;
            DIST(x, y) = ((DIST(x, y) < t) ? DIST(x, y) : t);
          }
        }
      }
    }
    d = DIST(lx, ly);
    GRN_PLUGIN_FREE(ctx, dists);
  }
  return d;
}
Exemple #18
0
 bool pose_dist_thresh(geometry_msgs::Pose pose, geometry_msgs::Point pt, double thresh) {
     ROS_INFO("dist: %f, thresh: %f, val %d", DIST(pose.position.x, pose.position.y, pt.x, pt.y), thresh, DIST(pose.position.x, pose.position.y, pt.x, pt.y) < thresh);
     return DIST(pose.position.x, pose.position.y, pt.x, pt.y) < thresh;
 }