std::vector<Point2D> merge_hull(std::vector<Point2D> set) { if(set.size() < 2) return set; if (set.size() <= SIZE) { return get_hull(set); } std::vector<Point2D> set1; set1.assign(set.begin(), set.begin() + set.size() / 2); std::vector<Point2D> set2; set2.assign(set.begin() + set.size() / 2 , set.end()); std::vector<Point2D> hull1 = merge_hull(set1); std::vector<Point2D> hull2 = merge_hull(set2); return merge(hull1, hull2); }
std::vector <int> ConvexHull2D::work() { //print_hull(_P, ch2d(_P, _size)); return get_hull(_P, ch2d(_P, _size)); }
//merging of 2 convex hulls std::vector<Point2D> merge(std::vector<Point2D> set1, std::vector<Point2D> set2) { Point2Df p; std::vector<Point2D> sum; int is_line1 = is_line(set1); int is_line2 = is_line(set2); if(!is_line1) { for(int i = 0; i < set1.size() - 2; i++) { if(is_left(set1[i], set1[i + 1], set1[i + 2]) != 0) { p = centroid(set1[i], set1[i + 1], set1[i + 2]); break; } } } else if(!is_line2) { for(int i = 0; i < set2.size() - 2; i++) { if(is_left(set2[i], set2[i + 1], set2[i + 2]) != 0) { p = centroid(set2[i], set2[i + 1], set2[i + 2]); break; } } } if(!is_line1 && !is_line2)// 2 polygons { if(in_polygon(set2, p) != 0) { sum = merge_polygons(set1, set2, p); return graham_scan(sum); } else { std::vector<Point2D> clean_set2; clean_set2 = delete_chain(set2, p); sum = merge_polygons(set1, clean_set2, p); return graham_scan(sum); } } else if (!is_line1 && is_line2)//polygon with centroid p and line { std::vector<Point2D> clean_set2; /* clean_set2 = delete_chain(set2, p); sum = merge_polygons(set1, clean_set2, p); */ if(angle_compare(p, (Point2Df)set2[0], (Point2Df)set2[set2.size() - 1])) { clean_set2.push_back(set2[0]); clean_set2.push_back(set2[set2.size() - 1]); } else { clean_set2.push_back(set2[set2.size() - 1]); clean_set2.push_back(set2[0]); } sum = merge_polygons(set1, clean_set2, p); return graham_scan(sum); } else if(is_line1 && !is_line2) { std::vector<Point2D> clean_set1; /* clean_set1 = delete_chain(set1, p); sum = merge_polygons(clean_set1, set2, p); */ if(angle_compare(p, (Point2Df)set1[0], (Point2Df)set1[set1.size() - 1])) { clean_set1.push_back(set1[0]); clean_set1.push_back(set1[set1.size() - 1]); } else { clean_set1.push_back(set1[set1.size() - 1]); clean_set1.push_back(set1[0]); } sum = merge_polygons(clean_set1, set2, p); return graham_scan(sum); } else // if(is_line1 && is_line2) { std::vector<Point2D> clean_set1; clean_set1.push_back(set1[0]); clean_set1.push_back(set1[set1.size() - 1]); clean_set1.push_back(set2[0]); clean_set1.push_back(set2[set2.size() - 1]); return get_hull(clean_set1); } }