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; }
/* 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)); }
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; }
static int edgeLen (Agedge_t* e) { pointf p = ND_coord(agtail(e)); pointf q = ND_coord(aghead(e)); return (int)DIST2(p,q); }
/** 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); } }
/* 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"); }
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; }
/*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*/ }
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); }
// 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; }
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; }
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; }
/** 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; }
inline static bool is_near(float p1[3], float p2[3]) { return DIST2(p1,p2) < AOI_RADIS2 * 0.25f ; }
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"); } }
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; } }
inline static float dist2(struct object *p1, struct object *p2) { float d = DIST2(p1->position,p2->position); return d; }
// 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; }
// 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; }
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); }
/** 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; }