两条直线,已知每条直线上的两个不同的点 求标准方程AX+BY+C=0
def common_style(x1,y1,x2,y2):
return y2-y1,x1-x2,x2*y1-x1*y2
根据标准方差,求直线的截距
def line_intercept_with_commonstyle(A,B,C):
if A==0 and B==0:return None,None
if A==0:return None,-C/B
if B==0:return -C/A,None
return -C/A,-C/B
根据直线两点求截距
def line_intercept_with_two_point(x1,y1,x2,y2):
A,B,C = common_style(x1,y1,x2,y2)
return line_intercept_with_commonstyle(A,B,C)
根据线段两点 求截距
def line_seg_intercept_with_two_point(x1,y1,x2,y2):
# 根据线段两点 求截距
x_d,y_d = line_intercept_with_two_point(x1,y1,x2,y2)
if x_d == None and y_d==None:
return None,None
# 平行x轴 且与y轴无交点
if x_d == None and (min(x1,x2)>0 or max(x1,x2)<0):
return None,None
# 平行y轴 且与x轴无交点
if y_d== None and (min(y1,y2)>0 or max(y1,y2)<0):
return None,None
if point_in_line_seg(x1,y1,x2,y2,x_d,0) and point_in_line_seg(x1,y1,x2,y2,0,y_d):
return x_d,y_d
if point_in_line_seg(x1,y1,x2,y2,x_d,0):
return x_d,None
return None,y_d
判断点是否在 两个点构成的线段上 即是否三点共线段
def point_in_line_seg(x1,y1,x2,y2,x3,y3):
if x1==x3 and y1==y3: return True
if x2==x3 and y2==y3:return True
if x1==x3 and y1!=y3:return False
if x2==x3 and y2!=y3:return False
# 斜率不一样
if (y2-y1)/(x2-x1)!=(y3-y1)/(x3-x1):return False
# 在线段上
if x3<=max(x1,x2) and x3>=min(x1,x2) and y3>=min(y1,y2) and y3<=max(y1,y2):
return True
return False
判断两个线段是否有交点,写出交点x最小的那个坐标,如果一样,写y较小的
思路:这一问题主要是特殊情况的处理很麻烦。
0.完全重叠,直接返回坐标小的点
1.如果在x,y轴上的投影有不重叠的,那么这两个线段一定不重叠。
因为重叠部分的投影一定相同,所以必须有重叠的。
2.先考虑直线,需要判断斜率是否存在,斜率是否相同。
如果斜率都不存在,判断他们有无交点。这里由于0的筛选所以肯定有交点,直接返回满足条件的坐标即可。
其中的一个不存在,判断另一个直线和该直线构成的点,是否在两个线段上。可以用上面的函数。
3.如果斜率存在,但是相等。由于0的判断,把投影不重复的全去掉了。这样可以避免两个线段在同一个直线上但是没有交点的情况。所以如果斜率相等,判断截距是否一样即可
4.其余情况 就是普通情况可以用 公式计算。详情看代码
def intersection(self, start1, end1, start2, end2):
[x0,y0],[x1,y1],[x2,y2],[x3,y3] = start1,end1,start2,end2
d = [start1, end1, start2, end2]
d = sorted(d)
# 重合情况
if x0 == x2 and y0==y2 and x1==y3 and y1==y3:
return list(d[1])
# x,y 以及他的投影都不重合的情况 一定不存在 交点
if min(x1,x0)>max(x2,x3) or max(x1,x0)<min((x3,x2)):
return []
if min(y1,y0)>max(y2,y3) or max(y1,y0)<min((y3,y2)):
return []
# 判断斜率不存在在情况
# 斜率都不存在 这个时候必须x都一样
if x0==x1 and x2==x3:
if x1!=x3 or min(y0,y1)>max(y2,y3) or max(y0,y1)<min(y2,y3):
return []
return list(d[1])
# 第一条斜率不存在
if x0 == x1:
A,B,C = common_style(x2,y2,x3,y3)
x_j,y_j = x1,x_to_y(A,B,C,x0)
if point_in_line_seg(x0,y0,x1,y1,x_j,y_j):
return [x_j,y_j]
# 第2条斜率不存在
elif x2==x3:
A, B, C = common_style(x0, y0, x1, y1)
x_j, y_j = x2, x_to_y(A, B, C, x0)
if point_in_line_seg(x2, y2, x3, y3, x_j, y_j):
return [x_j, y_j]
# 斜率相等
if (y1-y0)/(x1-x0)==(y3-y2)/(x3-x2):
if line_seg_intercept_with_two_point(x0,y0,x1,y1)[1]==line_seg_intercept_with_two_point(x2,y2,x3,y3)[1]:
return list(d[1])
return []
y = ((y0-y1)*(y3-y2)*x0 + (y3-y2)*(x1-x0)*y0 + (y1-y0)*(y3-y2)*x2 + (x2-x3)*(y1-y0)*y2 ) / ( (x1-x0)*(y3-y2) + (y0-y1)*(x3-x2) )
x = x2 + (x3-x2)*(y-y2) / (y3-y2)
if point_in_line_seg(x0,y0,x1,y1,x,y) and point_in_line_seg(x2,y2,x3,y3,x,y):return [x,y]
return []
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。