Think Python Exercise 15.1

15.1.1

定义一个叫做Circle类, 类的属性是圆心 (center) 和半径 (radius), 其中, 圆心 (center) 是一个 Point 类,而半径 (radius) 是一个数字。

实例化一个圆心 (center) 为 (150, 100) ,半径 (radius) 为 75 的Circle 对象。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Circle:
    """属性:圆心center、半径radius
    圆心是一个Point类
    半径是一个数字
    """
    
class Point:
    """表示一个二维的点
    """
    
bob = Circle()
bob.center = Point()
bob.center.x = 150
bob.center.y = 100
bob.radius = 75

15.1.2

编写一个名称为point_in_circle的函数,该函数可以接受一个圆类 (Circle) 对象和点类 (Point) 对象, 然后判断该点是否在圆内。在圆内则返回True 。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import math

class Circle:
    """属性:圆心center、半径radius
    圆心是一个Point类
    半径是一个数字
    """
    
class Point:
    """表示一个二维的点
    """
    
def point_in_circle(cir,poi):
    distance = math.sqrt((poi.x-cir.center.x)**2+(poi.y-cir.center.y)**2)#求点到圆心的距离来判断点是否在圆内
    
    if distance <= cir.radius:
        return True
    else:
        return False

bob = Circle()
bob.center = Point()
bob.center.x = 150
bob.center.y = 100
bob.radius = 75

tom = Point()
tom.x = 100
tom.y = 101

point_in_circle(bob,tom)

15.1.3

编写一个名称为rect_in_circle的函数,该函数接受一个圆类 (Circle) 对象和矩形(Rectangle) 对象,如果该矩形上的点完全在圆内或者在圆上则返回True。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import math

class Point:
    """表示一个二维的点
    """

class Circle:
    """属性:圆心center、半径radius
    圆心是一个Point类
    半径是一个数字
    """
    
class Rectangle:
    """Represents a rectangle.
    attributes: width, height, corner."""
    
    
def point_in_circle(cir,poi):
    distance = math.sqrt((poi.x-cir.center.x)**2+(poi.y-cir.center.y)**2)#求点到圆心的距离来判断点是否在圆内
    
    if distance <= cir.radius:
        return True
    else:
        return False

    
def rect_in_circle(cir,rect):
    #根据矩形左下角的坐标及长宽,得到其他三个点的坐标
    topleft = Point()
    topleft.x = rect.corner.x
    topleft.y = rect.corner.y + rect.height
    
    topright = Point()
    topright.x = rect.corner.x + rect.width
    topright.y = rect.corner.y + rect.height
    
    bottomright = Point()
    bottomright.x = rect.corner.x + rect.width
    bottomright.y = rect.corner.y

    # 如果矩形的四个点都在圆内或圆上,就可以认为矩形在圆内或圆上
    if point_in_circle(cir,topleft) and point_in_circle(cir,topright) and point_in_circle(cir, bottomright) and point_in_circle(cir, rect.corner):
        return True
    else:
        return False
    
bob = Circle()
bob.center = Point()
bob.center.x = 150
bob.center.y = 100
bob.radius = 75

box = Rectangle()
box.width = 100.0
box.height = 200.0
box.corner = Point()
box.corner.x = 0.0
box.corner.y = 0.0

rect_in_circle(bob,box)

写到这里插句题外话,我在写代码的时候遇到两次这个类似报错:“AttributeError: ‘Rectangle’ object has no attribute ‘x’”,但我咋看,我定义的函数咋没问题。最后发现,确实不是函数的问题,而是我调用错了函数。因为练习题与练习题之间是有关联的,我是直接在上一题的代码基础上来做这道题,在调用函数的时候,我错误地用了上一题的函数,调用了这一题这个函数对应的参数,所以就报错了。

15.1.4

编写一个名为 rect_circle_overlap 函数,该函数接受一个圆类对象和一个矩形类对象,如果矩形有任意一个角落在圆内则返回True 。或者写一个更具有挑战性的版本, 如果该矩形有任何部分落在圆内返回True 。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import math

class Point:
    """表示一个二维的点
    """

class Circle:
    """属性:圆心center、半径radius
    圆心是一个Point类
    半径是一个数字
    """
    
class Rectangle:
    """Represents a rectangle.
    attributes: width, height, corner."""
    
    
def point_in_circle(cir,poi):
    distance = math.sqrt((poi.x-cir.center.x)**2+(poi.y-cir.center.y)**2)#求点到圆心的距离来判断点是否在圆内
    
    if distance <= cir.radius:
        return True
    else:
        return False
    

def rect_circle_overlap(cir, rect):
    #根据矩形左下角的坐标及长宽,得到其他三个点的坐标
    topleft = Point()
    topleft.x = rect.corner.x
    topleft.y = rect.corner.y + rect.height
    
    topright = Point()
    topright.x = rect.corner.x + rect.width
    topright.y = rect.corner.y + rect.height
    
    bottomright = Point()
    bottomright.x = rect.corner.x + rect.width
    bottomright.y = rect.corner.y
    
    # 矩形是否有角落在圆内
    if point_in_circle(cir,topleft) or point_in_circle(cir,topright) or point_in_circle(cir, bottomright) or point_in_circle(cir, rect.corner):
        return True
    else:
        return False
    
bob = Circle()
bob.center = Point()
bob.center.x = 150
bob.center.y = 100
bob.radius = 75

box = Rectangle()
box.width = 100.0
box.height = 200.0
box.corner = Point()
box.corner.x = 100
box.corner.y = 90

rect_circle_overlap(bob,box)

这里也就是把上一段代码里的 and 换成了 or、改了个函数名。函数其他部分一点都没变。