void solve(int u) { rt = 0; ff[0] = size; find_center(u, -1); u = rt; tot = sum = 0; get_order(u, -1); for(int i = 0; i <= tot; ++i) for(int j = 0; j <= sum; ++j) f[i][j] = 0; f[0][0] = 1; sum = 0; for(int i = 0; i < tot; ++i) { DB pr = (DB)p[seq[i]] / 100; for(int j = 0; j <= sum; ++j) { if(i) f[nxt[i]][j] += f[i][j]; f[i + 1][j] += f[i][j] * (1 - pr); f[i + 1][j + w[seq[i]]] += f[i][j] * pr; } sum += w[seq[i]]; } for(int i = 0; i <= sum; ++i) s[i] += f[tot][i]; vis[u] = 1; for(std::vector<int>::iterator it = e[u].begin(); it != e[u].end(); ++it) { int v = *it; if(!vis[v]) { size = sz[v]; solve(v); } } }
// 当数据量太大的时候,递归会导致栈溢出,最好用非递归的形式实现快排 void quick_sort(int a[], int left, int right) { if( left < right) { int center = find_center(a, left, right); quick_sort(a, left, center); quick_sort(a, center+1, right); } }
void find_center(int u, int fa) { sz[u] = 1; ff[u] = 0; for(std::vector<int>::iterator it = e[u].begin(); it != e[u].end(); ++it) { int v = *it; if(!vis[v] && v != fa) { find_center(v, u); sz[u] += sz[v]; ff[u] = std::max(ff[u], sz[v]); } } ff[u] = std::max(ff[u], size - sz[u]); if(ff[u] < ff[rt]) rt = u; }
long double minimum_enclosing_circle(polygon_t &convex_hull) { if (convex_hull.size() <= 1) return 0; if (convex_hull.size() == 2) return distance_square(convex_hull[0], convex_hull[1]) / 4.0; point_t s_a = convex_hull[0]; point_t s_b = convex_hull[1]; while (1) { long double alpha = 100; point_t v; for (polygon_t::iterator p = convex_hull.begin(); p != convex_hull.end(); p++) { if (*p == s_a || *p == s_b) continue; long double a = angle(*p, s_a, s_b); if (a < alpha) { alpha = a; v = *p; } } if (alpha >= M_PI / 2) return distance_square(s_a, s_b) / 4.0; // printf("s_a:(%ld, %ld) s_b:(%ld, %ld) v:(%ld, %ld)\n", s_a.first, s_a.second, s_b.first, s_b.second, v.first, v.second); // printf("angle v-s_a-s_b: %Lf\n", angle(s_a, v, s_b)); if (angle(s_a, v, s_b) >= M_PI / 2) { s_a = v; continue; } // printf("angle v-s_b-s_a: %Lf\n", angle(s_b, v, s_a)); if (angle(s_b, v, s_a) >= M_PI / 2) { s_b = v; continue; } /* v, s_a, s_b */ fpoint_t center = find_center(v, s_a, s_b); // printf("center: %Lf, %Lf\n", center.first, center.second); // printf("%Lf = %Lf, %Lf\n", distance_square(center, v), distance_square(center, s_a), distance_square(center, s_b)); return distance_square(center, v); } }
bool featureextraction::findMarker02(cv::Mat &img, std::vector<cv::Point> &points, bool constraintTime, double maxprocessingtime){ std::chrono::high_resolution_clock::time_point start; start = std::chrono::high_resolution_clock::now(); cv::Mat imghsv = img.clone(); cv::Mat white; cv::cvtColor(img, imghsv, CV_BGR2HSV); cv::inRange(imghsv, cv::Scalar(0, 0, 127), cv::Scalar(180,50,255), white); std::vector<std::vector<cv::Point> > contours; std::vector<std::vector<cv::Point> > good_contours; points.clear(); std::vector<cv::Point> center = find_blobs(white, contours, good_contours); if(constraintTime){ std::chrono::high_resolution_clock::time_point now; now = std::chrono::high_resolution_clock::now(); double runTime = std::chrono::duration_cast<std::chrono::duration<double>>(now - start).count(); if(runTime > maxprocessingtime){ return false; } } cv::Point midpoint = find_center(img, center, good_contours); if(midpoint.x == 0 && midpoint.y == 0){ return false; } else { midpoint.x -= img.cols / 2; midpoint.y = img.rows / 2 - midpoint.y; points.push_back(midpoint); return true; } }
// Uses a variant of the bounded harmonic mean approximation to determine the evidence. // Essentially, the regulator chosen is an ellipsoid with radius nsigma standard deviations // along each principal axis. The regulator is then 1/V inside the ellipsoid and 0 without, // where V is the volume of the ellipsoid. In this form, the harmonic mean approximation // has finite variance. See Gelfand & Dey (1994) and Robert & Wraith (2009) for details. double TChain::get_ln_Z_harmonic(bool use_peak, double nsigma_max, double nsigma_peak, double chain_frac) const { // Get the covariance and determinant of the chain gsl_matrix* Sigma = gsl_matrix_alloc(N, N); gsl_matrix* invSigma = gsl_matrix_alloc(N, N); double detSigma; stats.get_cov_matrix(Sigma, invSigma, &detSigma); // Determine the center of the prior volume to use double* mu = new double[N]; if(use_peak) { // Use the peak density as the center find_center(mu, Sigma, invSigma, &detSigma, nsigma_peak, 5); //density_peak(mu, nsigma_peak); } else { // Get the mean from the stats class for(unsigned int i=0; i<N; i++) { mu[i] = stats.mean(i); } } // Sort elements in chain by distance from center, filtering out values of L which are not finite std::vector<TChainSort> sorted_indices; sorted_indices.reserve(length); unsigned int filt_length = 0; for(unsigned int i=0; i<length; i++) { if(!(isnan(L[i]) || is_inf_replacement(L[i]))) { TChainSort tmp_el; tmp_el.index = i; tmp_el.dist2 = metric_dist2(invSigma, get_element(i), mu, N); sorted_indices.push_back(tmp_el); filt_length++; } } unsigned int npoints = (unsigned int)(chain_frac * (double)filt_length); std::partial_sort(sorted_indices.begin(), sorted_indices.begin() + npoints, sorted_indices.end()); // Determine <1/L> inside the prior volume double sum_invL = 0.; double tmp_invL; double nsigma = sqrt(sorted_indices[npoints-1].dist2); unsigned int tmp_index = sorted_indices[0].index;; double L_0 = L[tmp_index]; //std::cout << "index_0 = " << sorted_indices[0].index << std::endl; for(unsigned int i=0; i<npoints; i++) { if(sorted_indices[i].dist2 > nsigma_max * nsigma_max) { nsigma = nsigma_max; break; } tmp_index = sorted_indices[i].index; tmp_invL = w[tmp_index] / exp(L[tmp_index] - L_0); //std::cout << w[tmp_index] << ", " << L[tmp_index] << std::endl; //if(isnan(tmp_invL)) { // std::cout << "\t\tL, L_0 = " << L[tmp_index] << ", " << L_0 << std::endl; //} if((tmp_invL + sum_invL > 1.e100) && (i != 0)) { nsigma = sqrt(sorted_indices[i-1].dist2); break; } sum_invL += tmp_invL; } // Determine the volume normalization (the prior volume) double V = sqrt(detSigma) * 2. * pow(SQRTPI * nsigma, (double)N) / (double)(N) / gsl_sf_gamma((double)(N)/2.); // Return an estimate of ln(Z) double lnZ = log(V) - log(sum_invL) + log(total_weight) + L_0; if(isnan(lnZ)) { std::cout << std::endl; std::cout << "NaN Error! lnZ = " << lnZ << std::endl; std::cout << "\tsum_invL = e^(" << -L_0 << ") * " << sum_invL << " = " << exp(-L_0) * sum_invL << std::endl; std::cout << "\tV = " << V << std::endl; std::cout << "\ttotal_weight = " << total_weight << std::endl; std::cout << std::endl; } else if(is_inf_replacement(lnZ)) { std::cout << std::endl; std::cout << "inf Error! lnZ = " << lnZ << std::endl; std::cout << "\tsum_invL = e^(" << -L_0 << ") * " << sum_invL << " = " << exp(-L_0) * sum_invL << std::endl; std::cout << "\tV = " << V << std::endl; std::cout << "\ttotal_weight = " << total_weight << std::endl; std::cout << "\tnsigma = " << nsigma << std::endl; std::cout << "\tIndex\tDist^2:" << std::endl; for(unsigned int i=0; i<10; i++) { std::cout << sorted_indices[i].index << "\t\t" << sorted_indices[i].dist2 << std::endl; std::cout << " "; const double *tmp_x = get_element(sorted_indices[i].index); for(unsigned int k=0; k<N; k++) { std::cout << " " << tmp_x[k]; } std::cout << std::endl; } std::cout << "mu ="; for(unsigned int i=0; i<N; i++) { std::cout << " " << mu[i]; } std::cout << std::endl; } // Cleanup gsl_matrix_free(Sigma); gsl_matrix_free(invSigma); delete[] mu; return lnZ; }
// // Add ghost cells // void MeshAddGhostCells(const string& GridType, cart2d& cart2dinfo, int& numpts, int& numtri, int& numghost, int& num_ext_node, point*& p, triangle*& t, double*& area, double*& cdual, int*& ghost_link, int*& proper_ghostcell, int*& ext_node_link, double (*SignedDistance)(point)) { int i,j; int k = 0; int mfound = 0; int jstore[4]; double x,y; int tmp[4]; point ptmp; point A,B,C,nvec,Anew,v12,v23,v31; double BCnorm,nvec_norm; int tmps,temp,kcheck; point alpha,beta; double alpha_norm,beta_norm,theta_alpha,theta_beta; int jopp; point pnew[2*numpts]; triangle tnew[2*numtri]; double area_new[2*numtri]; double cdual_new[2*numpts]; int ghost_link_new[2*numtri]; int numghost_new = 0; int numpts_new = numpts; int numtri_new = numtri; int ext_new[2*numtri]; int num_ext = 0; // for periodic boundary conditions int* centers_index_tmp = new int[2*numtri]; double* centers_xy_tmp = new double[2*numtri]; int num_centers = 0; const double olx = 1.0/(cart2dinfo.xhigh-cart2dinfo.xlow); const double oly = 1.0/(cart2dinfo.yhigh-cart2dinfo.ylow); // Compute the minimal distance parameter hmin double min_parea = 1.0e10; for (i=0; i<numtri; i++) { if (min_parea > area[i]) { min_parea = area[i]; } } double hmin = sqrt(2.0*min_parea)/5.0e0; // Store old t,area,p,cdual in new versions of each for (i=0; i<numtri; i++) { tnew[i].n1 = t[i].n1; tnew[i].n2 = t[i].n2; tnew[i].n3 = t[i].n3; area_new[i] = area[i]; } for (i=0; i<numpts; i++) { pnew[i].x = p[i].x; pnew[i].y = p[i].y; cdual_new[i] = cdual[i]; } // Loop over every element in order to determine // if a ghost cell should be created for (i=0; i<numtri; i++) { mfound = 0; jstore[1] = 0; jstore[2] = 0; jstore[3] = 0; // Look at ith element tmp[1] = t[i].n1; tmp[2] = t[i].n2; tmp[3] = t[i].n3; // Check how many nodes of ith element lie on the boundary (either 0, 1, 2, or 3) // If there are 0 or 1 nodes on the bnd, then do nothing and proceed to next element for (j=1; j<=3; j++) { ptmp.x = p[tmp[j]].x; ptmp.y = p[tmp[j]].y; if (fabs(SignedDistance(ptmp))<=hmin) { mfound = mfound + 1; jstore[mfound] = j; } else { A.x = ptmp.x; A.y = ptmp.y; jopp = tmp[j]; } } // Exactly three nodes of a triangle are on the boundary // NOTE: 3 nodes on boundary <==> exactly two edges are boundary edges // (assuming the mesh has more than 1 element and these elements are connected) if (mfound==3) { kcheck = 0; // check if edge 12 is on the boundary ptmp.x = 0.5*( p[tmp[1]].x + p[tmp[2]].x ); ptmp.y = 0.5*( p[tmp[1]].y + p[tmp[2]].y ); if (fabs(SignedDistance(ptmp))<=hmin) { kcheck=kcheck+1; jstore[1] = 1; jstore[2] = 2; jstore[3] = 3; A.x = p[tmp[jstore[3]]].x; A.y = p[tmp[jstore[3]]].y; B.x = p[tmp[jstore[1]]].x; B.y = p[tmp[jstore[1]]].y; C.x = p[tmp[jstore[2]]].x; C.y = p[tmp[jstore[2]]].y; Anew.x = B.x + C.x - A.x; Anew.y = B.y + C.y - A.y; // Add new node and corresponding new element numtri_new = numtri_new+1; numpts_new = numpts_new+1; pnew[numpts_new-1].x = Anew.x; pnew[numpts_new-1].y = Anew.y; tnew[numtri_new-1].n1 = tmp[jstore[1]]; tnew[numtri_new-1].n2 = tmp[jstore[2]]; tnew[numtri_new-1].n3 = numpts_new-1; // New node link to old node num_ext = num_ext+1; ext_new[num_ext-1] = tmp[jstore[3]]; // Add ghost index; numghost_new = numghost_new+1; ghost_link_new[numghost_new-1] = i; // Center information - to be used for periodic BCs num_centers = num_centers + 1; centers_index_tmp[num_centers-1] = i; double x1 = A.x; double x2 = B.x; double x3 = C.x; double y1 = A.y; double y2 = B.y; double y3 = C.y; centers_xy_tmp[num_centers-1] = olx*(onethird*(x1+x2+x3)-cart2dinfo.xlow) + 1000.0*oly*(onethird*(y1+y2+y3)-cart2dinfo.ylow); // Compute signed element area, change orientation if necessary v12.x = pnew[tnew[numtri_new-1].n2].x - pnew[tnew[numtri_new-1].n1].x; v12.y = pnew[tnew[numtri_new-1].n2].y - pnew[tnew[numtri_new-1].n1].y; v23.x = pnew[tnew[numtri_new-1].n3].x - pnew[tnew[numtri_new-1].n2].x; v23.y = pnew[tnew[numtri_new-1].n3].y - pnew[tnew[numtri_new-1].n2].y; v31.x = pnew[tnew[numtri_new-1].n1].x - pnew[tnew[numtri_new-1].n3].x; v31.y = pnew[tnew[numtri_new-1].n1].y - pnew[tnew[numtri_new-1].n3].y; area_new[numtri_new-1] = .5*(pnew[tnew[numtri_new-1].n1].x * (pnew[tnew[numtri_new-1].n2].y -pnew[tnew[numtri_new-1].n3].y) + pnew[tnew[numtri_new-1].n2].x * (pnew[tnew[numtri_new-1].n3].y -pnew[tnew[numtri_new-1].n1].y) + pnew[tnew[numtri_new-1].n3].x * (pnew[tnew[numtri_new-1].n1].y -pnew[tnew[numtri_new-1].n2].y)); if (area_new[numtri_new-1] < 0.0) { temp = tnew[numtri_new-1].n2; tnew[numtri_new-1].n2 = tnew[numtri_new-1].n3; tnew[numtri_new-1].n3 = temp; area_new[numtri_new-1] = fabs(area_new[numtri_new-1]); } // Add element area to the appropriate dual cell area cdual_new[tnew[numtri_new-1].n1] += (area_new[numtri_new-1]/3.0); cdual_new[tnew[numtri_new-1].n2] += (area_new[numtri_new-1]/3.0); cdual_new[tnew[numtri_new-1].n3] += (area_new[numtri_new-1]/3.0); } // check if edge 13 is on the boundary ptmp.x = 0.5*( p[tmp[1]].x + p[tmp[3]].x ); ptmp.y = 0.5*( p[tmp[1]].y + p[tmp[3]].y ); if (fabs(SignedDistance(ptmp))<=hmin) { kcheck=kcheck+1; jstore[1] = 3; jstore[2] = 1; jstore[3] = 2; A.x = p[tmp[jstore[3]]].x; A.y = p[tmp[jstore[3]]].y; B.x = p[tmp[jstore[1]]].x; B.y = p[tmp[jstore[1]]].y; C.x = p[tmp[jstore[2]]].x; C.y = p[tmp[jstore[2]]].y; Anew.x = B.x + C.x - A.x; Anew.y = B.y + C.y - A.y; // Add new node and corresponding new element numtri_new = numtri_new+1; numpts_new = numpts_new+1; pnew[numpts_new-1].x = Anew.x; pnew[numpts_new-1].y = Anew.y; tnew[numtri_new-1].n1 = tmp[jstore[1]]; tnew[numtri_new-1].n2 = tmp[jstore[2]]; tnew[numtri_new-1].n3 = numpts_new-1; // New node link to old node num_ext = num_ext+1; ext_new[num_ext-1] = tmp[jstore[3]]; // Add ghost index; numghost_new = numghost_new+1; ghost_link_new[numghost_new-1] = i; // Center information - to be used for periodic BCs num_centers = num_centers + 1; centers_index_tmp[num_centers-1] = i; double x1 = A.x; double x2 = B.x; double x3 = C.x; double y1 = A.y; double y2 = B.y; double y3 = C.y; centers_xy_tmp[num_centers-1] = olx*(onethird*(x1+x2+x3)-cart2dinfo.xlow) + 1000.0*oly*(onethird*(y1+y2+y3)-cart2dinfo.ylow); // Compute signed element area, change orientation if necessary v12.x = pnew[tnew[numtri_new-1].n2].x - pnew[tnew[numtri_new-1].n1].x; v12.y = pnew[tnew[numtri_new-1].n2].y - pnew[tnew[numtri_new-1].n1].y; v23.x = pnew[tnew[numtri_new-1].n3].x - pnew[tnew[numtri_new-1].n2].x; v23.y = pnew[tnew[numtri_new-1].n3].y - pnew[tnew[numtri_new-1].n2].y; v31.x = pnew[tnew[numtri_new-1].n1].x - pnew[tnew[numtri_new-1].n3].x; v31.y = pnew[tnew[numtri_new-1].n1].y - pnew[tnew[numtri_new-1].n3].y; area_new[numtri_new-1] = .5*(pnew[tnew[numtri_new-1].n1].x * (pnew[tnew[numtri_new-1].n2].y -pnew[tnew[numtri_new-1].n3].y) + pnew[tnew[numtri_new-1].n2].x * (pnew[tnew[numtri_new-1].n3].y -pnew[tnew[numtri_new-1].n1].y) + pnew[tnew[numtri_new-1].n3].x * (pnew[tnew[numtri_new-1].n1].y -pnew[tnew[numtri_new-1].n2].y)); if (area_new[numtri_new-1] < 0.0) { temp = tnew[numtri_new-1].n2; tnew[numtri_new-1].n2 = tnew[numtri_new-1].n3; tnew[numtri_new-1].n3 = temp; area_new[numtri_new-1] = fabs(area_new[numtri_new-1]); } // Add element area to the appropriate dual cell area cdual_new[tnew[numtri_new-1].n1] += (area_new[numtri_new-1]/3.0); cdual_new[tnew[numtri_new-1].n2] += (area_new[numtri_new-1]/3.0); cdual_new[tnew[numtri_new-1].n3] += (area_new[numtri_new-1]/3.0); } // check if edge 23 is on the boundary ptmp.x = 0.5*( p[tmp[2]].x + p[tmp[3]].x ); ptmp.y = 0.5*( p[tmp[2]].y + p[tmp[3]].y ); if (fabs(SignedDistance(ptmp))<=hmin) { kcheck=kcheck+1; jstore[1] = 2; jstore[2] = 3; jstore[3] = 1; A.x = p[tmp[jstore[3]]].x; A.y = p[tmp[jstore[3]]].y; B.x = p[tmp[jstore[1]]].x; B.y = p[tmp[jstore[1]]].y; C.x = p[tmp[jstore[2]]].x; C.y = p[tmp[jstore[2]]].y; Anew.x = B.x + C.x - A.x; Anew.y = B.y + C.y - A.y; // Add new node and corresponding new element numtri_new = numtri_new+1; numpts_new = numpts_new+1; pnew[numpts_new-1].x = Anew.x; pnew[numpts_new-1].y = Anew.y; tnew[numtri_new-1].n1 = tmp[jstore[1]]; tnew[numtri_new-1].n2 = tmp[jstore[2]]; tnew[numtri_new-1].n3 = numpts_new-1; // New node link to old node num_ext = num_ext+1; ext_new[num_ext-1] = tmp[jstore[3]]; // Add ghost index; numghost_new = numghost_new+1; ghost_link_new[numghost_new-1] = i; // Center information - to be used for periodic BCs num_centers = num_centers + 1; centers_index_tmp[num_centers-1] = i; double x1 = A.x; double x2 = B.x; double x3 = C.x; double y1 = A.y; double y2 = B.y; double y3 = C.y; centers_xy_tmp[num_centers-1] = olx*(onethird*(x1+x2+x3)-cart2dinfo.xlow) + 1000.0*oly*(onethird*(y1+y2+y3)-cart2dinfo.ylow); // Compute signed element area, change orientation if necessary v12.x = pnew[tnew[numtri_new-1].n2].x - pnew[tnew[numtri_new-1].n1].x; v12.y = pnew[tnew[numtri_new-1].n2].y - pnew[tnew[numtri_new-1].n1].y; v23.x = pnew[tnew[numtri_new-1].n3].x - pnew[tnew[numtri_new-1].n2].x; v23.y = pnew[tnew[numtri_new-1].n3].y - pnew[tnew[numtri_new-1].n2].y; v31.x = pnew[tnew[numtri_new-1].n1].x - pnew[tnew[numtri_new-1].n3].x; v31.y = pnew[tnew[numtri_new-1].n1].y - pnew[tnew[numtri_new-1].n3].y; area_new[numtri_new-1] = .5*(pnew[tnew[numtri_new-1].n1].x * (pnew[tnew[numtri_new-1].n2].y -pnew[tnew[numtri_new-1].n3].y) + pnew[tnew[numtri_new-1].n2].x * (pnew[tnew[numtri_new-1].n3].y -pnew[tnew[numtri_new-1].n1].y) + pnew[tnew[numtri_new-1].n3].x * (pnew[tnew[numtri_new-1].n1].y -pnew[tnew[numtri_new-1].n2].y)); if (area_new[numtri_new-1] < 0.0) { temp = tnew[numtri_new-1].n2; tnew[numtri_new-1].n2 = tnew[numtri_new-1].n3; tnew[numtri_new-1].n3 = temp; area_new[numtri_new-1] = fabs(area_new[numtri_new-1]); } // Add element area to the appropriate dual cell area cdual_new[tnew[numtri_new-1].n1] += (area_new[numtri_new-1]/3.0); cdual_new[tnew[numtri_new-1].n2] += (area_new[numtri_new-1]/3.0); cdual_new[tnew[numtri_new-1].n3] += (area_new[numtri_new-1]/3.0); } if (kcheck!=2) { cout << endl; cout << " ERROR in MeshAddGhostCells.cpp: " << endl; cout << " Found a triangle with 3 nodes on the boundary." << endl; cout << " This triangle should have exactly 2 edges on the boundary," << endl; cout << " but in fact it has " << kcheck << endl; cout << endl; exit(1); } } // Exactly two nodes of a triangle are on the boundary // NOTE: 2 nodes on boundary <==> either exactly one edge is a boundary edge -or- // near a corner and exactly zero edges are a bnd edge else if (mfound==2) { // Compute edge midpoint ptmp.x = 0.5*( p[tmp[jstore[1]]].x + p[tmp[jstore[2]]].x ); ptmp.y = 0.5*( p[tmp[jstore[1]]].y + p[tmp[jstore[2]]].y ); // Proceed if edge midpoint is also on the bnd <==> exactly one edge is a bnd edge if (fabs(SignedDistance(ptmp))<=hmin) { if (jstore[1]>jstore[2]) { tmps = jstore[2]; jstore[2] = jstore[1]; jstore[1] = tmps; } B.x = p[tmp[jstore[1]]].x; B.y = p[tmp[jstore[1]]].y; C.x = p[tmp[jstore[2]]].x; C.y = p[tmp[jstore[2]]].y; Anew.x = B.x + C.x - A.x; Anew.y = B.y + C.y - A.y; // Add new node and corresponding new element numtri_new = numtri_new+1; numpts_new = numpts_new+1; pnew[numpts_new-1].x = Anew.x; pnew[numpts_new-1].y = Anew.y; tnew[numtri_new-1].n1 = tmp[jstore[1]]; tnew[numtri_new-1].n2 = tmp[jstore[2]]; tnew[numtri_new-1].n3 = numpts_new-1; // New node link to old node num_ext = num_ext+1; ext_new[num_ext-1] = jopp;// tmp[jstore[3]]; // Add ghost index; numghost_new = numghost_new+1; ghost_link_new[numghost_new-1] = i; // Center information - to be used for periodic BCs num_centers = num_centers + 1; centers_index_tmp[num_centers-1] = i; double x1 = A.x; double x2 = B.x; double x3 = C.x; double y1 = A.y; double y2 = B.y; double y3 = C.y; centers_xy_tmp[num_centers-1] = olx*(onethird*(x1+x2+x3)-cart2dinfo.xlow) + 1000.0*oly*(onethird*(y1+y2+y3)-cart2dinfo.ylow); // Compute signed element area, change orientation if necessary v12.x = pnew[tnew[numtri_new-1].n2].x - pnew[tnew[numtri_new-1].n1].x; v12.y = pnew[tnew[numtri_new-1].n2].y - pnew[tnew[numtri_new-1].n1].y; v23.x = pnew[tnew[numtri_new-1].n3].x - pnew[tnew[numtri_new-1].n2].x; v23.y = pnew[tnew[numtri_new-1].n3].y - pnew[tnew[numtri_new-1].n2].y; v31.x = pnew[tnew[numtri_new-1].n1].x - pnew[tnew[numtri_new-1].n3].x; v31.y = pnew[tnew[numtri_new-1].n1].y - pnew[tnew[numtri_new-1].n3].y; area_new[numtri_new-1] = .5*(pnew[tnew[numtri_new-1].n1].x * (pnew[tnew[numtri_new-1].n2].y -pnew[tnew[numtri_new-1].n3].y) + pnew[tnew[numtri_new-1].n2].x * (pnew[tnew[numtri_new-1].n3].y -pnew[tnew[numtri_new-1].n1].y) + pnew[tnew[numtri_new-1].n3].x * (pnew[tnew[numtri_new-1].n1].y -pnew[tnew[numtri_new-1].n2].y)); if (area_new[numtri_new-1] < 0.0) { temp = tnew[numtri_new-1].n2; tnew[numtri_new-1].n2 = tnew[numtri_new-1].n3; tnew[numtri_new-1].n3 = temp; area_new[numtri_new-1] = fabs(area_new[numtri_new-1]); } // Add element area to the appropriate dual cell area cdual_new[tnew[numtri_new-1].n1] += (area_new[numtri_new-1]/3.0); cdual_new[tnew[numtri_new-1].n2] += (area_new[numtri_new-1]/3.0); cdual_new[tnew[numtri_new-1].n3] += (area_new[numtri_new-1]/3.0); } } } // Resize all appropriate vectors delete[] p; delete[] t; delete[] area; delete[] cdual; numpts = numpts_new; numtri = numtri_new; numghost = numghost_new; num_ext_node = num_ext; p = new point[numpts]; t = new triangle[numtri]; area = new double[numtri]; cdual = new double[numpts]; ghost_link = new int[numghost]; proper_ghostcell = new int[numghost]; ext_node_link = new int[num_ext]; for (i=0; i<numtri; i++) { t[i].n1 = tnew[i].n1; t[i].n2 = tnew[i].n2; t[i].n3 = tnew[i].n3; area[i] = area_new[i]; } for (i=0; i<numpts; i++) { p[i].x = pnew[i].x; p[i].y = pnew[i].y; cdual[i] = cdual_new[i]; } for (i=0; i<numghost; i++) { ghost_link[i] = ghost_link_new[i]; } for (i=0; i<numghost; i++) { proper_ghostcell[i] = 1; } for (i=0; i<num_ext; i++) { ext_node_link[i] = ext_new[i]; } // Apply periodic boundary conditions int* centers_index = new int[num_centers]; double* centers_xy = new double[num_centers]; bool* centers_found = new bool[num_centers]; for (i=0; i<num_centers; i++) { centers_index[i] = centers_index_tmp[i]; centers_xy[i] = centers_xy_tmp[i]; centers_found[i] = 0; } delete[] centers_index_tmp; delete[] centers_xy_tmp; const double lx = (cart2dinfo.xhigh-cart2dinfo.xlow); const double ly = (cart2dinfo.yhigh-cart2dinfo.ylow); for (i=0; i<numghost; i++) { int n1 = t[numtri-numghost+i].n1; int n2 = t[numtri-numghost+i].n2; int n3 = t[numtri-numghost+i].n3; double x1 = p[n1].x; double y1 = p[n1].y; double x2 = p[n2].x; double y2 = p[n2].y; double x3 = p[n3].x; double y3 = p[n3].y; double xc = modxy(onethird*(x1+x2+x3),cart2dinfo.xlow,cart2dinfo.xhigh,lx); double yc = modxy(onethird*(y1+y2+y3),cart2dinfo.ylow,cart2dinfo.yhigh,ly); double cent = olx*(xc-cart2dinfo.xlow) + 1000.0*oly*(yc-cart2dinfo.ylow); ghost_link[i] = find_center(num_centers,centers_index,centers_xy,cent); } }
partlist *getParticles(matrix *mat){ int i,j; int id_counter=0; int width,height; partlist *plist; if((plist = calloc(1,sizeof(partlist)))==NULL){ fprintf(stderr, "ident.c: getParticles(): Out of memory error.\n"); exit(1); } width=mat->width; height=mat->height; for(i=0; i<width; i++){ for(j=0; j<height; j++){ if(mat->vals[i][j] == 0){ continue; } particle *part; part = floodfill(mat,getid(&id_counter),i,j); find_center(part); find_radius(part); #ifndef USE_RADIUS_THRESH if(part->size > MAX_PART_SIZE){ //This if statement removes any particles that are too large or too small. freeParticle(part); continue; }else if(part->size < MIN_PART_SIZE){ freeParticle(part); continue; } #endif #ifdef USE_RADIUS_THRESH if(part->radius > RAD_MAX){ freeParticle(part); continue; }else if(part->radius < RAD_MIN){ freeParticle(part); continue; } #endif else if(part->x > mat->width-6){ freeParticle(part); continue; }else if(part->x < 5){ freeParticle(part); continue; }else if(part->y > mat->height-6){ freeParticle(part); continue; }else if(part->y < 5){ freeParticle(part); continue; }else{ pushParticle(plist,part); } } } return plist; }