void convex_hull(polygon in, polygon& hull){
	hull.clear();
	
	if(in.size() < 3){ hull = in; return; }
	
	int pos = 0;
	for(int i = 1; i < in.size(); i++) if(in[i] < in[pos]) pos = i;
	swap(in[0], in[pos]);
	refer = in[0];
	
	sort(in.begin() + 1, in.end(), cmp_angle);
	in.resize(unique(in.begin(), in.end()) - in.begin());
	
	hull.push_back(in[0]); hull.push_back(in[1]);
	
	in.push_back(in[0]); //isto evita pontos colineares no final do poligono
	for(int i = 2; i < in.size(); ){
		if(hull.size() > 2 && side_sign(hull[hull.size() - 2], hull[hull.size() - 1], in[i]) <= 0){
			hull.pop_back();
		}
		else hull.push_back(in[i++]);
	}
	//tira a duplicata
	hull.pop_back();
}
// Returns a list of points on the convex hull in counter-clockwise order.
// NOTE: the last point in the returned list is the same as the first one.
void convex_hull_2(polygon P, polygon& hull) {
	hull.clear();
	
	// Sort points lexicographically
	sort(P.begin(), P.end());
	P.resize(unique(P.begin(), P.end()) - P.begin());
	
	// Build lower hull
	for (int i = 0; i < P.size(); i ++) {
		while (hull.size() >= 2 && side_sign(hull[hull.size() - 2], hull[hull.size() - 1], P[i]) <= 0)
			hull.pop_back();
		hull.push_back(P[i]);
	};
 
	// Build upper hull
	for (int i = P.size()-2, t = hull.size() + 1; i >= 0; i --) {
		while (hull.size() >= t && side_sign(hull[hull.size()-2], hull[hull.size()-1], P[i]) <= 0)
			hull.pop_back();
		hull.push_back(P[i]);
	};
}