• 
    

      <address id="upfr9"><pre id="upfr9"><strike id="upfr9"></strike></pre></address>
      1. <address id="upfr9"><tr id="upfr9"></tr></address><dl id="upfr9"></dl>

        判斷線段是否相交

        # -*- coding: utf-8 -*-
        # @Time         : 2019-09-18 16:55
        # @Author       : Jayce Wong
        # @ProjectName  : job
        # @FileName     : segment_cross.py
        # @Blog         : https://blog.51cto.com/jayce1111
        # @Github       : https://github.com/SysuJayce
        
        """
        Q:給定兩個線段的坐標(biāo)(也就是四個點的直角坐標(biāo)系坐標(biāo)),判斷這兩個線段是否相交
        
        ### 判斷線段是否相交可以利用向量的叉乘 ###
        假定輸入為P1、P2、Q1、Q2四個點的坐標(biāo),P1P2為一條線段,Q1Q2為另一條線段
        
        兩條線段相交只有兩種情況
        1. 其中一條線段的某一端點在另一條線段上;
        2. 兩條線段形成X形。
        
        首先判斷這四個點是否在另一條線段上,也就是說,判斷P1是否在線段Q1Q2上,P2是否在線段Q1Q2上...
        如果上述判斷為真,那么這兩條線段相交?!窘鉀Q了第一種情況】
        
        如果沒有點在另一條線段上,那么進行叉乘判斷。
        先固定線段Q1Q2,然后以Q1為軸,計算Q1P1和Q1Q2、Q1P2和Q1Q2的叉乘是否異號;
        然后固定線段P1P2,然后以P1為軸,計算P1Q1和P1P2、P1Q2和P1P2的叉乘是否異號。
        當(dāng)上述的叉乘都異號的時候,兩條線段相交。
        【解決了第二種情況】
        """
        
        class Point:
            def __init__(self, x, y):
                self.x = x
                self.y = y
        
            def __sub__(self, other):
                return Point(self.x - other.x, self.y - other.y)
        
        class Segment:
            def __init__(self, point1, point2):
                self.point1 = point1
                self.point2 = point2
                self.x = point1.x - point2.x
                self.y = point1.y - point2.y
        
        def crossProduct(v1, v2):
            return v1.x * v2.y - v2.x * v1.y
        
        def onSegment(p, seg):
            """
            判斷點在不在一條線段上,關(guān)鍵在于:
            1. 三點是否共線
            2. 點p是否在線段的延長線上。
        
            只要滿足了三點共線,且點p不在延長線上,那么點p就在線段上。
        
            判斷三點共線可以用向量的叉乘,三點共線即兩個向量平行,也就是叉乘結(jié)果為零向量(對應(yīng)到二維就是零)
            當(dāng)點p的橫縱坐標(biāo)都在線段端點之間的時候,點p不在延長線上。
            :param p:
            :param seg:
            :return:
            """
            # 先確保點p不在延長線上
            if min(seg.point1.x, seg.point2.x) <= p.x <= max(seg.point1.x, seg.point2.x)\
                    and min(seg.point1.y, seg.point2.y) <= p.y <= max(seg.point1.y, seg.point2.y):
                # 然后確保這三個點形成的向量兩兩平行,這里只要這三個向量中任意兩個平行,第三個一定也平行
                if crossProduct(p - seg.point1, p - seg.point2) == 0:
                    return True
                else:
                    return False
            else:
                return False
        
        def isCross(p1, p2, q1, q2):
            p1p2 = Segment(p1, p2)
            q1q2 = Segment(q1, q2)
        
            p1q1 = Segment(p1, q1)
            p1q2 = Segment(p1, q2)
        
            q1p1 = Segment(q1, p1)
            q1p2 = Segment(q1, p2)
        
            # 判斷是否存在端點位于另一條線段上,是的話則兩條線段相交
            if any([onSegment(p1, q1q2), onSegment(p2, q1q2),
                    onSegment(q1, p1p2), onSegment(q2, p1p2)]):
                return True
        
            # 否則固定線段P1P2,判斷Q1和Q2是否在P1P2的兩側(cè)(計算叉乘)
            # 然后固定線段Q1Q2,判斷P1和P2是否在Q1Q2的兩側(cè)
            # 如果上面的判斷均為真,那么這兩條線段形成一個X
            return (crossProduct(p1p2, p1q1) * crossProduct(p1p2, p1q2) < 0)\
                   and (crossProduct(q1q2, q1p1) * crossProduct(q1q2, q1p2) < 0)
        
        def main():
            p1 = Point(0, 0)
            p2 = Point(2, 2)
            q1 = Point(1, 1)
            q2 = Point(0, 2)
            if isCross(p1, p2, q1, q2):
                print('Yes')
            else:
                print('No')
        
        if __name__ == '__main__':
            main()
        

        分享名稱:判斷線段是否相交
        轉(zhuǎn)載來源:http://www.jbt999.com/article30/iipiso.html

        成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、網(wǎng)站收錄、移動網(wǎng)站建設(shè)、域名注冊電子商務(wù)、App設(shè)計

        廣告

        聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

        綿陽服務(wù)器托管

      2. 
        

          <address id="upfr9"><pre id="upfr9"><strike id="upfr9"></strike></pre></address>
          1. <address id="upfr9"><tr id="upfr9"></tr></address><dl id="upfr9"></dl>
            五十路在线视频 | 色哟哟无码精品一区二区三区 | 婷婷久久丁香 | 女人扒开尿口让男人桶 | 日逼99| 亚州操逼 | 福利导航二三区 | 午夜美女福利 | 国产伦精品一区二区三区视频女 | 成人影视自拍 |