寻找两个圆的交点
Finding the intersection of two circles
我试图在 Python(使用 Matplotlib)中找到两个圆圈之间的交点,但无法取回任何值。
我通过为每个单独的圆创建 X 和 Y 的列表来做到这一点(Matplotlib 在绘制圆时将第一个参数作为 X 值,将第二个参数作为 Y 值),然后相应地与列表相交(例如,circle1 x 值与 circle2 x 值)。
import numpy
import math
import matplotlib.pyplot as plt
import random
def origin_circle():
global x_points
global y_points
global r
global n
r=1
n=2**16
x_points=[(r*math.cos(t)) for t in numpy.linspace(0, 2*numpy.pi*r, n+1)]
y_points=[(r*math.sin(t)) for t in numpy.linspace(0, 2*numpy.pi*r, n+1)]
def new_circle(x_offset, y_offset):
global x_points1
global y_points1
x_points1=[x_offset+(r*math.cos(t)) for t in numpy.linspace(0, 2*numpy.pi*r, n+1)]
y_points1=[y_offset+(r*math.sin(t)) for t in numpy.linspace(0, 2*numpy.pi*r, n+1)]
origin_circle()
new_center= random.randint(0, len(x_points))
x_offset = x_points[new_center]
y_offset = y_points[new_center]
new_circle(x_offset, y_offset)
print(set(x_points1).intersection(set(x_points)))
print(set(y_points1).intersection(set(y_points)))
我希望取回值,但返回的集合是空的。
看看你生成了什么:
new_center= random.randint(0, len(x_points))
x_offset = x_points[new_center]
y_offset = y_points[new_center]
new_circle(x_offset, y_offset)
# I'm sorting these for easier visualization
print(sorted(x_points))
print(sorted(x_points1))
输出:
[-1.0, -0.9807852804032304, -0.9807852804032304, -0.9238795325112868,
-0.9238795325112867, -0.8314696123025455, -0.8314696123025453, -0.7071067811865477,
-0.7071067811865475, -0.5555702330196022, -0.555570233019602, -0.38268343236509034,
-0.3826834323650897, -0.19509032201612866, -0.1950903220161282,
-1.8369701987210297e-16, 6.123233995736766e-17, 0.1950903220161283,
0.19509032201612833, 0.38268343236508984, 0.38268343236509, 0.5555702330196018
, 0.5555702330196023, 0.7071067811865474, 0.7071067811865476, 0.8314696123025452,
0.8314696123025452, 0.9238795325112865, 0.9238795325112867, 0.9807852804032303,
0.9807852804032304, 1.0, 1.0]
[-2.0, -1.9807852804032304, -1.9807852804032304, -1.923879532511287,
-1.9238795325112867, -1.8314696123025453, -1.8314696123025453, -1.7071067811865477,
-1.7071067811865475, -1.5555702330196022, -1.555570233019602, -1.3826834323650903,
-1.3826834323650896, -1.1950903220161286, -1.1950903220161282, -1.0000000000000002,
-0.9999999999999999, -0.8049096779838717, -0.8049096779838717, -0.6173165676349102,
-0.6173165676349099, -0.44442976698039816, -0.4444297669803977, -0.29289321881345265,
-0.2928932188134524, -0.16853038769745476, -0.16853038769745476,
-0.07612046748871348, -0.07612046748871326, -0.01921471959676968,
-0.01921471959676957, 0.0, 0.0]
首先,你已经生成了独立的坐标列表;你没有 points 作为任何类型的协调对。
其次,您没有列出所有圆上的点:您不能,因为那是一个无限集合。相反,您生成了一个等间距的列表(好吧,x
和 y
每个列表)没有数学理由期望您将有一个 exact 匹配任何两个这样的坐标,更不用说碰巧选择 每个 圆上的两个点 正好 交点。
你什么也得不到,因为你的列表没有共同点。如果要找到交点,则需要通过代数求解、逐次逼近或其他一些方法来实现。例如,取两个圆的差值并求解 y == 0
.
的方程
如果您正在处理圆,获得交点的正确方法是使用一些代数。可能的情况有四种:不相交、一次相交(相切)、两次相交、无限相交(它们是同一个圆)。我们重点说说两种相交的情况。
从 https://math.stackexchange.com/a/256123/647423 你可以做的是沿着穿过两个交点的直线获得一个与 x 和 y 相关的线性方程:
−2x(x1center−x2center)−2y(y1center−y2center) = (r1)^2−(r2)^2−((x1center)^2−(x2center)^2)−((y1center)^2−(y2center)^2).
从这里你得到一个关于 x 的 y 的公式,然后将 y 代入你的一个圆公式以获得 x 的二次方程。
如果你不想实现二次方程求解器,你可以像这样使用 numpy.roots:
root_array = np.roots(quadratic_coeff, linear_coeff, constant_coef)
求两圆交点的正确方法是代数。由于坐标系(实数)的无限精度,您不能使用点(x,y 坐标)来完成。
如果两个圆在两点相交,那么有一种直接的方法可以计算出这两个交点。 Intersection of two circles
.
部分详细介绍了代数 here
我们还可以排除两个圆不相交的情况,如下所示
- 如果两个圆原点之间的距离 > 两个圆的半径之和,则表示圆是分开的,因此不相交。
- 如果两个圆原点之间的距离<两个圆半径的绝对差,则表示一个圆包含在另一个圆中,因此不相交。
代码为return两个圆的两个交点。每个cricle由其中心(x,y)和半径(r)描述
def get_intersections(x0, y0, r0, x1, y1, r1):
# circle 1: (x0, y0), radius r0
# circle 2: (x1, y1), radius r1
d=math.sqrt((x1-x0)**2 + (y1-y0)**2)
# non intersecting
if d > r0 + r1 :
return None
# One circle within other
if d < abs(r0-r1):
return None
# coincident circles
if d == 0 and r0 == r1:
return None
else:
a=(r0**2-r1**2+d**2)/(2*d)
h=math.sqrt(r0**2-a**2)
x2=x0+a*(x1-x0)/d
y2=y0+a*(y1-y0)/d
x3=x2+h*(y1-y0)/d
y3=y2-h*(x1-x0)/d
x4=x2-h*(y1-y0)/d
y4=y2+h*(x1-x0)/d
return (x3, y3, x4, y4)
让我们通过绘制
来测试它(视觉上)
# intersection circles
x0, y0 = 0, 0
r0 = 5
x1, y1 = 2, 2
r1 = 5
# intersecting with (x1, y1) but not with (x0, y0)
x2, y2 = -1,0
r2 = 2.5
circle1 = plt.Circle((x0, y0), r0, color='b', fill=False)
circle2 = plt.Circle((x1, y1), r1, color='b', fill=False)
circle3 = plt.Circle((x2, y2), r2, color='b', fill=False)
fig, ax = plt.subplots()
ax.set_xlim((-10, 10))
ax.set_ylim((-10, 10))
ax.add_artist(circle1)
ax.add_artist(circle2)
ax.add_artist(circle3)
intersections = get_intersections(x0, y0, r0, x1, y1, r1)
if intersections is not None:
i_x3, i_y3, i_x4, i_y4 = intersections
plt.plot([i_x3, i_x4], [i_y3, i_y4], '.', color='r')
intersections = get_intersections(x0, y0, r0, x2, y2, r2)
if intersections is not None:
i_x3, i_y3, i_x4, i_y4 = intersections
plt.plot([i_x3, i_x4], [i_y3, i_y4], '.', color='r')
intersections = get_intersections(x1, y1, r1, x2, y2, r2)
if intersections is not None:
i_x3, i_y3, i_x4, i_y4 = intersections
plt.plot([i_x3, i_x4], [i_y3, i_y4], '.', color='r')
plt.gca().set_aspect('equal', adjustable='box')
输出:
math/geometry 事物的语言错误。这是更合适的语言 (WL)
中的样子
Circle @@@ Thread @ {RandomReal[{-1,1},{3,2}], RandomReal[{.5,1},3]} //
Graphics[{
#, Red,
RegionIntersection @@@ #~Subsets~{2}
}]&
上面绘制交点的代码没有正确绘制交点。
我已经调整了代码来绘制它们如下:
import matplotlib.pyplot as plt
import math
def get_intersections(x0, y0, r0, x1, y1, r1):
# circle 1: (x0, y0), radius r0
# circle 2: (x1, y1), radius r1
d=math.sqrt((x1-x0)**2 + (y1-y0)**2)
# non intersecting
if d > r0 + r1 :
return {}
# One circle within other
if d < abs(r0-r1):
return {}
# coincident circles
if d == 0 and r0 == r1:
return {}
else:
a=(r0**2-r1**2+d**2)/(2*d)
h=math.sqrt(r0**2-a**2)
x2=x0+a*(x1-x0)/d
y2=y0+a*(y1-y0)/d
x3=x2+h*(y1-y0)/d
y3=y2-h*(x1-x0)/d
x4=x2-h*(y1-y0)/d
y4=y2+h*(x1-x0)/d
return x3, y3, x4, y4
# intersection circles
x0, y0 = 0, 0
r0 = 5
x1, y1 = 2, 2
r1 = 5
# intersecting with (x1, y1) but not with (x0, y0)
x2, y2 = -1,0
r2 = 2.5
circle1 = plt.Circle((x0, y0), r0, color='b', fill=False)
circle2 = plt.Circle((x1, y1), r1, color='b', fill=False)
circle3 = plt.Circle((x2, y2), r2, color='b', fill=False)
fig = plt.figure(figsize = (10, 10))
plt.grid(True)
ax = fig.add_subplot(111)
ax.set_xlim((-10, 10))
ax.set_ylim((-10, 10))
ax.add_artist(circle1)
ax.add_artist(circle2)
ax.add_artist(circle3)
intersections1 = get_intersections(x0, y0, r0, x1, y1, r1)
print(intersections1)
if len(intersections1) > 0:
print(intersections3)
i_x3, i_y3, i_x4, i_y4 = intersections1
#plt.plot([i_x3, i_x4], [i_y3, i_y4], 'o', color='r')
ax.scatter([i_x3, i_x4],[i_y3, i_y4] ,marker ='X',s=300,alpha=1)
intersections2 = get_intersections(x0, y0, r0, x2, y2, r2)
print(intersections2)
if len(intersections2) > 0:
i_x3, i_y3, i_x4, i_y4 = intersections2
plt.plot([i_x3, i_x4], [i_y3, i_y4], 'o', color='r')
ax.scatter([i_x3, i_x4],[i_y3, i_y4] ,marker ='X',s=300,alpha=1)
intersections3 = get_intersections(x1, y1, r1, x2, y2, r2)
if len(intersections3) > 0:
print(intersections3)
i_x3, i_y3, i_x4, i_y4 = intersections3
#plt.plot([i_x3, i_x4], [i_y3, i_y4], 'o', color='r')
ax.scatter([i_x3, i_x4],[i_y3, i_y4] ,marker ='X',s=300,alpha=1)
plt.gca().set_aspect('equal', adjustable='box')
图像中给出了输出:
我试图在 Python(使用 Matplotlib)中找到两个圆圈之间的交点,但无法取回任何值。
我通过为每个单独的圆创建 X 和 Y 的列表来做到这一点(Matplotlib 在绘制圆时将第一个参数作为 X 值,将第二个参数作为 Y 值),然后相应地与列表相交(例如,circle1 x 值与 circle2 x 值)。
import numpy
import math
import matplotlib.pyplot as plt
import random
def origin_circle():
global x_points
global y_points
global r
global n
r=1
n=2**16
x_points=[(r*math.cos(t)) for t in numpy.linspace(0, 2*numpy.pi*r, n+1)]
y_points=[(r*math.sin(t)) for t in numpy.linspace(0, 2*numpy.pi*r, n+1)]
def new_circle(x_offset, y_offset):
global x_points1
global y_points1
x_points1=[x_offset+(r*math.cos(t)) for t in numpy.linspace(0, 2*numpy.pi*r, n+1)]
y_points1=[y_offset+(r*math.sin(t)) for t in numpy.linspace(0, 2*numpy.pi*r, n+1)]
origin_circle()
new_center= random.randint(0, len(x_points))
x_offset = x_points[new_center]
y_offset = y_points[new_center]
new_circle(x_offset, y_offset)
print(set(x_points1).intersection(set(x_points)))
print(set(y_points1).intersection(set(y_points)))
我希望取回值,但返回的集合是空的。
看看你生成了什么:
new_center= random.randint(0, len(x_points))
x_offset = x_points[new_center]
y_offset = y_points[new_center]
new_circle(x_offset, y_offset)
# I'm sorting these for easier visualization
print(sorted(x_points))
print(sorted(x_points1))
输出:
[-1.0, -0.9807852804032304, -0.9807852804032304, -0.9238795325112868,
-0.9238795325112867, -0.8314696123025455, -0.8314696123025453, -0.7071067811865477,
-0.7071067811865475, -0.5555702330196022, -0.555570233019602, -0.38268343236509034,
-0.3826834323650897, -0.19509032201612866, -0.1950903220161282,
-1.8369701987210297e-16, 6.123233995736766e-17, 0.1950903220161283,
0.19509032201612833, 0.38268343236508984, 0.38268343236509, 0.5555702330196018
, 0.5555702330196023, 0.7071067811865474, 0.7071067811865476, 0.8314696123025452,
0.8314696123025452, 0.9238795325112865, 0.9238795325112867, 0.9807852804032303,
0.9807852804032304, 1.0, 1.0]
[-2.0, -1.9807852804032304, -1.9807852804032304, -1.923879532511287,
-1.9238795325112867, -1.8314696123025453, -1.8314696123025453, -1.7071067811865477,
-1.7071067811865475, -1.5555702330196022, -1.555570233019602, -1.3826834323650903,
-1.3826834323650896, -1.1950903220161286, -1.1950903220161282, -1.0000000000000002,
-0.9999999999999999, -0.8049096779838717, -0.8049096779838717, -0.6173165676349102,
-0.6173165676349099, -0.44442976698039816, -0.4444297669803977, -0.29289321881345265,
-0.2928932188134524, -0.16853038769745476, -0.16853038769745476,
-0.07612046748871348, -0.07612046748871326, -0.01921471959676968,
-0.01921471959676957, 0.0, 0.0]
首先,你已经生成了独立的坐标列表;你没有 points 作为任何类型的协调对。
其次,您没有列出所有圆上的点:您不能,因为那是一个无限集合。相反,您生成了一个等间距的列表(好吧,x
和 y
每个列表)没有数学理由期望您将有一个 exact 匹配任何两个这样的坐标,更不用说碰巧选择 每个 圆上的两个点 正好 交点。
你什么也得不到,因为你的列表没有共同点。如果要找到交点,则需要通过代数求解、逐次逼近或其他一些方法来实现。例如,取两个圆的差值并求解 y == 0
.
如果您正在处理圆,获得交点的正确方法是使用一些代数。可能的情况有四种:不相交、一次相交(相切)、两次相交、无限相交(它们是同一个圆)。我们重点说说两种相交的情况。
从 https://math.stackexchange.com/a/256123/647423 你可以做的是沿着穿过两个交点的直线获得一个与 x 和 y 相关的线性方程:
−2x(x1center−x2center)−2y(y1center−y2center) = (r1)^2−(r2)^2−((x1center)^2−(x2center)^2)−((y1center)^2−(y2center)^2).
从这里你得到一个关于 x 的 y 的公式,然后将 y 代入你的一个圆公式以获得 x 的二次方程。 如果你不想实现二次方程求解器,你可以像这样使用 numpy.roots:
root_array = np.roots(quadratic_coeff, linear_coeff, constant_coef)
求两圆交点的正确方法是代数。由于坐标系(实数)的无限精度,您不能使用点(x,y 坐标)来完成。
如果两个圆在两点相交,那么有一种直接的方法可以计算出这两个交点。 Intersection of two circles
.
我们还可以排除两个圆不相交的情况,如下所示
- 如果两个圆原点之间的距离 > 两个圆的半径之和,则表示圆是分开的,因此不相交。
- 如果两个圆原点之间的距离<两个圆半径的绝对差,则表示一个圆包含在另一个圆中,因此不相交。
代码为return两个圆的两个交点。每个cricle由其中心(x,y)和半径(r)描述
def get_intersections(x0, y0, r0, x1, y1, r1):
# circle 1: (x0, y0), radius r0
# circle 2: (x1, y1), radius r1
d=math.sqrt((x1-x0)**2 + (y1-y0)**2)
# non intersecting
if d > r0 + r1 :
return None
# One circle within other
if d < abs(r0-r1):
return None
# coincident circles
if d == 0 and r0 == r1:
return None
else:
a=(r0**2-r1**2+d**2)/(2*d)
h=math.sqrt(r0**2-a**2)
x2=x0+a*(x1-x0)/d
y2=y0+a*(y1-y0)/d
x3=x2+h*(y1-y0)/d
y3=y2-h*(x1-x0)/d
x4=x2-h*(y1-y0)/d
y4=y2+h*(x1-x0)/d
return (x3, y3, x4, y4)
让我们通过绘制
来测试它(视觉上)# intersection circles
x0, y0 = 0, 0
r0 = 5
x1, y1 = 2, 2
r1 = 5
# intersecting with (x1, y1) but not with (x0, y0)
x2, y2 = -1,0
r2 = 2.5
circle1 = plt.Circle((x0, y0), r0, color='b', fill=False)
circle2 = plt.Circle((x1, y1), r1, color='b', fill=False)
circle3 = plt.Circle((x2, y2), r2, color='b', fill=False)
fig, ax = plt.subplots()
ax.set_xlim((-10, 10))
ax.set_ylim((-10, 10))
ax.add_artist(circle1)
ax.add_artist(circle2)
ax.add_artist(circle3)
intersections = get_intersections(x0, y0, r0, x1, y1, r1)
if intersections is not None:
i_x3, i_y3, i_x4, i_y4 = intersections
plt.plot([i_x3, i_x4], [i_y3, i_y4], '.', color='r')
intersections = get_intersections(x0, y0, r0, x2, y2, r2)
if intersections is not None:
i_x3, i_y3, i_x4, i_y4 = intersections
plt.plot([i_x3, i_x4], [i_y3, i_y4], '.', color='r')
intersections = get_intersections(x1, y1, r1, x2, y2, r2)
if intersections is not None:
i_x3, i_y3, i_x4, i_y4 = intersections
plt.plot([i_x3, i_x4], [i_y3, i_y4], '.', color='r')
plt.gca().set_aspect('equal', adjustable='box')
输出:
math/geometry 事物的语言错误。这是更合适的语言 (WL)
中的样子 Circle @@@ Thread @ {RandomReal[{-1,1},{3,2}], RandomReal[{.5,1},3]} //
Graphics[{
#, Red,
RegionIntersection @@@ #~Subsets~{2}
}]&
上面绘制交点的代码没有正确绘制交点。 我已经调整了代码来绘制它们如下:
import matplotlib.pyplot as plt
import math
def get_intersections(x0, y0, r0, x1, y1, r1):
# circle 1: (x0, y0), radius r0
# circle 2: (x1, y1), radius r1
d=math.sqrt((x1-x0)**2 + (y1-y0)**2)
# non intersecting
if d > r0 + r1 :
return {}
# One circle within other
if d < abs(r0-r1):
return {}
# coincident circles
if d == 0 and r0 == r1:
return {}
else:
a=(r0**2-r1**2+d**2)/(2*d)
h=math.sqrt(r0**2-a**2)
x2=x0+a*(x1-x0)/d
y2=y0+a*(y1-y0)/d
x3=x2+h*(y1-y0)/d
y3=y2-h*(x1-x0)/d
x4=x2-h*(y1-y0)/d
y4=y2+h*(x1-x0)/d
return x3, y3, x4, y4
# intersection circles
x0, y0 = 0, 0
r0 = 5
x1, y1 = 2, 2
r1 = 5
# intersecting with (x1, y1) but not with (x0, y0)
x2, y2 = -1,0
r2 = 2.5
circle1 = plt.Circle((x0, y0), r0, color='b', fill=False)
circle2 = plt.Circle((x1, y1), r1, color='b', fill=False)
circle3 = plt.Circle((x2, y2), r2, color='b', fill=False)
fig = plt.figure(figsize = (10, 10))
plt.grid(True)
ax = fig.add_subplot(111)
ax.set_xlim((-10, 10))
ax.set_ylim((-10, 10))
ax.add_artist(circle1)
ax.add_artist(circle2)
ax.add_artist(circle3)
intersections1 = get_intersections(x0, y0, r0, x1, y1, r1)
print(intersections1)
if len(intersections1) > 0:
print(intersections3)
i_x3, i_y3, i_x4, i_y4 = intersections1
#plt.plot([i_x3, i_x4], [i_y3, i_y4], 'o', color='r')
ax.scatter([i_x3, i_x4],[i_y3, i_y4] ,marker ='X',s=300,alpha=1)
intersections2 = get_intersections(x0, y0, r0, x2, y2, r2)
print(intersections2)
if len(intersections2) > 0:
i_x3, i_y3, i_x4, i_y4 = intersections2
plt.plot([i_x3, i_x4], [i_y3, i_y4], 'o', color='r')
ax.scatter([i_x3, i_x4],[i_y3, i_y4] ,marker ='X',s=300,alpha=1)
intersections3 = get_intersections(x1, y1, r1, x2, y2, r2)
if len(intersections3) > 0:
print(intersections3)
i_x3, i_y3, i_x4, i_y4 = intersections3
#plt.plot([i_x3, i_x4], [i_y3, i_y4], 'o', color='r')
ax.scatter([i_x3, i_x4],[i_y3, i_y4] ,marker ='X',s=300,alpha=1)
plt.gca().set_aspect('equal', adjustable='box')
图像中给出了输出: