### point3.py

```'''\
Python 3D Point Class.

Extending the 2D Point class to three dimensions.
The sub-class adds a Z coordinate to the implementation
and an Elevation angle to the polar coordinates.

Developer@Sonnack.com
April 2010
'''
####################################################################################################
from sys import stdout, stderr, argv
import math
from point2 import point2
####################################################################################################

##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
## 3D POINT
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
class point3 (point2):
'''A 3D Point Class based on the 2D Point Class.'''

def __init__ (self, x=0, y=0, z=0):
super(point3,self).__init__(x,y)
self.z = z

def reset (self):
''' Move the Point to 0,0,0. '''
super(point3,self).reset()
self.z = 0
return self

def set (self, x=0, y=0, z=0):
''' Move the Point to an absolute coordinate (x,y,z). '''
super(point3,self).set(x,y)
self.z = z
return self

def move (self, x=0, y=0, z=0):
''' Move the Point relative to itself (+x,+y,+z). '''
super(point3,self).move(x,y)
self.z += z
return self

''' Radius: x^2 + y^2 + z^2 = r^2. '''
return math.sqrt((self.x ** 2)+(self.y ** 2)+(self.z ** 2))

def elevation (self):
''' Elevation: arc tangent of z/xy. '''
xy = math.hypot(self.x, self.y)
return math.degrees(math.atan2(self.z, xy))

def distance (self, other):
''' Distance from one point to another. '''
dx = math.fabs(self.x - other.x)
dy = math.fabs(self.y - other.y)
dz = math.fabs(self.z - other.z)
return math.sqrt((dx*dx)+(dy*dy)+(dz*dz))

def getList (self):
''' Return Point as a List object. '''
return [self.x, self.y, self.z]

def getTuple (self):
''' Return Point as a Tuple object. '''
return (self.x, self.y, self.z)

def coord (self):
''' Return pretty coordinate version. '''
return "(%.3f,%.3f,%.3f)" % (self.x, self.y, self.z)

def polar (self):
''' Return pretty polar version. '''
return "[%.3f@%.3f@%.3f]" % (self.radius(), self.angle(), self.elevation())

def __str__ (self):
''' Return pretty version. '''
s = "%.4f,%.4f,%.4f"
t = (self.x, self.y, self.z)
return s % t

def __repr__ (self):
''' Return Point as a serializable object (JSON). '''
s = "{point3:{x:%f, y:%f, z:%f}}"
t = (self.x, self.y, self.z)
return s % t

def __len__ (self):
''' A point's length is its radius as an integer. '''

def __cmp__ (self, other):
''' Points compare equal if they are really close. '''
diff = self.angle() - other.angle()
# if angles are nearly the same, compare based on elevation...
if math.fabs(diff) < self.tiny:
diff = self.elevation() - other.elevation()
# if elevations are nearly the same, compare based on radius...
if math.fabs(diff) < self.tiny:
# if the radii are nearly the same, just consider the points equal...
if math.fabs(diff) < self.tiny:
return 0
# if the difference sub-integer, use "hysteresis"...
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. '''
if math.fabs(offset) < self.tiny:
return True
return False

##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
## POINT
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
class point (point3):
'''A generic alias.'''
pass

##================================================================================================##
def demo1 ():
''' Just shows the Point in action.
(And proves the class works.)
'''
p0 = point()
p1 = point(10, 10, 10)
p2 = point(10, 20)
p3 = point(10, -20, 8)
p4 = point(0, 5, 7)
p5 = point(-10, 20, 9)
print p0, p1, p2, p3, p4, p5
print

list_point3("P0", p0)
list_point3("P1", p1)
list_point3("P2", p2)
list_point3("P3", p3)
list_point3("P4", p4)
list_point3("P5", p5)

p1.reset()
list_point3("P1.reset", p1)

p1.set(-10,10,-5)
list_point3("P1.set", p1)

p1.move(1,1,1)
list_point3("P1.move", p1)
p1.move(1,1,1)
list_point3("P1.move", p1)

ps = [p0, p1, p2, p3, p4, p5]
print ps
print
print sorted(ps)
return ps

##================================================================================================##
def list_point3 (s, p):
print "%s.coord: %.3f,%.3f,%.3f" % (s, p.x, p.y, p.z)
print "%s.polar: %.3f,%.3f,%.3f" % (s, p.angle(), p.radius(), p.elevation())

####################################################################################################
if __name__ == "__main__":
print 'autorun:',argv[0]
obj = demo1()

####################################################################################################
'''eof'''
```