计算椭圆内的点

时间:2011-11-18 19:27:35

标签: python matplotlib ellipse

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

enter image description here

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

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):
            .....

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

3 个答案:

答案 0 :(得分:8)

这可能与您正在做的事情类似。我只是想看看是否 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()

此代码生成下图: enter image description here

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

答案 1 :(得分:2)

你复杂化了。根据椭圆的几何定义,不需要计算焦点和到焦点等的距离。如果你知道长轴和短轴(你这么做),只需挤压整个问题(例如,两者都是1.0,例如,将x-centerx和y-centery除以x轴和y轴)然后问题是否为点在椭圆里面就是

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

P.S。:一般来说,这方面的好建议是:如果你可以通过不实际计算距离而是在其广场的范围内保持舒适来做同样的事情,则不sqrt

答案 2 :(得分:1)

以下是一些适合您的想法:

  • 你有正确的想法移动代码来计算循环外的焦点。
  • 通过移除平方根可以加快距离计算。换句话说,我们知道a < b隐含sqrt(a) < sqrt(b),因此无需计算平方根。
  • 如果椭圆是同心的并且长轴与x轴平行,则可以通过重新调整x值将椭圆问题简化为圆问题。

此外,这里有一个次要的编码。 if-statement 不需要返回 True False 。相反,您可以返回条件表达式:

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