File Annotation
Not logged in
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: //-------------------------------------------------------------
4fd800b3a8 2011-02-23        kinaba: // Convex Hull -- Andrew's Monotone Chain
4fd800b3a8 2011-02-23        kinaba: //   O(N log N)
4fd800b3a8 2011-02-23        kinaba: //
4fd800b3a8 2011-02-23        kinaba: // Verified by
4fd800b3a8 2011-02-23        kinaba: //   - SRM 336 Div1 LV3
4fd800b3a8 2011-02-23        kinaba: //   - TCO09 Round2 LV2
4fd800b3a8 2011-02-23        kinaba: //   - SRM 486 Div1 LV3
4fd800b3a8 2011-02-23        kinaba: //-------------------------------------------------------------
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: double outer_prod(const CMP& a, const CMP& b) { return imag(conj(a)*b); }
4fd800b3a8 2011-02-23        kinaba: double inner_prod(const CMP& a, const CMP& b) { return real(conj(a)*b); }
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: int ccw(const CMP& a, CMP b, CMP c) {
4fd800b3a8 2011-02-23        kinaba: 	b -= a; c -= a;
4fd800b3a8 2011-02-23        kinaba: 	if( outer_prod(b,c) > 0 ) return +1; // counter clockwise
4fd800b3a8 2011-02-23        kinaba: 	if( outer_prod(b,c) < 0 ) return -1; // clockwise
4fd800b3a8 2011-02-23        kinaba: 	if( inner_prod(b,c) < 0 ) return +2; // c--a--b on line
4fd800b3a8 2011-02-23        kinaba: 	if( norm(b) < norm(c) )   return -2; // a--b--c on line
4fd800b3a8 2011-02-23        kinaba: 	return 0;
4fd800b3a8 2011-02-23        kinaba: }
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: bool byX( const CMP& a, const CMP& b ) {
4fd800b3a8 2011-02-23        kinaba: 	if( a.real() != b.real() )
4fd800b3a8 2011-02-23        kinaba: 		return a.real() < b.real();
4fd800b3a8 2011-02-23        kinaba: 	return a.imag() < b.imag();
4fd800b3a8 2011-02-23        kinaba: }
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: vector<CMP> convex_hull( vector<CMP> p )
4fd800b3a8 2011-02-23        kinaba: {
4fd800b3a8 2011-02-23        kinaba: 	#define IS_RIGHT <0   // skip on-line verts
4fd800b3a8 2011-02-23        kinaba: 	//#define IS_RIGHT ==-1 // take all
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 	sort(p.begin(), p.end(), &byX);
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 	vector<CMP> ans;
4fd800b3a8 2011-02-23        kinaba: 	for(int i=0; i<p.size(); ans.push_back(p[i++])) // left-to-right
4fd800b3a8 2011-02-23        kinaba: 		while( ans.size()>=2 && ccw(ans[ans.size()-2], ans[ans.size()-1], p[i]) IS_RIGHT )
4fd800b3a8 2011-02-23        kinaba: 			ans.pop_back();
4fd800b3a8 2011-02-23        kinaba: 	if( ans.size() == p.size() )
4fd800b3a8 2011-02-23        kinaba: 		return ans;
4fd800b3a8 2011-02-23        kinaba: 	for(int i=p.size()-2; i>=0; ans.push_back(p[i--])) // right-to-left
4fd800b3a8 2011-02-23        kinaba: 		while( ans.size()>=2 && ccw(ans[ans.size()-2], ans[ans.size()-1], p[i]) IS_RIGHT )
4fd800b3a8 2011-02-23        kinaba: 			ans.pop_back();
4fd800b3a8 2011-02-23        kinaba: 	ans.pop_back();
4fd800b3a8 2011-02-23        kinaba: 	return ans;
4fd800b3a8 2011-02-23        kinaba: }