刷题记录7.15

交点


给定两条线段(表示为起点start = {X1, Y1}和终点end = {X2, Y2}),如果它们有交点,请计算其交点,没有交点则返回空值。

要求浮点型误差不超过10^-6。若有多个交点(线段重叠)则返回 X 值最小的点,X 坐标相同则返回 Y 值最小的点。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

遇到的第一道困难题,思路比较简单,根据给定两个点的位置,计算线段的斜率截距(斜率不存在的情况额外讨论),再根据按照两条线段可能的几何关系求解;两条线段的几种几何关系:平行、相交、重合、延长线相交但线段不相交。

class Solution:
    def intersection(self, start1: List[int], end1: List[int], start2: List[int], end2: List[int]) -> List[float]:
        x=[start1[0],end1[0],start2[0],end2[0]]
        y=[start1[1],end1[1],start2[1],end2[1]]
        x1=[start1[0],end1[0]]
        x2=[start2[0],end2[0]]
        y1=[start1[1],end1[1]]
        y2=[start2[1],end2[1]]
        x.sort()
        y.sort()
        x1.sort()
        x2.sort()
        y1.sort()
        y2.sort()
        eps=1e-6
        interpoint=[0.0,0.0]
        if start1[0] != end1[0]: # k1存在
            k1=(start1[1]-end1[1])/(start1[0]-end1[0])
            b1=((start1[1]+end1[1])-k1*(start1[0]+end1[0]))/2
            if start2[0] != end2[0]: # k2存在
                k2=(start2[1]-end2[1])/(start2[0]-end2[0])
                b2=((start2[1]+end2[1])-k2*(start2[0]+end2[0]))/2
                if k1 == k2: # 两条平行线
                    if k1 == 0 and start1[1] == start2[1]:  # 两条重合平行横线
                        x.sort()
                        interpoint[0] = x[1]
                        interpoint[1] = start1[1]
                    if (start1[0]*k2+b2-start1[1])**2<=eps or (end1[0]*k2+b2-end1[1])**2 <= eps:  # 两条重合平行斜线
                        interpoint[0] = x[1]
                        interpoint[1] = y[1]
                    else:
                        return []
                else:  # 不平行(相交或者延长线相交)
                    interpoint[0]=(b2-b1)/(k1-k2)
                    interpoint[1]=k1*interpoint[0]+b1
            else: # k1存在,k2不存在
            	interpoint[0]=start2[0]
            	interpoint[1]=k1*interpoint[0]+b1             
        if start1[0] == end1[0] and start2[0] == end2[0]: #两条斜率都不存在
            if start1[0] == start2[0]: # 两条垂直重合
                interpoint[0] = start1[0]
                interpoint[1] = y[1]
            else:
                return []
        if start1[0] == end1[0] and start2[0] != end2[0]: # k1不存在但k2存在
            k2=(start2[1]-end2[1])/(start2[0]-end2[0])
            b2=((start2[1]+end2[1])-k2*(start2[0]+end2[0]))/2
            interpoint[0]=start1[0]
            interpoint[1]=start1[0]*k2+b2       
        if x1[0] <= interpoint[0] and interpoint[0]<= x1[1] and y1[0] <= interpoint[1] and interpoint[1]<= y1[1] and x2[0] <= interpoint[0] and interpoint[0]<= x2[1] and y2[0] <= interpoint[1] and interpoint[1]<= y2[1]: 
            return interpoint
        else:
            return [] # 延长线相交但线段本身不相交
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值