void divide_and_conquer(const pointVec_t &P, pointVec_t &H, point_t p1, point_t p2, bool buffered) { assert(P.size() >= 2); pointVec_t P_reduced; pointVec_t H1, H2; point_t p_far; if(buffered) { p_far = divide<SplitByCP_buf>(P, P_reduced, p1, p2); } else { p_far = divide<SplitByCP>(P, P_reduced, p1, p2); } if (P_reduced.size()<2) { H.push_back(p1); #if USECONCVEC appendVector(P_reduced, H); #else // insert into STD::VECTOR H.insert(H.end(), P_reduced.begin(), P_reduced.end()); #endif } else { divide_and_conquer(P_reduced, H1, p1, p_far, buffered); divide_and_conquer(P_reduced, H2, p_far, p2, buffered); #if USECONCVEC appendVector(H1, H); appendVector(H2, H); #else // insert into STD::VECTOR H.insert(H.end(), H1.begin(), H1.end()); H.insert(H.end(), H2.begin(), H2.end()); #endif } }
void convex_hull(std::vector<Point> &points) { // sort points by x std::sort(points.begin(), points.end()); // points to return std::vector<Point> ret; Point pointL = points.front(); Point pointR = points.back(); ret.push_back(pointL); ret.push_back(pointR); // Line of points has max and min x. Line L(pointL, pointR); // points in positive or negative side of L std::vector<Point> pos; std::vector<Point> neg; // max distances and points in both sides. double pos_max_dist = -std::numeric_limits<double>::infinity(); double neg_max_dist = -std::numeric_limits<double>::infinity(); Point pos_max_point(0, 0); Point neg_max_point(0, 0); for(auto &point : points) { double dist = L.distance(point); if(L.value(point) > 0) { pos.push_back(point); if(dist > pos_max_dist) { pos_max_dist = dist; pos_max_point = point; } } else if(L.value(point) < 0) { neg.push_back(point); if(dist > neg_max_dist) { neg_max_dist = dist; neg_max_point = point; } } } //if pos or neg side has any points, divide. if(pos.size() > 0) { ret.push_back(pos_max_point); std::vector<Point> pos_hull = divide_and_conquer(Triangle(pointL, pointR, pos_max_point), pos); ret.insert(ret.end(), pos_hull.begin(), pos_hull.end()); } if(neg.size() > 0) { // if neg side has any points, divide. ret.push_back(neg_max_point); std::vector<Point> neg_hull = divide_and_conquer(Triangle(pointL, pointR, neg_max_point), neg); ret.insert(ret.end(), neg_hull.begin(), neg_hull.end()); } std::sort(ret.begin(), ret.end(), [&](Point p, Point q) { return p.index() < q.index(); }); // sort by index ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); // make indecies unique. // output printf("%d\n", (int)ret.size()); for(auto i : ret) printf("%d\n", i.index()); }
std::vector<Point> divide_and_conquer(Triangle triangle, std::vector<Point> &points) { std::vector<Point> ret; std::vector<Point> l_points; std::vector<Point> r_points; std::vector<Point> l_line; std::vector<Point> r_line; double l_max_dist = -std::numeric_limits<double>::infinity(); double r_max_dist = -std::numeric_limits<double>::infinity(); Point l_max_point(0, 0); Point r_max_point(0, 0); double dist; for(auto &point : points) { if(triangle.left().value(point) == 0) // point is on the left side l_line.push_back(point); else if(triangle.right().value(point) == 0) // point is on the right side r_line.push_back(point); else if(triangle.isInside(point)) // point is inside the triangle continue; else if(point.x() < triangle.t_vertex().x()) { // point is in the left l_points.push_back(point); dist = triangle.left().distance(point); if(dist > l_max_dist) { l_max_dist = dist; l_max_point = point; } } else if(point.x() > triangle.t_vertex().x()) { // point is in the right r_points.push_back(point); dist = triangle.right().distance(point); if(dist > r_max_dist) { r_max_dist = dist; r_max_point = point; } } } if(l_points.size() > 0) { // left side has point(s), divide. ret.push_back(l_max_point); std::vector<Point> l_hull = divide_and_conquer(Triangle(triangle.l_vertex(), triangle.t_vertex(), l_max_point), l_points); ret.insert(ret.end(), l_hull.begin(), l_hull.end()); } else ret.insert(ret.end(), l_line.begin(), l_line.end()); if(r_points.size() > 0) { // right side has point(s), divide. ret.push_back(r_max_point); std::vector<Point> r_hull = divide_and_conquer(Triangle(triangle.t_vertex(), triangle.r_vertex(), r_max_point), r_points); ret.insert(ret.end(), r_hull.begin(), r_hull.end()); } else ret.insert(ret.end(), r_line.begin(), r_line.end()); return ret; }
void quickhull(const pointVec_t &points, pointVec_t &hull) { if (points.size() < 2) { hull.insert(hull.end(), points.begin(), points.end()); return; } point_t p_maxx = extremum<FindXExtremum::maxX>(points); point_t p_minx = extremum<FindXExtremum::minX>(points); pointVec_t H; divide_and_conquer(points, hull, p_maxx, p_minx); divide_and_conquer(points, H, p_minx, p_maxx); hull.insert(hull.end(), H.begin(), H.end()); }
void quickhull(const pointVec_t &points, pointVec_t &hull) { if (points.size() < 2) { appendVector(points, hull); return; } point_t p_maxx = extremum<FindXExtremum::maxX>(points); point_t p_minx = extremum<FindXExtremum::minX>(points); pointVec_t H; divide_and_conquer(points, hull, p_maxx, p_minx); divide_and_conquer(points, H, p_minx, p_maxx); appendVector(H, hull); }
void divide_and_conquer(const pointVec_t &P, pointVec_t &H, point_t p1, point_t p2) { assert(P.size() >= 2); pointVec_t P_reduced; pointVec_t H1, H2; point_t p_far = divide(P, P_reduced, p1, p2); if (P_reduced.size()<2) { H.push_back(p1); H.insert(H.end(), P_reduced.begin(), P_reduced.end()); } else { divide_and_conquer(P_reduced, H1, p1, p_far); divide_and_conquer(P_reduced, H2, p_far, p2); H.insert(H.end(), H1.begin(), H1.end()); H.insert(H.end(), H2.begin(), H2.end()); } }
void divide_and_conquer(const pointVec_t &P, pointVec_t &H, point_t p1, point_t p2) { assert(P.size() >= 2); pointVec_t P_reduced; pointVec_t H1, H2; point_t p_far = divide(P, P_reduced, p1, p2); if (P_reduced.size()<2) { H.push_back(p1); appendVector(P_reduced, H); } else { divide_and_conquer(P_reduced, H1, p1, p_far); divide_and_conquer(P_reduced, H2, p_far, p2); appendVector(H1, H); appendVector(H2, H); } }
ResultType divide_and_conquer(vector<int>& A, int start, int end) { if (start > end) return ResultType(0, 0, INT_MIN); if (start == end) return ResultType(start, end, A[start]); int mid = start + (end - start) / 2; ResultType left_res = divide_and_conquer(A, start, mid); ResultType right_res = divide_and_conquer(A, mid + 1, end); int sum = 0; int left = 0; int left_biggest = INT_MIN; for (int i = mid; i >= 0; i--) { sum += A[i]; if (sum > left_biggest) { left = i; left_biggest = sum; } } int right = 0; int right_biggest = INT_MIN; sum = 0; for (int i = mid + 1; i <= end; i++) { sum += A[i]; if (sum > right_biggest) { right = i; right_biggest = sum; } } int across_biggest = left_biggest + right_biggest; int biggest = ::max(left_res.biggest, ::max(right_res.biggest, across_biggest)); if (biggest == left_res.biggest) { return left_res; } else if (biggest == right_res.biggest) { return right_res; } else { return ResultType(left, right, across_biggest); } }
void quickhull(const pointVec_t &points, pointVec_t &hull, bool buffered) { if (points.size() < 2) { #if USECONCVEC appendVector(points, hull); #else // STD::VECTOR hull.insert(hull.end(), points.begin(), points.end()); #endif // USECONCVEC return; } point_t p_maxx = extremum<FindXExtremum::maxX>(points); point_t p_minx = extremum<FindXExtremum::minX>(points); pointVec_t H; divide_and_conquer(points, hull, p_maxx, p_minx, buffered); divide_and_conquer(points, H, p_minx, p_maxx, buffered); #if USECONCVEC appendVector(H, hull); #else // STD::VECTOR hull.insert(hull.end(), H.begin(), H.end()); #endif // USECONCVEC }