bool Segment::doesIntersect(const Segment &that, Point* intersectionPoint) const { const Vector r(this->b - this->a); const Vector s(that.b - that.a); const Vector thatAMinThisA(that.a - this->a); const double rCrossS(r.cross(s)); if (almost_equal(rCrossS, 0.)) { if (almost_equal(thatAMinThisA.cross(r), 0.)) { // colinear, check if overlap if (this->isDegenerate()) { if (that.isDegenerate()) { // both degenerate, are they equal? if (this->a == that.a) { // yes? intersection if (intersectionPoint) *intersectionPoint = a; return true; } return false; } else { // only this is degenerate, is it on that? if ((a.x >= fmin(that.a.x, that.b.x)) && (a.y >= fmin(that.a.y, that.b.y)) && (a.x <= fmax(that.a.x, that.b.x)) && (a.y <= fmax(that.a.y, that.b.y))) { // yes, intersection if (intersectionPoint) *intersectionPoint = a; return true; } return false; } } // both segments have non-zero length const Vector rOnNorm2(r / r.norm2()); const double t0(thatAMinThisA * rOnNorm2); const double t1(t0 + s * rOnNorm2); if (fmin(t0, t1) > 1) return false; if (fmax(t0, t1) < 0) return false; if (intersectionPoint) { // intersection is in the middle of the overlapping interval const double t0Clamped(fmax(fmin(t0, 1.), 0.)); const double t1Clamped(fmax(fmin(t1, 1.), 0.)); const double tMean((t0Clamped + t1Clamped) / 2); *intersectionPoint = a + r * tMean; } return true; } return false; } else { const double t(thatAMinThisA.cross(s) / rCrossS); const double u(thatAMinThisA.cross(r) / rCrossS); if (0 <= t && t <= 1 && 0 <= u && u <= 1) { if (intersectionPoint) *intersectionPoint = a + r * t; return true; } return false; } }
vector<SubstitutionalCorrelation*> correlators_from_cuns(ChemicalUnitNode* node1,ChemicalUnitNode* node2,vector<double> corr) { int s1 = node1->chemical_units.size(); int s2 = node2->chemical_units.size(); vector<double> correlations(s1*s2); //check there are enough numbers in the matrix //fill the correlations //if full version, check the last column-row bool full_version; if(corr.size()==(s1-1)*(s2-1)) { full_version = false; //fill upper-right corner of correlation matrix for(int i=0; i<s1-1; i++) for(int j=0; j<s2-1; j++) correlations[i+s1*j] = corr[i+j*(s1-1)]; } else if(corr.size()==s1*s2) { full_version = true; correlations = corr; } else { REPORT(ERROR) << "Wrong number of joint probabilities, expected a " << (s1-1)<< "x" << (s2-1) << " or a " << s1 << "x" << s2 << " matrix. Found " << corr.size() << " values.\n"; throw "fail"; } //fill last row for(int j=0; j<s2-1; j++){ correlations[s1*j+s1-1]=node2->chemical_units[j].get_occupancy(); for(int i=0; i<s1-1; i++) correlations[s1*j+s1-1]-=correlations[i+s1*j]; } //fill last coloumn for(int i=0; i<s1; i++) { correlations[(s2-1)*s1+i]=node1->chemical_units[i].get_occupancy(); for(int j=0; j<s2-1; j++) correlations[(s2-1)*s1+i] -= correlations[i+s1*j]; } if(full_version) for(int i=0; i<correlations.size(); ++i) if(!(almost_equal(corr[i],correlations[i]))){ REPORT(ERROR) << "The joint probabilities are incompatible with the average structure.\n"; throw "fail"; } //create correlations vector<SubstitutionalCorrelation*> res; for(int j=0; j<s2; j++) { for(int i=0; i<s1; i++) { res.push_back( new SubstitutionalCorrelation(& node1->chemical_units[i],& node2->chemical_units[j], correlations[i+s1*j])); } } return res; }
END_TEST START_TEST (test_reject_p2_n3_c4) { int i; s_array * paths; c_array * line_buffer; i_array * stat_indices; d_array * obs_stats; d_array * means; d_array * std_devs; s_array * header; sample_array * samples; int num_to_retain; num_to_retain = 3; paths = init_s_array(1); line_buffer = init_c_array(1023); stat_indices = init_i_array(4); means = init_d_array(1); std_devs = init_d_array(1); obs_stats = init_d_array(1); header = init_s_array(1); append_s_array(paths, "data/test_parameter_stat_samples4.txt"); append_s_array(paths, "data/test_parameter_stat_samples.txt"); parse_header(get_s_array(paths, 0), line_buffer, header); for (i = 2; i < header->length; i++) { append_i_array(stat_indices, i); } append_d_array(obs_stats, 0.1); append_d_array(obs_stats, 0.21); append_d_array(obs_stats, 1.0); append_d_array(obs_stats, 2.0); append_d_array(means, 0.25); append_d_array(means, 0.2225); append_d_array(means, 2.5); append_d_array(means, 3.0); append_d_array(std_devs, 0.1290994); append_d_array(std_devs, 0.009574271); append_d_array(std_devs, 1.290994); append_d_array(std_devs, 1.154701); standardize_vector(obs_stats, means, std_devs); samples = reject(paths, line_buffer, stat_indices, obs_stats, means, std_devs, num_to_retain, header); ck_assert_int_eq(samples->length, num_to_retain); ck_assert_int_eq(samples->capacity, num_to_retain); ck_assert_msg((almost_equal(samples->a[0]->distance, 0.0, 0.000001)), "euclidean distance was %lf, expected %lf", samples->a[0]->distance, 0.0); ck_assert_msg((almost_equal(samples->a[1]->distance, 0.130035, 0.000001)), "euclidean distance was %lf, expected %lf", samples->a[1]->distance, 0.130035); ck_assert_msg((almost_equal(samples->a[2]->distance, 0.1433004, 0.000001)), "euclidean distance was %lf, expected %lf", samples->a[2]->distance, 0.1433004); free_s_array(paths); free_c_array(line_buffer); free_i_array(stat_indices); free_d_array(obs_stats); free_sample_array(samples); free_d_array(means); free_d_array(std_devs); free_s_array(header); }