Exemplo n.º 1
0
pointf dotneato_closest(splines * spl, pointf pt)
{
    int i, j, k, besti, bestj;
    double bestdist2, d2, dlow2, dhigh2; /* squares of distances */
    double low, high, t;
    pointf c[4], pt2;
    bezier bz;

    besti = bestj = -1;
    bestdist2 = 1e+38;
    for (i = 0; i < spl->size; i++) {
	bz = spl->list[i];
	for (j = 0; j < bz.size; j++) {
	    pointf b;

	    b.x = bz.list[j].x;
	    b.y = bz.list[j].y;
	    d2 = DIST2(b, pt);
	    if ((bestj == -1) || (d2 < bestdist2)) {
		besti = i;
		bestj = j;
		bestdist2 = d2;
	    }
	}
    }

    bz = spl->list[besti];
    /* Pick best Bezier. If bestj is the last point in the B-spline, decrement.
     * Then set j to be the first point in the corresponding Bezier by dividing
     * then multiplying be 3. Thus, 0,1,2 => 0; 3,4,5 => 3, etc.
     */
    if (bestj == bz.size-1)
	bestj--;
    j = 3*(bestj / 3);
    for (k = 0; k < 4; k++) {
	c[k].x = bz.list[j + k].x;
	c[k].y = bz.list[j + k].y;
    }
    low = 0.0;
    high = 1.0;
    dlow2 = DIST2(c[0], pt);
    dhigh2 = DIST2(c[3], pt);
    do {
	t = (low + high) / 2.0;
	pt2 = Bezier(c, 3, t, NULL, NULL);
	if (fabs(dlow2 - dhigh2) < 1.0)
	    break;
	if (fabs(high - low) < .00001)
	    break;
	if (dlow2 < dhigh2) {
	    high = t;
	    dhigh2 = DIST2(pt2, pt);
	} else {
	    low = t;
	    dlow2 = DIST2(pt2, pt);
	}
    } while (1);
    return pt2;
}
Exemplo n.º 2
0
/* nearTail:
 * Given a point a and edge e, return true if a is closer to the
 * tail of e than the head.
 */
static int
nearTail (GVJ_t* job, pointf a, Agedge_t* e)
{
    pointf tp = gvrender_ptf(job, ND_coord(agtail(e)));
    pointf hp = gvrender_ptf(job, ND_coord(aghead(e)));

    return (DIST2(a, tp) < DIST2(a, hp));
}
Exemplo n.º 3
0
point dotneato_closest(splines * spl, point p)
{
    int i, j, k, besti, bestj;
    double bestdist2, d2, dlow2, dhigh2; /* squares of distances */
    double low, high, t;
    pointf c[4], pt2, pt;
    point rv;
    bezier bz;

    besti = bestj = -1;
    bestdist2 = 1e+38;
    P2PF(p, pt);
    for (i = 0; i < spl->size; i++) {
	bz = spl->list[i];
	for (j = 0; j < bz.size; j++) {
	    pointf b;

	    b.x = bz.list[j].x;
	    b.y = bz.list[j].y;
	    d2 = DIST2(b, pt);
	    if ((bestj == -1) || (d2 < bestdist2)) {
		besti = i;
		bestj = j;
		bestdist2 = d2;
	    }
	}
    }

    bz = spl->list[besti];
    j = bestj / 3;
    if (j >= spl->size)
	j--;
    for (k = 0; k < 4; k++) {
	c[k].x = bz.list[j + k].x;
	c[k].y = bz.list[j + k].y;
    }
    low = 0.0;
    high = 1.0;
    dlow2 = DIST2(c[0], pt);
    dhigh2 = DIST2(c[3], pt);
    do {
	t = (low + high) / 2.0;
	pt2 = Bezier(c, 3, t, NULL, NULL);
	if (fabs(dlow2 - dhigh2) < 1.0)
	    break;
	if (fabs(high - low) < .00001)
	    break;
	if (dlow2 < dhigh2) {
	    high = t;
	    dhigh2 = DIST2(pt2, pt);
	} else {
	    low = t;
	    dlow2 = DIST2(pt2, pt);
	}
    } while (1);
    PF2P(pt2, rv);
    return rv;
}
Exemplo n.º 4
0
static int
edgeLen (Agedge_t* e)
{
    pointf p = ND_coord(agtail(e));
    pointf q = ND_coord(aghead(e));
    return (int)DIST2(p,q);
}
Exemplo n.º 5
0
/** Process an NOEtypeArray */
void Action_NMRrst::ProcessNoeArray(NOEtypeArray& Narray, Frame const& frameIn, int frameNum) const
{
  for (NOEtypeArray::iterator my_noe = Narray.begin();
                              my_noe != Narray.end(); ++my_noe)
  {
    unsigned int shortest_idx1 = 0, shortest_idx2 = 0;
    double shortest_dist2 = -1.0;
    for (unsigned int idx1 = 0; idx1 != my_noe->Site1().Nindices(); ++idx1)
    {
      for (unsigned int idx2 = 0; idx2 != my_noe->Site2().Nindices(); ++idx2)
      {
        double dist2 = DIST2(frameIn.XYZ(my_noe->Site1().Idx(idx1)),
                             frameIn.XYZ(my_noe->Site2().Idx(idx2)),
                             Image_.ImageType(), frameIn.BoxCrd(),
                             ucell_, recip_);
        if (shortest_dist2 < 0.0 || dist2 < shortest_dist2) {
          shortest_dist2 = dist2;
          shortest_idx1 = idx1;
          shortest_idx2 = idx2;
        }
      }
    }
    // NOTE: Saving d^2
    my_noe->UpdateNOE(frameNum, shortest_dist2, shortest_idx1, shortest_idx2);
  }
}
Exemplo n.º 6
0
/* doArrowhead:
 * If edge is straight, we attach a cone to the edge as a group.
 */
