示例#1
0
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
    }
}
示例#2
0
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());
}
示例#3
0
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;
}
示例#4
0
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);
}
示例#6
0
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);
     }
 }
示例#9
0
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
}