import math
class Point( object ):
def __init__( self, x, y ):
self.x = x
self.y = y
def __cmp__( self, other ):
if self.y < other.y:
return -1
elif self.y == other.y:
if self.x < other.x:
return -1
elif self.x == other.x:
return 0
else:
return 1
else:
return 1
def __repr__( self ):
return "(X: {x}, Y:{y})".format( x = self.x, y = self.y )
@staticmethod
def distance( p1, p2 ):
return math.sqrt( ( p1.x - p2.x ) * ( p1.x - p2.x ) + ( p1.y - p2.y ) * ( p1.y - p2.y ) )
@staticmethod
def crossMultiply( p1, p2, p3 ):
return ( p2.x - p1.x ) * ( p3.y - p1.y ) - ( p2.y - p1.y ) * ( p3.x - p1.x )
points = []
results = []
def graham():
def find_start_point():
res = Point( float( 'inf' ), float( 'inf' ) )
for p in points:
if res > p:
res = p
return res
def _cmp( p1, p2 ):
m = Point.crossMultiply( start_point, p1, p2 )
if m < 0:
return 1
elif m == 0 and Point.distance( start_point, p1 ) < Point.distance( start_point, p2 ):
return 1
else:
return -1
global points, results
start_point = find_start_point()
points.remove( start_point )
points = sorted( points, _cmp )
results.extend( [start_point, points.pop( 0 ), points.pop( 0 )] )
for p in points:
while ( Point.crossMultiply( results[-2], results[-1], p ) ) <= 0:
results.pop()
results.append( p )
return results
if __name__ == "__main__":
points.extend( [ Point( 30, 30 ),
Point( 50, 60 ),
Point( 60, 20 ),
Point( 70, 45 ),
Point( 86, 39 ),
Point( 112, 60 ),
Point( 200, 113 ),
Point( 250, 50 ),
Point( 300, 200 ),
Point( 130, 240 ),
Point( 76, 150 ),
Point( 47, 76 ),
Point( 36, 40 ),
Point( 33, 35 ) ] )
res = graham()
print res
原文地址:http://blog.csdn.net/pandora_madara/article/details/39228661