static void doArrowhead (GVJ_t *job, pointf * A)
{
    FILE *out = job->output_file;
    obj_state_t *obj = job->obj;
    edge_t *e = obj->u.e;
    double rad, ht, y;
    pointf p0;      /* center of triangle base */
    point  tp,hp;

    p0.x = (A[0].x + A[2].x)/2.0;
    p0.y = (A[0].y + A[2].y)/2.0;
    rad = DIST(A[0],A[2])/2.0;
    ht = DIST(p0,A[1]);

    y = (CylHt + ht)/2.0;

    tp = ND_coord_i(e->tail);
    hp = ND_coord_i(e->head);
    fprintf(out, "Transform {\n");
    if (DIST2(A[1], tp) < DIST2(A[1], hp)) {
	TailHt = ht;
	fprintf(out, "  translation 0 %.3f 0\n", -y);
	fprintf(out, "  rotation 0 0 1 %.3f\n", M_PI);
    }
    else {
	HeadHt = ht;
	fprintf(out, "  translation 0 %.3f 0\n", y);
    }
    fprintf(out, "  children [\n");
    fprintf(out, "    Shape {\n");
    fprintf(out, "      geometry Cone {bottomRadius %.3f height %.3f }\n",
	rad, ht);
    fprintf(out, "      appearance Appearance {\n");
    fprintf(out, "        material Material {\n");
    fprintf(out, "          ambientIntensity 0.33\n");
    fprintf(out, "          diffuseColor %.3f %.3f %.3f\n",
	    obj->pencolor.u.rgba[0] / 255.,
	    obj->pencolor.u.rgba[1] / 255.,
	    obj->pencolor.u.rgba[2] / 255.);
    fprintf(out, "        }\n");
    fprintf(out, "      }\n");
    fprintf(out, "    }\n");
    fprintf(out, "  ]\n");
    fprintf(out, "}\n");
}
Exemplo n.º 7
0
Arquivo: p2.c Projeto: kota395/ip
int main(){
  int width=640, height=480;
  unsigned char*img=(unsigned char*)malloc(height*width*3);
  {
#define DIST2(x,y,xx,yy) (x-xx)*(x-xx)+(y-yy)*(y-yy)
    int y,x;
    for(y=0;y<height;y++)
      for(x=0;x<width;x++){
        img[(y*width+x)*3+0]=DIST2(x,y,320,180)<65536 ? 255 : 0;
        // 座標(x,y)の赤輝度
        img[(y*width+x)*3+1]=DIST2(x,y,260,300)<65536 ? 255 : 0;
        // 座標(x,y)の緑輝度
        img[(y*width+x)*3+2]=DIST2(x,y,380,300)<65536 ? 255 : 0;
        // 座標(x,y)の青輝度
      }
  }
  printf("P6 %d %d 255\n",width,height);
  fwrite(img,1,width*height*3,stdout);
  return 0;
}
Exemplo n.º 8
0
/*Space time separation plot.
in_series: time series
in_length: time series length
in_m, in_d: embedding dimension and time delay
in_steps: total time
in_idt: number of time units in each step
in_epsmax: max length scale
out: computed iso-lines of the plot
*/
void stplot(double *in_series, int *in_length, int *in_m, int *in_d, int *in_steps, int *in_idt, double *in_epsmax, double *out) {
	double tmp, need;
	int i,j, a, b, md, is, ieps, length, blength, m, d, steps, idt;
	double epsmax, *series, *hist, **stp;

/*
BIND PARAMETERS
*/
	series = in_series;
	length = *in_length;
	m = *in_m;
	d = *in_d;
	md = m*d;
	steps = *in_steps;
	idt = *in_idt;
	epsmax = sqr(*in_epsmax);
/**/
/*
INIT VARIABLES
*/
	blength = length - (m-1)*d;
	stp = (double**) R_alloc(MFRAC, sizeof(double*));
	for(i=0; i<MFRAC; i++) stp[i] = (double*) R_alloc(steps, sizeof(double));
	hist = (double*) R_alloc(MEPS, sizeof(double));
/**/

	for(i=0; i<steps; i++) { /*for each time step...*/
		for(j=0; j<MEPS; j++) hist[j] = 0.0; /*init histogram for all eps values*/
		for(j=0; j<(blength-i*idt); j++) { /*for each point...*/
			a = j; b = j+i*idt;
			DIST2(series, a, b, md, d, tmp);
			hist[MIN((long)(tmp*MEPS/epsmax), MEPS-1)]++;
		} /*end for each point*/
		for(j=0; j<MFRAC; j++) { /*update iso-lines*/
			need = (blength - i*idt)*(j+1)/(double) MFRAC;
			for(is=0, ieps=0; ieps<MEPS && is<need; ieps++)
				is +=hist[ieps];
			stp[j][i] = ieps*(epsmax/(double)MEPS);
		} /*end update iso-lines*/
	} /*end for each time step*/
	for(i=0; i<steps; i++) for(j=0; j<MFRAC; j++) /*take sqrt on all iso-lines*/
		stp[j][i] = sqrt(stp[j][i]);

	MATRIX2VEC(stp, out, MFRAC, steps); /*copy result to the output*/
}
Exemplo n.º 9
0
void init_fractal_polyline (fractal_line_struct *f,
	gint sizex, gint sizey,
	gint x0, gint y0,
	gint x1, gint y1) {

	// When using the fault or crack pens,
	// create a fractal line for the preview window or for initializing the drawing buffer

	gdouble cos, sin, ddist;

	// Subdivide and draw the line
	srand (f->seed);
	ddist = DIST2(x0,y0,x1,y1);
	sin = -((gdouble) (y1-y0)) / ddist;
	cos = ((gdouble)(x1-x0)) / ddist;;

	reset_line (f->polyline, (gint) pow(2.0,(gdouble) f->steps),1);
	set_line_translation (f->polyline, x0, y0, sizex, sizey);
	set_line_scale (f->polyline,(gdouble) (sizex-1), (gdouble) (sizey-1));

	divide_n_draw (f, f->steps, 0.0, 0.0,
		(gdouble) (x1-x0), (gdouble) (y1-y0), ddist, cos, sin);
}
Exemplo n.º 10
0
// NOTE: Because of maximum2 not essential to check idx>numBins?
Action::RetType Action_Radial::DoAction(int frameNum, ActionFrame& frm) {
  double D;
  Matrix_3x3 ucell, recip;
  int atom1, atom2;
  int nmask1, nmask2;
  int idx;
# ifdef _OPENMP
  int mythread;
# endif

  // Set imaging information and store volume if specified
  // NOTE: Ucell and recip only needed for non-orthogonal boxes.
  if (image_.ImagingEnabled() || useVolume_) {
    D = frm.Frm().BoxCrd().ToRecip(ucell,recip);
    if (useVolume_)  volume_ += D;
  }

  if ( rmode_ == NORMAL ) { 
    // Calculation of all atoms in Mask1 to all atoms in Mask2
    int outer_max = OuterMask_.Nselected();
    int inner_max = InnerMask_.Nselected();
#   ifdef _OPENMP
#   pragma omp parallel private(nmask1,nmask2,atom1,atom2,D,idx,mythread)
    {
    //mprintf("OPENMP: %i threads\n",omp_get_num_threads());
    mythread = omp_get_thread_num();
#   pragma omp for
#   endif
    for (nmask1 = 0; nmask1 < outer_max; nmask1++) {
      atom1 = OuterMask_[nmask1];
      for (nmask2 = 0; nmask2 < inner_max; nmask2++) {
        atom2 = InnerMask_[nmask2];
        if (atom1 != atom2) {
          D = DIST2( frm.Frm().XYZ(atom1), frm.Frm().XYZ(atom2),
                     image_.ImageType(), frm.Frm().BoxCrd(), ucell, recip);
          if (D <= maximum2_) {
            // NOTE: Can we modify the histogram to store D^2?
            D = sqrt(D);
            //mprintf("MASKLOOP: %10i %10i %10.4f\n",atom1,atom2,D);
            idx = (int) (D * one_over_spacing_);
            if (idx > -1 && idx < numBins_)
#             ifdef _OPENMP
              ++rdf_thread_[mythread][idx];
#             else
              ++RDF_[idx];
#             endif
          }
        }
      } // END loop over 2nd mask
    } // END loop over 1st mask
#   ifdef _OPENMP
    } // END pragma omp parallel
#   endif 
  } else if ( rmode_ == NO_INTRAMOL ) {
    // Calculation of all atoms in Mask1 to all atoms in Mask2, ignoring
    // intra-molecular distances.
    int outer_max = OuterMask_.Nselected();
    int inner_max = InnerMask_.Nselected();
#   ifdef _OPENMP
#   pragma omp parallel private(nmask1,nmask2,atom1,atom2,D,idx,mythread)
    {
    //mprintf("OPENMP: %i threads\n",omp_get_num_threads());
    mythread = omp_get_thread_num();
#   pragma omp for
#   endif
    for (nmask1 = 0; nmask1 < outer_max; nmask1++) {
      atom1 = OuterMask_[nmask1];
      for (nmask2 = 0; nmask2 < inner_max; nmask2++) {
        atom2 = InnerMask_[nmask2];
        if ( (*currentParm_)[atom1].MolNum() != (*currentParm_)[atom2].MolNum() ) {
          D = DIST2( frm.Frm().XYZ(atom1), frm.Frm().XYZ(atom2),
                     image_.ImageType(), frm.Frm().BoxCrd(), ucell, recip);
          if (D <= maximum2_) {
            // NOTE: Can we modify the histogram to store D^2?
            D = sqrt(D);
            //mprintf("MASKLOOP: %10i %10i %10.4f\n",atom1,atom2,D);
            idx = (int) (D * one_over_spacing_);
            if (idx > -1 && idx < numBins_)
#             ifdef _OPENMP
              ++rdf_thread_[mythread][idx];
#             else
              ++RDF_[idx];
#             endif
          }
        }
      } // END loop over 2nd mask
    } // END loop over 1st mask
#   ifdef _OPENMP
    } // END pragma omp parallel
#   endif
  } else { // CENTER1 || CENTER2
    // Calculation of center of one Mask to all atoms in other Mask
    Vec3 coord_center = frm.Frm().VGeometricCenter(OuterMask_);
    int mask2_max = InnerMask_.Nselected();
#   ifdef _OPENMP
#   pragma omp parallel private(nmask2,atom2,D,idx,mythread)
    {
    mythread = omp_get_thread_num();
#   pragma omp for
#   endif
    for (nmask2 = 0; nmask2 < mask2_max; nmask2++) {
      atom2 = InnerMask_[nmask2];
      D = DIST2(coord_center.Dptr(), frm.Frm().XYZ(atom2), image_.ImageType(),
                frm.Frm().BoxCrd(), ucell, recip);
      if (D <= maximum2_) {
        // NOTE: Can we modify the histogram to store D^2?
        D = sqrt(D);
        //mprintf("MASKLOOP: %10i %10i %10.4f\n",atom1,atom2,D);
        idx = (int) (D * one_over_spacing_);
        if (idx > -1 && idx < numBins_)
#         ifdef _OPENMP
          ++rdf_thread_[mythread][idx];
#         else
          ++RDF_[idx];
#         endif
      }
    } // END loop over 2nd mask
#   ifdef _OPENMP
    } // END pragma omp parallel
#   endif 
  }
  ++numFrames_;

  return Action::OK;
} 
Exemplo n.º 11
0
Action::RetType Action_DNAionTracker::DoAction(int frameNum, Frame* currentFrame, Frame** frameAddress) {
  Matrix_3x3 ucell, recip;
  double d_tmp, dval;
  Vec3 P1, P2, BASE;
  // Setup imaging info if necessary
  if (ImageType()==NONORTHO) 
    currentFrame->BoxCrd().ToRecip(ucell,recip);

  // Get center for P1, P2, and Base
  if (useMass_) {
    P1 = currentFrame->VCenterOfMass( p1_ );
    P2 = currentFrame->VCenterOfMass( p2_ );
    BASE = currentFrame->VCenterOfMass( base_ );
  } else {
    P1 = currentFrame->VGeometricCenter( p1_ );
    P2 = currentFrame->VGeometricCenter( p2_ );
    BASE = currentFrame->VGeometricCenter( base_ );
  }
 
  // Calculate P -- P distance and centroid
  double d_pp = DIST2(P1.Dptr(), P2.Dptr(), ImageType(), currentFrame->BoxCrd(), ucell, recip);
  Vec3 pp_centroid = (P1 + P2) / 2.0;

  // Cutoff^2
  double d_cut = d_pp*0.25 + (poffset_*poffset_); // TODO: precalc offset^2

  // Calculate P -- base centroid to median point
  double d_pbase = DIST2(pp_centroid.Dptr(), BASE.Dptr(), ImageType(), currentFrame->BoxCrd(), 
                         ucell, recip);

  //double d_min = DBL_MAX;
  if (bintype_ == SHORTEST)
    dval = DBL_MAX; //d_min;
  else
    dval = 0;
  // Loop over ion positions
  for (AtomMask::const_iterator ion = ions_.begin(); ion != ions_.end(); ++ion)
  {
    const double* ionxyz = currentFrame->XYZ(*ion);
    double d_p1ion =   DIST2(P1.Dptr(),   ionxyz, ImageType(), currentFrame->BoxCrd(), 
                             ucell, recip);
    double d_p2ion =   DIST2(P2.Dptr(),   ionxyz, ImageType(), currentFrame->BoxCrd(), 
                             ucell, recip);
    double d_baseion = DIST2(BASE.Dptr(), ionxyz, ImageType(), currentFrame->BoxCrd(), 
                             ucell, recip);
    //mprintf("DEBUG: ion atom %i to P1 is %f\n", *ion+1, sqrt(d_p1ion));
    //mprintf("DEBUG: ion atom %i to P2 is %f\n", *ion+1, sqrt(d_p2ion));
    //mprintf("DEBUG: ion atom %i to base is %f\n", *ion+1, sqrt(d_baseion));
    //mprintf("DEBUG: d_pp is %f, poffset is %f, d_cut is %f\n", sqrt(d_pp), poffset_, sqrt(d_cut));

    int bound = 0;
    int boundLower = 0;
    int boundUpper = 0;

    if (d_p1ion < d_cut && d_p2ion < d_cut)
      bound = 1;
    if (d_baseion < d_pbase)
      boundLower = 1;
    if (bound && boundLower == 0)
      boundUpper = 1;
    //if (d_tmp > d_min)
    //  d_min = d_tmp;

    switch (bintype_) {
      case COUNT: 
        dval += (double)bound; break;
      case SHORTEST:
        if (d_p1ion < d_p2ion)
          d_tmp = d_p1ion;
        else
          d_tmp = d_p2ion;
        if (d_tmp > d_baseion)
          d_tmp = d_baseion;
        if (d_tmp < dval) 
          dval = d_tmp;
        break;
      case TOPCONE: 
        dval += (double)boundUpper; break;
      case BOTTOMCONE: 
        dval += (double)boundLower; break;
    }
  }
  if (bintype_ == SHORTEST)
    dval = sqrt(dval);
  distance_->Add(frameNum, &dval);
  
  return Action::OK;
}
Exemplo n.º 12
0
gboolean draw_continuous_line_by_dot (hf_struct_type *hf, pen_struct *pen,
                                      gdouble begin_x, gdouble begin_y,
                                      gdouble *end_x_ptr, gdouble *end_y_ptr,
                                      gboolean draw_end, gdouble **gauss_list) {

    // Same concept as draw_hf_line in draw_hf.c
    // Draw in real coordinates (interpolated from (gdouble))
    // Instead of drawing a HF, we draw a gaussian map, whose size is more versatile
    // We smooth progressively what is drawn
    // Return TRUE if something has been drawn, FALSE otherwise

    gint h, steps, map_size, i, j, ii;
    gdouble spacing, dist, dx, dy, end_x, end_y;
    gboolean wrap;
    map_struct *map;
    draw_buf *d;

    map = pen->map;
    d = map->dr_buf;

    // We force the map size to be odd
    map_size = 2*map->radius+1;

    end_x = *end_x_ptr;
    end_y = *end_y_ptr;

    if (hf->if_tiles==NULL)
        wrap = (pen->wrap==TILING_YES) || (pen->wrap==TILING_AUTO);
    else
        wrap = (pen->wrap==TILING_YES) ||
               ((pen->wrap==TILING_AUTO) && *hf->if_tiles);

    // 	Radius is 0 for a size of 1, 1 for a size of 3... up to 127 for a size of 255
    //	Size should always be odd

    // Draw each dot from the last x,y
    // Won't draw the last (just before the mouse release)
    // spacing is the increment applied, in pixels, each time we draw a dot

    spacing = pen->spacing * (gdouble) map_size;

    dist = (gdouble) DIST2((gdouble) begin_x,
                           (gdouble) begin_y,
                           (gdouble) end_x, (gdouble) end_y);

    dx = spacing * ((gdouble) (end_x - begin_x)) / dist;
    dy = spacing * ((gdouble) (end_y - begin_y)) /dist ;

    steps = (gint) floor(dist/spacing);
    if (!steps) {
        // We return FALSE when there is nothing to draw,
        // so that the (begin_x, begin_y) coordinates are not changed
        // for the next line to draw
        return FALSE;
    }

    if (pen->shape != NO_WAVE_SHAPE) {
        rotate ( (gdouble) dx, (gdouble) dy,
                 map->data, map->tmp,
                 map_size, map_size,
                 HF_TYPE_ID, OVERFLOW_ZERO);
        map->map_to_use = map->tmp;
    }
    else
        map->map_to_use = map->data;

    if (d->delayed_dot) {
        draw_dot (hf, pen, (d->tail+d->current_tail)->x, (d->tail+d->current_tail)->y, gauss_list);
        d->delayed_dot = FALSE;
    }

// printf("DX: %5.2f; DY: %5.2f; shape: %d; symm: %d\n",dx,dy,pen->shape, pen->map->square_symmetry);
    for (h=1; h<=steps; h++) {
        end_x = begin_x + dx * (gdouble) h;
        end_y = begin_y + dy * (gdouble) h;
        if (pen->merge == SMOOTH_OP)
            map_convolve (map->map_to_use,
                          map_size, map_size,
                          hf->hf_buf, hf->max_x, hf->max_y,
                          (gint) end_x, (gint) end_y,
                          wrap, 100, gauss_list, TRUE);
        else {

            if (pen->overlap) {

                generalized_merge(
                    (gpointer) map->map_to_use, HF_TYPE_ID,
                    map_size, map_size,
                    hf->hf_buf, HF_TYPE_ID,
                    hf->max_x, hf->max_y,
                    (gint) end_x, (gint) end_y,
                    pen->merge,
                    wrap,
                    map->square_symmetry);
            }
            else {
                // 1. Translate the drawing buffer "under" the
                //    current map (pen tip)
                // 2. Write in the drawing buffer
                // 3. Write the drawing buffer in the layer buffer

                translate_draw_buf (map, (gint) end_x,
                                    (gint) end_y, pen->shape);

                generalized_merge( (gpointer) map->map_to_use,
                                   HF_TYPE_ID,
                                   map_size, map_size,
                                   d->data, HF_TYPE_ID,
                                   d->size, d->size,
                                   d->size/2, d->size/2,
                                   ADD,
                                   FALSE, // no wrap
                                   pen->map->square_symmetry);

                generalized_merge( (gpointer) map->dr_buf->data,
                                   HF_TYPE_ID,
                                   d->size, d->size,
                                   hf->layer_buf, HF_TYPE_ID,
                                   hf->max_x, hf->max_y,
                                   (gint) end_x, (gint) end_y,
                                   MAX_MERGE,
                                   wrap,
                                   FALSE ); // square_symmetry
            }
        }
    }

    // The last dot drawn doesn't fall on the coordinates where the motion motify event was emitted,
    // so we must adjust these coordinates
    (*end_x_ptr) = end_x;
    (*end_y_ptr) = end_y;

    return TRUE;
}
Exemplo n.º 13
0
/** Find the minimum distance between atoms in distanceMask and each 
  * solvent Mask.
  */
