【问题标题】:Counting points inside an ellipse计算椭圆内的点
【发布时间】:2012-01-01 13:06:27
【问题描述】:

我正在尝试计算每个椭圆环内的给定数据点:

问题是我有一个功能可以检查: 所以对于每个椭圆,要确定一个点是否在其中,必须计算三个输入:

def get_focal_point(r1,r2,center_x):
    # f = square root of r1-squared - r2-squared
    focal_dist = sqrt((r1**2) - (r2**2))
    f1_x = center_x - focal_dist
    f2_x = center_x + focal_dist
    return f1_x, f2_x

def get_distance(f1,f2,center_y,t_x,t_y):
    d1 = sqrt(((f1-t_x)**2) + ((center_y - t_y)**2)) 
    d2 = sqrt(((f2-t_x)**2) + ((center_y - t_y)**2))
    return d1,d2

def in_ellipse(major_ax,d1,d2):
    if (d1+d2) <= 2*major_ax:
        return True
    else:
        return False

现在我正在检查它是否在椭圆中:

for i in range(len(data.latitude)):
    t_x = data.latitude[i] 
    t_y = data.longitude[i] 
    d1,d2 = get_distance(f1,f2,center_y,t_x,t_y)
    d1_array.append(d1)
    d2_array.append(d2)
    if in_ellipse(major_ax,d1,d2) == True:
        core_count += 1
        # if the point is not in core ellipse 
        # check the next ring up
    else:
        for i in range(loop):
            .....

但是我必须计算外循环的每一对焦点.. 有没有更有效或更聪明的方法来做到这一点?

【问题讨论】:

  • 这些椭圆具有相同的比例和中心,我说得对吗?如果是这样,您可以通过例如识别它们。 r1 并创建一个函数,为每个点分配最小值 r1,该点在省略号中。我是对的还是我误解了什么?
  • 椭圆是否同心,它们的大小是否按固定比例变化(它们看起来像)?如果是这样,您应该能够使用dist_to_point / size_per_ellipse 之类的内容来判断一个点的位置。
  • 是的,它们是同心的!但是 dist_to_point/size_per_ellipse 不仅适用于圆圈吗?
  • @gddc:这与我相信我所说的相似,除了 到点的距离 并不能确定它何时落下 - 更重要的是一对“latitude”和“longitude”,因为这些椭圆不是圆形。
  • 没错! @g.d.d.c 的解决方案在我看来只适用于圈子。

标签: python matplotlib ellipse


【解决方案1】:

这可能与您正在做的事情相似。我只是想看看是否 f(x,y) = x^2/r1^2 + y^2/r2^2 = 1。

当 f(x,y) 大于 1 时,点 x,y 在椭圆之外。当它较小时,它在椭圆内。我遍历每个椭圆以找到 f(x,y) 小于 1 的那个。

代码也没有考虑以原点为中心的椭圆。包含此功能是一个小改动。

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np

def inWhichEllipse(x,y,rads):
    '''
    With a list of (r1,r2) pairs, rads, return the index of the pair in which
    the point x,y resides. Return None as the index if it is outside all 
    Ellipses.
    '''
    xx = x*x
    yy = y*y

    count = 0
    ithEllipse =0
    while True:
        rx,ry = rads[count]
        ellips = xx/(rx*rx)+yy/(ry*ry)
        if ellips < 1:
            ithEllipse = count
            break
        count+=1
        if count >= len(rads):
            ithEllipse = None
            break

    return ithEllipse

rads = zip(np.arange(.5,10,.5),np.arange(.125,2.5,.25))

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(-15,15)
ax.set_ylim(-15,15)

# plot Ellipses
for rx,ry in rads:
    ellipse = patches.Ellipse((0,0),rx*2,ry*2,fc='none',ec='red')    
    ax.add_patch(ellipse)

x=3.0
y=1.0
idx = inWhichEllipse(x,y,rads)
rx,ry = rads[idx]
ellipse = patches.Ellipse((0,0),rx*2,ry*2,fc='none',ec='blue')    
ax.add_patch(ellipse)

if idx != None:
    circle = patches.Circle((x,y),.1)
    ax.add_patch(circle)

plt.show()

此代码生成下图:

请记住,这只是一个起点。一方面,您可以更改 inWhichEllipse 以接受 r1 和 r2 的平方列表,即 (r1*r1,r2*r2) 对,这将进一步减少计算。

【讨论】:

    【解决方案2】:

    你把事情复杂化了。无需根据椭圆的几何定义计算焦点和到焦点的距离等。如果您知道长轴和短轴(您知道),只需稍微压缩整个问题(例如,通过将 x-centerx 和 y-centery 除以 xaxis 和 yaxis 来使两者均为 1.0)然后问题是否该点在椭圆里面是简单的

    xnormalized**2 + ynormalized**2 <= 1
    

    P.S.:总的来说,这个领域的好建议:不要sqrt,如果你可以通过不实际计算距离而是舒适地保持在平方范围内来做同样的事情。

    【讨论】:

    • +1 我认为@herby 比我表达的要好得多。这个问题可以大大简化。
    【解决方案3】:

    这里有一些想法给你:

    • 您的想法是正确的,将用于计算焦点的代码移到循环之外。
    • 可以通过去除平方根来加快距离计算。换句话说,我们知道a &lt; b 隐含sqrt(a) &lt; sqrt(b),所以不需要计算平方根。
    • 如果椭圆是同心的并且长轴平行于 x 轴,您可以通过重新调整 x 值来将椭圆问题简化为圆问题。

    另外,这里有一个小的编码技巧。 if-statement 不需要返回 TrueFalse。相反,您可以返回条件表达式本身:

    def in_ellipse(major_ax,d1,d2):
        return (d1+d2) <= 2*major_ax:
    

    【讨论】:

    • 非常感谢,这对您很有帮助。虽然主轴并不总是 x 轴...我将在循环中对多组数据执行此操作,因此主轴不一定是 x 轴。
    • 如果轴穿过原件,您仍然可以使用单个复数乘法将椭圆问题旋转和缩放成圆形问题。此外,如果 x,y 表示为复数,则距离计算会简化为 abs(p)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多