题目

image-20200909121457880

分析

点C 到 点P 的距离 与半径r进行比大小使用两点间的距离公式即可 , 关于 Q1Q_1Q2Q_2点的坐标 考虑联立二元二次方程组进行求解 .

  1. 利用切线与半径垂直 , 有 : (yqyc)(xqxc)(yqyp)(xqxp)=1\frac{(y_q - y_c)}{(x_q - x_c)} \cdot \frac{(y_q - y_p)}{(x_q - x_p)} = -1
  2. 利用切点到圆心的距离等于半径 , 有 : (yqyc)2+(xqxc)2=r2(y_q - y_c) ^ 2 + (x_q - x_c) ^ 2 = r ^ 2

解此二元方程组即可得出切点坐标 .

Python代码实现

久闻Python中存在各种强大的包 , “后人” 无需重复造轮子, 直接引用包即可实现自己的需求 . 因此 , 对于一个简单的解方程问题 , 解决起来只需两行代码 .

经过搜索引擎的简单搜索 ,发现了许多Python中解方程的方法 , 但是考虑到本题中所需求解的方程是二元二次方程 , 且所需结果为全部解 . 因此使用网上所说的sympy包可以很好的解决该问题. 下面是该包中solve函数的基本用法示例 :

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
from sympy import *

c = input("请输入C点的坐标,用英文逗号隔开:")
c = c.split(",") # 分隔字符串
c = [float(c[i]) for i in range(len(c))]
p = input("请输入P点的坐标,用英文逗号隔开:")
p = p.split(",")
p = [float(p[i]) for i in range(len(p))]
r = float(input("请输入圆的半径:"))

while r ** 2 >= ((c[0]-p[0]) ** 2 + (c[1]-p[1]) ** 2) :
print("P点不在圆外 , 请重新输入:")
c = input("请输入C点的坐标,用英文逗号隔开:")
c = c.split(",")
c = [float(c[i]) for i in range(len(c))]
p = input("请输入P点的坐标,用英文逗号隔开:")
p = p.split(",")
p = [float(p[i]) for i in range(len(p))]
r = float(input("请输入圆的半径:"))
else:
x = Symbol("x")
y = Symbol("y")
ans = solve([(x-c[0]) ** 2 + (y - c[1]) ** 2 - r**2 , (y-c[1])*(y-p[1])+(x-c[0])*(x-p[0])] , [x,y]) # 第一个参数列表是方程组 , 第二个参数列表是未知数
print("Q1点的坐标:",ans[0])
print("Q2点的坐标:",ans[1])

我们使用一个可以口算的数据进行测试:

image-20200909123355774

可以看出 , 计算结果正确 .

测试题目数据:

image-20200909123624578

image-20200909123720592