Action_Closest::RetType Action_Closest::DoAction(int frameNum, Frame& frmIn) {
  int solventMol; 
  double Dist, maxD;
  Matrix_3x3 ucell, recip;
  AtomMask::const_iterator solute_atom;
  Iarray::const_iterator solvent_atom;

  if (image_.ImagingEnabled()) {
    frmIn.BoxCrd().ToRecip(ucell, recip);
    // Calculate max possible imaged distance
    maxD = frmIn.BoxCrd().BoxX() + frmIn.BoxCrd().BoxY() + 
           frmIn.BoxCrd().BoxZ();
    maxD *= maxD;
  } else {
    // If not imaging, set max distance to an arbitrarily large number
    maxD = DBL_MAX;
  }

  // Loop over all solvent molecules in original frame
  if (useMaskCenter_) {
    Vec3 maskCenter = frmIn.VGeometricCenter( distanceMask_ );
    for (solventMol=0; solventMol < NsolventMolecules_; solventMol++) {
      SolventMols_[solventMol].D = maxD;
      for (solvent_atom = SolventMols_[solventMol].solventAtoms.begin();
           solvent_atom != SolventMols_[solventMol].solventAtoms.end(); ++solvent_atom)
      {
        Dist = DIST2( maskCenter.Dptr(),
                      frmIn.XYZ(*solvent_atom), image_.ImageType(),
                      frmIn.BoxCrd(), ucell, recip);
        if (Dist < SolventMols_[solventMol].D) 
          SolventMols_[solventMol].D = Dist;
      }
    }
  } else {
    for (solventMol=0; solventMol < NsolventMolecules_; solventMol++) {
      if (debug_ > 1)
        mprintf("DEBUG: Calculating distance for molecule %i\n", solventMol);
      // Set the initial minimum distance for this solvent mol to be the
      // max possible distance.
      SolventMols_[solventMol].D = maxD;
      // Calculate distance between each atom in distanceMask and atoms in solvent Mask
      for (solvent_atom = SolventMols_[solventMol].solventAtoms.begin();
           solvent_atom != SolventMols_[solventMol].solventAtoms.end(); ++solvent_atom)
      {
        for (solute_atom = distanceMask_.begin(); 
             solute_atom != distanceMask_.end(); ++solute_atom)
        {
          Dist = DIST2(frmIn.XYZ(*solute_atom),
                       frmIn.XYZ(*solvent_atom), image_.ImageType(), 
                       frmIn.BoxCrd(), ucell, recip);
          if (Dist < SolventMols_[solventMol].D) 
            SolventMols_[solventMol].D = Dist;
          if (debug_ > 2)
            mprintf("DEBUG: SolvMol %i, soluteAtom %i, solventAtom %i, D= %f, minD= %f\n",
                    solventMol, *solute_atom, *solvent_atom, Dist,
                    sqrt(SolventMols_[solventMol].D));
        }
      }
      if (debug_ > 1) mprintf("DEBUG:\tMol %8i minD= %lf\n",solventMol, SolventMols_[solventMol].D);
    } // END for loop over solventMol
  }

  // Sort distances
  std::sort( SolventMols_.begin(), SolventMols_.end(), moldist_cmp() );
  // Add first closestWaters solvent atoms to stripMask
  std::vector<MolDist>::iterator solventend = SolventMols_.begin() + closestWaters_;
  for ( std::vector<MolDist>::const_iterator solvent = SolventMols_.begin();
                                             solvent != solventend;
                                           ++solvent ) 
  {
    solvent_atom = solvent->mask.begin();
    mprintf("\tMol= %8i  Atom= %8i  Dist= %10.4f\n", solvent->mol,
            *solvent_atom + 1, sqrt( solvent->D ));
  }

  return Action_Closest::OK;
}
Exemplo n.º 14
0
Arquivo: aoi.c Projeto: ChowZenki/aoi
inline static bool
is_near(float p1[3], float p2[3]) {
	return DIST2(p1,p2) < AOI_RADIS2 * 0.25f ;
}
Exemplo n.º 15
0
static void vrml_ellipse(GVJ_t * job, pointf * A, int filled)
{
    FILE *out = job->output_file;
    obj_state_t *obj = job->obj;
    node_t *n;
    edge_t *e;
    double z = obj->z;
    double rx, ry;
    int dx, dy;
    pointf npf, nqf;
    point np;
    int pen;
    gdImagePtr brush = NULL;

    rx = A[1].x - A[0].x;
    ry = A[1].y - A[0].y;

    switch (obj->type) {
    case ROOTGRAPH_OBJTYPE:
    case CLUSTER_OBJTYPE:
	break;
    case NODE_OBJTYPE:
	n = obj->u.n;
	if (shapeOf(n) == SH_POINT) {
	    doSphere (job, n, A[0], z, rx, ry);
	    return;
	}
	pen = set_penstyle(job, im, brush);

	npf = vrml_node_point(job, n, A[0]);
	nqf = vrml_node_point(job, n, A[1]);

	dx = ROUND(2 * (nqf.x - npf.x));
	dy = ROUND(2 * (nqf.y - npf.y));

	PF2P(npf, np);

	if (filled)
	    gdImageFilledEllipse(im, np.x, np.y, dx, dy, color_index(im, obj->fillcolor));
	gdImageArc(im, np.x, np.y, dx, dy, 0, 360, pen);

	if (brush)
	    gdImageDestroy(brush);

	fprintf(out, "Transform {\n");
	fprintf(out, "  translation %.3f %.3f %.3f\n", A[0].x, A[0].y, z);
	fprintf(out, "  scale %.3f %.3f 1\n", rx, ry);
	fprintf(out, "  children [\n");
	fprintf(out, "    Transform {\n");
	fprintf(out, "      rotation 1 0 0   1.57\n");
	fprintf(out, "      children [\n");
	fprintf(out, "        Shape {\n");
	fprintf(out, "          geometry Cylinder { side FALSE }\n");
	fprintf(out, "          appearance Appearance {\n");
	fprintf(out, "            material Material {\n");
	fprintf(out, "              ambientIntensity 0.33\n");
	fprintf(out, "              diffuseColor 1 1 1\n");
	fprintf(out, "            }\n");
	fprintf(out, "            texture ImageTexture { url \"node%d.png\" }\n", n->id);
	fprintf(out, "          }\n");
	fprintf(out, "        }\n");
	fprintf(out, "      ]\n");
	fprintf(out, "    }\n");
	fprintf(out, "  ]\n");
	fprintf(out, "}\n");
	break;
    case EDGE_OBJTYPE:
	e = obj->u.e;
	/* this is gruesome, but how else can we get z coord */
	if (DIST2(A[0], ND_coord_i(e->tail)) < DIST2(A[0], ND_coord_i(e->head)))
	    z = obj->tail_z;
	else
	    z = obj->head_z;

	fprintf(out, "Transform {\n");
	fprintf(out, "  translation %.3f %.3f %.3f\n", A[0].x, A[0].y, z);
	fprintf(out, "  children [\n");
	fprintf(out, "    Shape {\n");
	fprintf(out, "      geometry Sphere {radius %.3f }\n", (double) rx);
	fprintf(out, "      appearance USE E%d\n", e->id);
	fprintf(out, "    }\n");
	fprintf(out, "  ]\n");
	fprintf(out, "}\n");
    }
}
Exemplo n.º 16
0
static void vrml_polygon(GVJ_t *job, pointf * A, int np, int filled)
{
    FILE *out = job->output_file;
    obj_state_t *obj = job->obj;
    node_t *n;
    edge_t *e;
    double z = obj->z;
    pointf p, mp;
    gdPoint *points;
    int i, pen;
    gdImagePtr brush = NULL;
    double theta;

    switch (obj->type) {
    case ROOTGRAPH_OBJTYPE:
	fprintf(out, " Background { skyColor %.3f %.3f %.3f }\n",
	    obj->fillcolor.u.rgba[0] / 255.,
	    obj->fillcolor.u.rgba[1] / 255.,
	    obj->fillcolor.u.rgba[2] / 255.);
	Saw_skycolor = TRUE;
	break;
    case CLUSTER_OBJTYPE:
	break;
    case NODE_OBJTYPE:
	n = obj->u.n;
	pen = set_penstyle(job, im, brush);
	points = N_GNEW(np, gdPoint);
	for (i = 0; i < np; i++) {
	    mp = vrml_node_point(job, n, A[i]);
	    points[i].x = ROUND(mp.x);
	    points[i].y = ROUND(mp.y);
	}
	if (filled)
	    gdImageFilledPolygon(im, points, np, color_index(im, obj->fillcolor));
	gdImagePolygon(im, points, np, pen);
	free(points);
	if (brush)
	    gdImageDestroy(brush);

	fprintf(out, "Shape {\n");
	fprintf(out, "  appearance Appearance {\n");
	fprintf(out, "    material Material {\n");
	fprintf(out, "      ambientIntensity 0.33\n");
	fprintf(out, "        diffuseColor 1 1 1\n");
	fprintf(out, "    }\n");
	fprintf(out, "    texture ImageTexture { url \"node%d.png\" }\n", n->id);
	fprintf(out, "  }\n");
	fprintf(out, "  geometry Extrusion {\n");
	fprintf(out, "    crossSection [");
	for (i = 0; i < np; i++) {
	    p.x = A[i].x - ND_coord_i(n).x;
	    p.y = A[i].y - ND_coord_i(n).y;
	    fprintf(out, " %.3f %.3f,", p.x, p.y);
	}
	p.x = A[0].x - ND_coord_i(n).x;
	p.y = A[0].y - ND_coord_i(n).y;
	fprintf(out, " %.3f %.3f ]\n", p.x, p.y);
	fprintf(out, "    spine [ %d %d %.3f, %d %d %.3f ]\n",
		ND_coord_i(n).x, ND_coord_i(n).y, z - .01,
		ND_coord_i(n).x, ND_coord_i(n).y, z + .01);
	fprintf(out, "  }\n");
	fprintf(out, "}\n");
	break;
    case EDGE_OBJTYPE:
	e = obj->u.e;
	if (np != 3) {
	    static int flag;
	    if (!flag) {
		flag++;
		agerr(AGWARN,
		  "vrml_polygon: non-triangle arrowheads not supported - ignoring\n");
	    }
	}
	if (IsSegment) {
	    doArrowhead (job, A);
	    return;
	}
	p.x = p.y = 0.0;
	for (i = 0; i < np; i++) {
	    p.x += A[i].x;
	    p.y += A[i].y;
	}
	p.x = p.x / np;
	p.y = p.y / np;

	/* it is bad to know that A[1] is the aiming point, but we do */
	theta =
	    atan2((A[0].y + A[2].y) / 2.0 - A[1].y,
		  (A[0].x + A[2].x) / 2.0 - A[1].x) + M_PI / 2.0;

	/* this is gruesome, but how else can we get z coord */
	if (DIST2(p, ND_coord_i(e->tail)) < DIST2(p, ND_coord_i(e->head)))
	    z = obj->tail_z;
	else
	    z = obj->head_z;

	/* FIXME: arrow vector ought to follow z coord of bezier */
	fprintf(out, "Transform {\n");
	fprintf(out, "  translation %.3f %.3f %.3f\n", p.x, p.y, z);
	fprintf(out, "  children [\n");
	fprintf(out, "    Transform {\n");
	fprintf(out, "      rotation 0 0 1 %.3f\n", theta);
	fprintf(out, "      children [\n");
	fprintf(out, "        Shape {\n");
	fprintf(out, "          geometry Cone {bottomRadius %.3f height %.3f }\n",
		obj->penwidth * 2.5, obj->penwidth * 10.0);
	fprintf(out, "          appearance USE E%d\n", e->id);
	fprintf(out, "        }\n");
	fprintf(out, "      ]\n");
	fprintf(out, "    }\n");
	fprintf(out, "  ]\n");
	fprintf(out, "}\n");
	break;
    }
}
Exemplo n.º 17
0
Arquivo: aoi.c Projeto: ChowZenki/aoi
inline static float
dist2(struct object *p1, struct object *p2) {
	float d = DIST2(p1->position,p2->position);
	return d;
}
Exemplo n.º 18
0
// Action_RandomizeIons::DoAction()
Action::RetType Action_RandomizeIons::DoAction(int frameNum, ActionFrame& frm) {
  Matrix_3x3 ucell, recip;

  if (image_.ImageType() == NONORTHO)
    frm.Frm().BoxCrd().ToRecip(ucell, recip);
  // Loop over all solvent molecules and mark those that are too close to the solute
  int n_active_solvent = 0;
  for (int idx = 0; idx != n_solvent_; idx++) {
    solvent_[idx] = true;
    if (around_.MaskStringSet()) {
      const double* solventXYZ = frm.Frm().XYZ( solventStart_[idx] );
      // Is solvent molecule too close to any atom in the around mask?
      for (AtomMask::const_iterator atom = around_.begin(); atom != around_.end(); ++atom)
      {
        double dist = DIST2( solventXYZ, frm.Frm().XYZ(*atom), image_.ImageType(),
                             frm.Frm().BoxCrd(), ucell, recip);
        if (dist < min_) {
          solvent_[idx] = false;
          //mprintf("RANDOMIZEIONS: water %i only %.2f ang from around @%i\n",
          //        smolnum, sqrt(dist), *atom+1);
          break;
        }
      }
    }
    if (solvent_[idx]) ++n_active_solvent;
  }
  if (n_active_solvent < ions_.Nselected()) {
    mprinterr("Error: Fewer active solvent molecules (%i) than ions (%i)\n",
              n_active_solvent, ions_.Nselected());
    return Action::ERR;
  }

  // DEBUG - print solvent molecule mask
  if (debug_ > 2) {
    mprintf("RANDOMIZEIONS: The following waters are ACTIVE so far:\n");
    int smoltot = 0;
    for (int idx = 0; idx != n_solvent_; idx++) {
      if (solvent_[idx]) {
        mprintf(" %5i ", solventStart_[idx]+1 );
        ++smoltot;
        if (smoltot%10 == 0) mprintf("\n");
      }
    }
    mprintf("RANDOMIZEIONS: A total of %i waters (out of %zu) are active\n",
            smoltot, solvent_.size());
  }

  // Outer loop over all ions
  for (AtomMask::const_iterator ion1 = ions_.begin(); ion1 != ions_.end(); ++ion1)
  {
    //mprintf("RANDOMIZEIONS: Processing ion atom %i\n", *ion1+1);
    // Is a potential solvent molecule close to any of the ions (except this one)?
    for (int idx = 0; idx != n_solvent_; idx++) {
      if (solvent_[idx]) {
        const double* solventXYZ = frm.Frm().XYZ( solventStart_[idx] );
        // This solvent is active; check distance to all other ions
        for (AtomMask::const_iterator ion2 = ions_.begin(); ion2 != ions_.end(); ++ion2)
        {
          if (*ion1 != *ion2) {
            double dist = DIST2( solventXYZ, frm.Frm().XYZ(*ion2), image_.ImageType(),
                                 frm.Frm().BoxCrd(), ucell, recip);
            if (dist < overlap_) {
              // This solvent mol is too close to another ion.
              solvent_[idx] = false;
              //mprintf("RANDOMIZEIONS: water %i only %.2f ang from ion @%i\n",
              //        smolnum, sqrt(dist), *ion2+1);
              break;
            }
          }
        } // END inner loop over ions
      }
    } // END loop over solvent molecules
    // The solvent_ array should now be true for all solvent molecules eligible
    // to swap with ion.
    int loop = 1;
    int swapMol = 0;
    while (loop > 0 && loop < 10000) {
      // Run the random number generator so that the same number is not produced
      // when the seed was set manually.
      swapMol = (int)(RN_.rn_gen() * (double)n_solvent_);
      if ( solvent_[swapMol] ) 
        loop = -1;
      else 
        ++loop;
    }

    // If a suitable solvent molecule was found, swap it.
    if (loop > 0) {
      mprintf("Warning: Tried to swap ion @%i with %i random waters\n",*ion1+1,loop);
      mprintf("Warning: and couldn't meet criteria; skipping.\n");
    } else {
      if (debug_ > 2)
        mprintf("RANDOMIZEIONS: Swapping solvent mol %i for ion @%i\n", swapMol+1, *ion1+1);
      const double* ionXYZ = frm.Frm().XYZ( *ion1 );
      int sbegin = solventStart_[ swapMol ];
      const double* watXYZ = frm.Frm().XYZ( sbegin );
      Vec3 trans( ionXYZ[0] - watXYZ[0],
                  ionXYZ[1] - watXYZ[1],
                  ionXYZ[2] - watXYZ[2]);
      frm.ModifyFrm().Translate( trans, sbegin, solventEnd_[ swapMol ] );
      trans.Neg();
      frm.ModifyFrm().Translate( trans, *ion1 );
    }
  } // END outer loop over all ions

  return Action::MODIFY_COORDS;
}
Exemplo n.º 19
0
// Action_Watershell::action()
Action::RetType Action_Watershell::DoAction(int frameNum, ActionFrame& frm) {
  Matrix_3x3 ucell, recip;
  int nlower = 0;
  int nupper = 0;

  if (ImageType()==NONORTHO) frm.Frm().BoxCrd().ToRecip(ucell,recip);

  int Vidx, Uidx, Vat, currentRes;
  int NU = soluteMask_.Nselected();
  int NV = solventMask_.Nselected();
  double dist;
# ifdef _OPENMP
  int mythread;
#pragma omp parallel private(dist,Vidx,Vat,currentRes,Uidx,mythread)
{
  mythread = omp_get_thread_num();
#pragma omp for
# endif
  // Assume solvent mask is the larger one.
  // Loop over solvent atoms
  for (Vidx = 0; Vidx < NV; Vidx++) {
    // Figure out which solvent residue this is
    Vat = solventMask_[Vidx];
    currentRes = (*CurrentParm_)[ Vat ].ResNum();
    // Loop over solute atoms
    for (Uidx = 0; Uidx < NU; Uidx++) {
      // If residue is not yet marked as 1st shell, calc distance
#     ifdef _OPENMP
      if ( activeResidues_thread_[mythread][currentRes] < 2 )
#     else
      if ( activeResidues_[currentRes] < 2 )
#     endif
      {
        dist = DIST2(frm.Frm().XYZ(soluteMask_[Uidx]), frm.Frm().XYZ(Vat),
                     ImageType(), frm.Frm().BoxCrd(), ucell, recip );
        // Less than upper, 2nd shell
        if (dist < upperCutoff_) 
        {
#         ifdef _OPENMP
          activeResidues_thread_[mythread][currentRes] = 1;
#         else
          activeResidues_[currentRes] = 1;
#         endif
          // Less than lower, 1st shell
          if (dist < lowerCutoff_)
#           ifdef _OPENMP
            activeResidues_thread_[mythread][currentRes] = 2;
#           else
            activeResidues_[currentRes] = 2;
#           endif
        }
      }
    } // End loop over solute atoms
  } // End loop over solvent atoms
# ifdef _OPENMP
} // END parallel
  // Combine results from each thread.
  for (int res = 0; res < NactiveResidues_; res++) {
    int shell = 0;
    for (int thread = 0; thread < numthreads_; thread++) {
      if (activeResidues_thread_[thread][res] > shell)
        shell = activeResidues_thread_[thread][res];
      // Dont break here so we can reset counts. Could also do with a fill 
      activeResidues_thread_[thread][res] = 0;
    }
    if (shell > 0) {
      ++nupper;
      if (shell > 1) ++nlower;
    }
  }
# else
  // Now each residue is marked 0 (no shell), 1 (second shell), 2 (first shell)
  for (std::vector<int>::iterator shell = activeResidues_.begin();
                                  shell != activeResidues_.end(); ++shell)
  {
    if ( *shell > 0 ) {
      ++nupper;
      if ( *shell > 1 ) ++nlower;
    }
    // Reset for next pass
    *shell = 0;
  }
# endif
  lower_->Add(frameNum, &nlower);
  upper_->Add(frameNum, &nupper);

  return Action::OK;
}
Exemplo n.º 20
0
void map_init (map_struct *map, gint size,
               gint level, gint shape, gdouble spacing) {

    gint x,y, radius, ss;
    gdouble dlevel, offset, ddist, p, maxd = (gdouble) MAX_HF_VALUE;
    shape_type *shape_data=NULL;
    radius = size >> 1;
    // The map size should always be odd
    size = 2*radius+1;
    ss = size * size;
    map->data = (hf_type *) x_realloc (map->data, sizeof(hf_type) * ss, "hf_type (map->data in draw.c)");
    map->tmp = (hf_type *) x_realloc (map->tmp, sizeof(hf_type) * ss, "hf_type (map->tmp in draw.c)");
    map->map_to_use = map->data;
    map->units = (hf_type *) x_realloc (map->units, sizeof(hf_type) * ss, "hf_type (map->units in draw.c)");

    FILL_MAP(map->units,ss,1);

    if (spacing == SPACING_HIGH_QUALITY) {
        dlevel = LEVEL_HQ_SPACING;
    }
    else {
        if (spacing == SPACING_STANDARD_QUALITY)
            dlevel = LEVEL_SQ_SPACING;
        else if (spacing == SPACING_VHIGH_QUALITY)
            dlevel = LEVEL_VHQ_SPACING;
        else
            dlevel = LEVEL_LQ_SPACING;
    }
    if (shape != NO_WAVE_SHAPE) {
        shape_data = shape_type_new(shape, size);
        map->square_symmetry = FALSE;
    }
    else
        map->square_symmetry = TRUE;

    // Position (0,0) in the map is the minimum value
    // We "clamp" all the edges to 0
    // The maximum edge value is at (0,radius) or (radius,0) or (2*radius, radius) or (radius, 2*radius)
    offset = BELLD(CONST_E,2.0,1.5*DIST2(0,0,0,radius),radius);
    if (shape_data) { // square_symmetry == FALSE
        dlevel = ((gdouble) level)*dlevel/(100.0*(gdouble) MAX_HF_VALUE);
        // We intersect the gaussian bell (values from 0.0 to 1.0) with the pen tip shape
        for (x=0; x<size; x++)
            for (y=0; y<size; y++) {
                // Technique #1: gaussian bell on x axis, shape on y axis
                // A basic technique, giving, with sharps tips, straight lines when the stroke curves
                /*				*(map->data+VECTORIZE(x,y,size)) = (hf_type)
                					(dlevel * *(shape_data+y) *
                 					MAX(0.0, BELLD(e,2.0,1.5*ABS(radius-x),radius) - offset) );
                */
                // Technique #2: same as technique #1, but the shape
                // is emphasized only around the center
                // Towards the edges, we average it with a gaussian bell
                // in proportion with the square of the distance
                // Increasing the base to 10.0 shortens the shape
                // so that even with sharp tips, straight lines are invisible in stroke curves
                p = MAX(0.0, BELLD(10.0,2.0,1.5*ABS(radius-x),radius) - offset);
                *(map->data+VECTORIZE(x,y,size)) = (hf_type) (dlevel *
                                                   (p * *(shape_data+y) + (1.0-p) * MAX(0.0, BELLD(CONST_E,2.0,1.5*ABS(radius-y),radius) - offset) * maxd ) *
                                                   MAX(0.0, BELLD(CONST_E,2.0,1.5*ABS(radius-x),radius) - offset) );

            }
    }
    else {
        // Level is relative (50 means 50%)
        dlevel = ((gdouble) level)*dlevel/100.0;
        for (x=0; x<(radius+1); x++)
            for (y=0; y<(radius+1); y++) {
                ddist = (gdouble) DIST2(0,0,x,y);
                if (ddist >= radius)
                    *(map->data+VECTORIZE(radius-x,radius-y,radius+1)) = 0;
                else
                    *(map->data+VECTORIZE(radius-x,radius-y,radius+1)) =
                        (hf_type) (dlevel * MAX(0.0, BELLD(CONST_E,2.0,1.5*ddist,radius) - offset) );
//						 0x04FF; // TEST
            }
    }
    map->radius = radius;
    if (map->dr_buf)
        draw_buf_free(map->dr_buf);
    map->dr_buf = draw_buf_new (MULT_SIZE*size/DIV_SIZE);
    draw_buf_init (map, spacing);
    if (shape_data)
        free(shape_data);
}
Exemplo n.º 21
0
/** Check for bad overlaps. */
int Action_CheckStructure::CheckOverlap(int frameNum, Frame const& currentFrame, Topology const& top)
{
  double D2;
  Matrix_3x3 ucell, recip; // ToFrac, ToCart
  int nmask1, nmask2;
  int atom1, atom2;
  int Nproblems = 0;

  // Get imaging info for non-orthogonal box // TODO Check volume
  if (image_.ImageType()==NONORTHO)
    currentFrame.BoxCrd().ToRecip(ucell, recip);
  if ( Mask2_.MaskStringSet() ) {
    // Calculation of all atoms in Mask1 to all atoms in Mask2
    int outer_max = OuterMask_.Nselected();
    int inner_max = InnerMask_.Nselected();
#   ifdef _OPENMP
#   pragma omp parallel private(nmask1,nmask2,atom1,atom2,D2) reduction(+: Nproblems)
    {
    //mprintf("OPENMP: %i threads\n",omp_get_num_threads());
    //mythread = omp_get_thread_num();
#   pragma omp for
#   endif
    for (nmask1 = 0; nmask1 < outer_max; nmask1++) {
      atom1 = OuterMask_[nmask1];
      for (nmask2 = 0; nmask2 < inner_max; nmask2++) {
        atom2 = InnerMask_[nmask2];
        if (atom1 != atom2) {
          D2 = DIST2( currentFrame.XYZ(atom1), currentFrame.XYZ(atom2),
                      image_.ImageType(), currentFrame.BoxCrd(), ucell, recip);
          if (D2 < nonbondcut2_) {
            ++Nproblems;
            if (outfile_ != 0) {
#             ifdef _OPENMP
#             pragma omp critical
#             endif
              outfile_->Printf(
                    "%i\t Warning: Atoms %i:%s and %i:%s are close (%.2lf)\n", frameNum,
                    atom1+1, top.TruncResAtomName(atom1).c_str(),
                    atom2+1, top.TruncResAtomName(atom2).c_str(), sqrt(D2));
            }
          }
        }
      } // END loop over inner mask
    } // END loop over outer mask
#   ifdef _OPENMP
    } // END pragma omp parallel
#   endif
  } else {
    // Calculation of atoms in Mask1 to all other atoms in Mask1
    int mask1_max = Mask1_.Nselected();
#   ifdef _OPENMP
#   pragma omp parallel private(nmask1,nmask2,atom1,atom2,D2) reduction(+: Nproblems)
    {
    //mprintf("OPENMP: %i threads\n",omp_get_num_threads());
    //mythread = omp_get_thread_num();
#   pragma omp for schedule(dynamic)
#   endif
    for (nmask1 = 0; nmask1 < mask1_max; nmask1++) {
      atom1 = Mask1_[nmask1];
      for (nmask2 = nmask1 + 1; nmask2 < mask1_max; nmask2++) {
        atom2 = Mask1_[nmask2];
        D2 = DIST2( currentFrame.XYZ(atom1), currentFrame.XYZ(atom2),
                    image_.ImageType(), currentFrame.BoxCrd(), ucell, recip);
        if (D2 < nonbondcut2_) {
          ++Nproblems;
          if (outfile_ != 0) {
#           ifdef _OPENMP
#           pragma omp critical
#           endif
            outfile_->Printf(
                  "%i\t Warning: Atoms %i:%s and %i:%s are close (%.2lf)\n", frameNum,
                  atom1+1, top.TruncResAtomName(atom1).c_str(),
                  atom2+1, top.TruncResAtomName(atom2).c_str(), sqrt(D2));
          }
        }
      } // END inner loop over Mask1
    } // END outer loop over Mask1
#   ifdef _OPENMP
    } // END pragma omp parallel
#   endif
  }

  return Nproblems;
}