point2.py
'''\
Python 2D Point Class.
A two-dimensional point is implemented as an intelligent tuple.
The value is stored as an X,Y coordinate, but the object can also
return the polar coordinates (Radius and Angle).
Note that, since Python class members are public, the class state
is readable and writeable. It should be, at the least, read-only,
but ideally, private to the class.
Developer@Sonnack.com
April 2010
'''
from sys import stdout, stderr, argv
import math
class point2 (object):
'''Your basic 2D Point Class!'''
tiny = 0.000001
def __init__ (self, x=0, y=0):
self.x = x
self.y = y
def reset (self):
''' Move the Point to 0,0. '''
self.x = 0
self.y = 0
return self
def set (self, x=0, y=0):
''' Move the Point to an absolute coordinate (x,y). '''
self.x = x
self.y = y
return self
def move (self, x=0, y=0):
''' Move the Point relative to itself (+x,+y). '''
self.x += x
self.y += y
return self
def radius (self):
''' Radius: x^2 + y^2 = r^2. '''
return math.hypot(self.x, self.y)
def angle (self):
''' Angle: arc tangent of y/x. '''
return math.degrees(math.atan2(self.y, self.x))
def distance (self, other):
''' Distance from one point to another. '''
dx = math.fabs(self.x - other.x)
dy = math.fabs(self.y - other.y)
return math.hypot(dx, dy)
def getList (self):
''' Return Point as a List object. '''
return [self.x, self.y]
def getTuple (self):
''' Return Point as a Tuple object. '''
return (self.x, self.y)
def coord (self):
''' Return pretty coordinate version. '''
return "(%.3f,%.3f)" % (self.x, self.y)
def polar (self):
''' Return pretty polar version. '''
return "[%.3f@%.3f]" % (self.radius(), self.angle())
def __str__ (self):
''' Return pretty version. '''
s = "%.4f,%.4f"
t = (self.x, self.y)
return s % t
def __repr__ (self):
''' Return Point as a serializable object (JSON). '''
s = "{point2:{x:%f, y:%f}}"
t = (self.x, self.y)
return s % t
def __len__ (self):
''' A point's length is the radius as an integer. '''
return int(self.radius())
def __cmp__ (self, other):
''' Points compare equal if they are really close. '''
diff = self.angle() - other.angle()
if math.fabs(diff) < self.tiny:
diff = self.radius() - other.radius()
if math.fabs(diff) < self.tiny:
return 0
if int(diff) == 0:
return -1 if (diff < 0) else +1
return int(diff)
def __nonzero__ (self):
''' Point is non-zero if outside a tiny radius. '''
offset = self.radius()
if math.fabs(offset) < self.tiny:
return True
return False
class point (point2):
'''A generic alias.'''
pass
def demo1 ():
''' Just shows the Point in action.
(And proves the class works.)
'''
p1 = point()
p2 = point(4,3)
print p1, p2
print "repr: ", repr(p1), repr(p2)
print "str:", str(p1), str(p2)
print "len: ", len(p1), len(p2)
list_point2("P0", p1)
list_point2("P2", p2)
compare_points(p1, p2)
p2.reset()
print "p2.reset(): %s" % p2
list_point2("P2", p2)
compare_points(p1, p2)
p1.set( 5,5)
p2.set(-8,6)
print "p1.set( 5, 5): %s" % p1
print "p2.set(-8, 6): %s" % p2
list_point2("P0", p1)
list_point2("P2", p2)
compare_points(p1, p2)
p1.move(-10,-10)
print "p1.move(-10,-10): %s" % p1
list_point2("P0", p1)
compare_points(p1, p2)
return [p1, p2]
def compare_points (pa, pb):
print "p1.compare(p2): %d" % cmp(pa, pb)
print "p1.distance(p2): %f" % pa.distance(pb)
print
def list_point2 (s, p):
print "%s.coord: %.3f,%.3f" % (s, p.x, p.y)
print "%s.polar: %.3f,%.3f" % (s, p.angle(), p.radius())
if __name__ == "__main__":
print 'autorun:',argv[0]
obj = demo1()
'''eof'''