习题1.8和1.9,顺带把点ADT也写一下
#-*-copy: utf-8-*-
# 点
from math import sqrt
class Point(object):
def __init__(self, x, y):
self.xCoord = x
self.yCoord = y
def getX(self):
return self.xCoord
def getY(self):
return self.yCoord
def shift(self, xInc, yInc):
self.xCoord += xInc
self.yCoord += yInc
def distance(self, other):
return sqrt((self.xCoord - other.xCoord) ** 2 + (self.yCoord - other.yCoord) ** 2)
#-*-coding: utf-8-*-
# 线段
from math import sqrt
from mypoint import Point
class LineSegment(object):
def __init__(self, ptA, ptB):
if isinstance(ptA, Point) and isinstance(ptB, Point):
self.ptA = ptA
self.ptB = ptB
self.vector = (ptB.xCoord - ptA.xCoord, ptB.yCoord - ptA.yCoord)
def endPointA(self):
return self.ptA
def endPointB(self):
return self.ptB
def length(self):
return ptA.distance(ptB)
def __str__(self):
return "{0}#{1}".format(self.ptA, self.ptB)
# 判断线段是否与y轴平行
def isVertical(self):
if self.ptA.xCoord == self.ptB.xCoord and self.ptA.yCoord != self.ptB.yCoord:
return True
else:
return False
# 判断线段是否与x轴平行
def isHorizontal(self):
if self.ptA.yCoord == self.ptB.yCoord and self.ptA.xCoord != self.ptB.xCoord:
return True
else:
return False
# 判断两线段是否互相平行
def isParallel(self, other):
if self.isVertical() and other.isVertical():
return True
elif self.isVertical() and (not other.isVertical()):
return False
elif (not self.isVertical()) and other.isVertical():
return False
else:
if self.slope() == other.slope():
return True
else:
return False
# 判断两线段是否互相垂直
def isPerpendicular(self, other):
if self.isHorizontal() and other.isVertical():
return True
elif self.isVertical() and other.isHorizontal():
return True
elif self.slope() * other.slope() == -1:
return True
else:
return False
# 判断两线段是否相交,即(AC叉乘AD) <= 0 以及(CA叉乘CD) <= 0同时成立,注意不是直线相交
def intersects(self, other):
AC = LineSegment(self.ptA, other.ptA)
AD = LineSegment(self.ptA, other.ptB)
CA = LineSegment(other.ptA, self.ptA)
CB = LineSegment(other.ptA, self.ptB)
if (self.vector[0] * AC.vector[1] - self.vector[1] * AC.vector[0]) * (self.vector[0] * AD.vector[1] -self.vector[1] * AD.vector[0]) <= 0 /
and (other.vector[0] * CA.vector[1] - other.vector[1] * CA.vector[0]) * (other.vector[0] * CB.vector[1] - other.vector[1] * CB.vector[0]) <= 0:
return True
else:
return False
# 判断线段是否平分另一条线段
def bisects(self, other):
if intersects(self, other):
if (other.midpoint().yCoord - self.ptA.yCoord) * self.vector[0] == self.vector[1] * (other.midpoint().xCoord - self.ptA.xCoord):
return True
else:
return False
else:
return False
def slope(self):
try:
return 1.0 * self.vector[1] / self.vector[0]
except ZeroDivisorError, e:
return None
# 感觉有点怪怪的
def shift(xInc, yInc):
ptA.xCoord += xInc
ptA.yCoord += yInc
ptB.xCoord += xInc
ptB.yCoord += yInc
def midpoint(self):
return Point(0.5 * (self.ptA.xCoord + self.ptB.xCoord), 0.5 * (self.ptA.yCoord + self.ptB.yCoord))
#-*-coding: utf-8-*-
# 多边形
from mypoint import Point
from mylinesegment import Segment
from math import copysign # 符号函数
class Ploygon(object):
def __init__(self, *pts):
if len(pts) < 3:
print "Please enter laege than two points."
else:
if False not in [instance(pt, Point) for pt in pts]:
self.sides = []
for i in range(len(pts)):
if i < len(pts) - 1:
self.sides.append(Segment(pt[i], pt[i+1])
else:
self.sides.append(Segment(pt[i], pt[0]))
self.pts = list(pts)
# 无共同顶点的边不能相交
for i in self.sides:
for j in self.sides:
if set([i.endPointA, i.endPointB) & set([j.endPointA, j.endPointB]) == 0:
if i.interset(j):
print "Cannot be a ploygon."
self.pts = None
self.sides = None
break
# 判断凹凸性,依据所有相邻边的向量的叉乘符号判断,所有符号相同,则为凸多边形,出现不同符号,则为凹多边形。
def isConvex(self):
crsprodsts = [self.sides[-1].vector[0] * self.sides[0].vector[1] - self.sides[-1].vector[1] * self.sides[0].vector[0]]
for i in range(len(self.sides)):
crsprodt = self.sides[i].vector[0] * self.sides[i+1].vector[1] - self.sides[i].vector[1] * self.sides[i+1].vector[0]
if copysign(1, crsprodsts) != copysign(1, crsprodt):
return False
return True
# 返回内角和
def intAngSum(self):
return 180 * (len(self.sides) - 2)
# 应该还有好多,以后慢慢补充