"""
用面向对象的思维设计相关类,从而实现直线与直线、直线与圆、直线与矩形的交点。
要求各给出每个案例的至少一个示例的程序。
"""
class Point:
def __init__(self, x, y):
self.__x = x
self.__y = y
pass
def get_x(self):
return self.__x
def get_y(self):
return self.__y
def __str__(self):
return "("+str(self.__x)+","+str(self.__y)+")"
pass
class Line:
def __init__(self, a, b, c):
"""
直线一般式ax+by+c=0
:param a: x前系数
:param b: y前系数
:param c: 常数项
"""
if a == 0 and b == 0:
print("无法构成直线")
exit(-1)
self.__a = a
self.__b = b
self.__c = c
pass
def get_line(self):
return self.__a, self.__b, self.__c
def get_line_point(self, line):
"""
得到与另一个直线的交点
:param line: 另一个直线
:return: None / 与直线的交点
"""
(a, b, c) = line.get_line() # 获取另一直线的参数
if a * self.__b == b * self.__a:
print("直线平行,无交点")
return None
else: # 求交点 x = (c2*a1 - c1*a2) / (b1*a2 - b2*a1)
x0 = (self.__b * c - self.__c * b) / (self.__a * b - a * self.__b)
y0 = (c * self.__a - self.__c * a) / (self.__b * a - b * self.__a)
inter_point = Point(x0, y0)
return inter_point
def get_cir_point(self, cir):
"""
点到直线的距离:d = | ax0+bx0+c |/ (a^2+b^2)^1/2
:param cir: 待求的圆
:return: None / 交点
"""
r = cir.get_r()
center = cir.get_center()
x0, y0 = center.get_x(), center.get_y()
d = abs(self.__a * x0 + self.__b * y0 + self.__c) \
/ pow(self.__a * self.__a + self.__b * self.__b, 1/2)
if d > r:
print("直线与圆无交点")
return None
elif r - d > 0: # 有交点
if self.__b == 0: # 直线垂直
x1 = x2 = self.__c / self.__a
d_y = pow(r * r - d * d, 1 / 2)
if x1 - x0 < 1e-6: # 如果直线在圆的左边
y1, y2 = y0 + r, y0 - r
pass
else:
y1, y2 = y0 + d_y, y0 - d_y
pass
pass # 直线垂直
else: # 求解一元二次方程 ax^2+bx+c=0
k = - (self.__a / self.__b) # 直线斜率
m = - (self.__c / self.__b) # 直线截距
a = 1 + k**2
b = -2 * x0 + 2 * (m - y0)
c = x0**2 + (m-y0)**2 - r**2
dert = pow(b**2 - 4 * a * c, 1/2)
x1, x2 = (-b+dert) / (2 * a), (-b-dert) / (2 * a)
y1, y2 = k * x1 + m, k * x2 + m
pass # 直线不垂直
point_1, point_2 = Point(x1, y1), Point(x2, y2)
pass
return point_1, point_2
def get_rectangle_point(self, rectangle):
point1, point2 = rectangle.get_point1(), rectangle.get_point2()
x1, x2 = point1.get_x(), point2.get_x()
y1, y2 = point1.get_y(), point2.get_y()
m_x, M_x = min(x1,x2),max(y1,y2)
m_y, M_y = min(y1,y2), max(y1,y2)
c_point1 = self.get_seg_line(Point(m_x,M_y),Point(M_x,M_y)) # 上水平线段
c_point2 = self.get_seg_line(Point(m_x, m_y), Point(M_x, m_y)) # 下水平线段
c_point3 = self.get_seg_line(Point(m_x, m_y), Point(m_x, M_y)) # 左垂直线段
c_point4 = self.get_seg_line(Point(M_x, m_y), Point(M_x, M_y)) # 右垂直线段
return c_point1,c_point2,c_point3,c_point4 # get_rectangle_point
def get_seg_line(self, point1, point2):
"""
返回一个直线和线段的交点
:param point1: 线段点一
:param point2: 线段点二
:return: 无交点或者无数交点都返回None,有一个交点返回一个交点
"""
x1, y1 = point1.get_x(), point1.get_y()
x2, y2 = point2.get_x(), point2.get_y()
if self.__b == 0: # 如果直线垂直
if x1 == x2: # 如果线段垂直
if abs(x1 + (self.__c / self.__a)) < 1e-6: # 重合
print("直线与线段重合")
pass
else:
print("无交点")
pass
return None
elif y1 == y2: # 线段水平
if min(x1, x2) <= -(self.__c / self.__a) <= max(x1, x2): # 相交
c_x = -(self.__c / self.__a)
c_y = y1
c_point = Point(c_x, c_y)
pass
else:
print("无交点")
pass
return None
elif self.__a == 0: # 直线水平
if x1 == x2: # 如果线段垂直
if min(y1, y2) <= -(self.__c / self.__b) <= max(y1, y2): # 相交
c_x = x1
c_y = -(self.__c / self.__b)
c_point = Point(c_x,c_y)
pass
else:
print("无交点")
return None
elif y1 == y2: # 线段水平
if abs(y1 + (self.__c / self.__b)) < 1e-6: # 重合
print("直线与线段重合")
pass
else:
print("无交点")
pass
return None
else: # 直线倾斜
if x1 == x2: # 如果线段垂直
x3 = -(self.__b * max(y1,y2) + self.__c) / self.__a
x4 = -(self.__b * min(y1,y2) + self.__c) / self.__a
if min(x3, x4) <= x1 <= max(x3,x4): # 有交点
c_point = self.get_line_point(Line(1, 0, -x1))
pass
else:
print("无交点")
return None
pass
elif y1 == y2: # 线段水平
y3 = -(self.__a * max(x1,x2) + self.__c) / self.__b
y4 = -(self.__a * min(x1,x2) + self.__c) / self.__b
if min(y3, y4) <= y1 <= max(y3,y4): # 有交点
c_point = self.get_line_point(Line(0, 1, -y1))
pass
else:
print("无交点")
return None
pass
pass
return c_point
class Circle:
def __init__(self,point, r):
"""
园的一般式(x-x0)^2+(y-y0)^2=r^2
:param point:圆心坐标
:param r:
"""
self.point = point
self.__r = r
pass
def get_center(self):
return self.point
def get_r(self):
return self.__r
pass
class Rectangle:
def __init__(self, point1, point2):
"""
两点确定一个矩形
:param point1: 第一个矩形
:param point2: 第二个矩形
"""
if abs(point1.get_x() - point2.get_x()) < 1e-6 or abs(point1.get_y() - point2.get_y()) < 1e-6:
print("无法构成矩形,程序退出")
exit(2)
self.__point1 = point1
self.__point2 = point2
pass
def get_point1(self):
return self.__point1
def get_point2(self):
return self.__point2
pass
if __name__ == '__main__':
line_1 = Line(1, 1, -1)
line_2 = Line(1, -1, 0)
print("直线x+y-1与x-y的交点为:",end="")
print(line_1.get_line_point(line_2))
cir = Circle(Point(0,0),1)
print("圆心为(0,0)半径为1的圆与直线x-y=0的交点为:",end="")
p1, p2 = line_2.get_cir_point(cir)
print(p1,p2)
rec = Rectangle(Point(0,0),Point(1,1))
p_1,p_2,p_3,p_4 = line_1.get_rectangle_point(rec)
print("(0,0)与(1,1)构成的矩形与直线x+y-1=0的交点为:",end="")
print(p_1,p_2,p_3,p_4)
pass
希望大家有认真查看代码学习,看到这里我可以告诉你,这是我三个小时临时写出来的东西,大体上没有任何毛病,但是有小bug需要你自己发现,我也不会去改了(不影响运行和部分正确结果),如果你发现了可以告诉我或者写在评论区。这个代码只是提供一个思路。毕竟当时三个小时写完就草草交了作业的代码质量肯定不会太好。