9

楕円の各リング内の特定のデータポイントを数えようとしています:

ここに画像の説明を入力

問題は、それをチェックする関数があることです。各楕円について、点がその中にあるかどうかを確認するには、3 つの入力を計算する必要があります。

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

しかし、その後、外側のループの焦点の各ペアを計算する必要があります..これを行うためのより効率的で賢い方法はありますか?

4

3 に答える 3

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()

このコードは、次の図を生成します。 ここに画像の説明を入力

これは単なる出発点であることを覚えておいてください。たとえばinWhichEllipse、r1 と r2 の 2 乗のリスト、つまり (r1*r1,r2*r2) のペアを受け入れるように変更すると、計算がさらに削減されます。

于 2011-11-18T20:22:55.933 に答える
2

あなたは物事を複雑にします。楕円の幾何学的定義に従って、焦点と焦点までの距離などを計算する必要はありません。長軸と短軸がわかっている場合は (知っている)、質問全体を少し絞って (たとえば、x-centerx と y-centery を xaxis と yaxis で割って、両方が 1.0 になるように)、点が楕円の中にあるのは単純です

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

PS: 一般的に、この分野での良いアドバイス:sqrt距離を実際に計算せずに、その正方形の領域に快適にとどまることで同じことができる場合は、いいえ。

于 2011-11-18T20:27:38.160 に答える
1

ここにあなたのためのいくつかのアイデアがあります:

  • 焦点を計算するためのコードをループの外に移動するという正しい考えがあります。
  • 平方根を削除することで、距離の計算を高速化できます。言い換えれば、私たちはa < b含意を知っているsqrt(a) < sqrt(b)ので、平方根を計算する必要はありません.
  • 楕円が同心円で、長軸が x 軸に平行である場合、x 値を再スケーリングすることにより、楕円の問題を円の問題に単純化できます。

また、ここに 1 つのマイナーなコーディング ニットがあります。TrueまたはFalseを返すif ステートメントは必要ありません。代わりに、条件式自体を返すことができます。

def in_ellipse(major_ax,d1,d2):
    return (d1+d2) <= 2*major_ax:
于 2011-11-18T20:20:38.947 に答える