python数据结构学习笔记-2016-10-09-01-点、线段和多边形ADT

        习题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)
                
    # 应该还有好多,以后慢慢补充              



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值