在给出焦点的情况下在matplotlib中绘制椭圆

时间:2017-02-16 03:21:38

标签: python numpy matplotlib

椭圆的方程是:

sqrt((x-a1)**2 + (y-b1)**2) + np.sqrt((x-a2)**2 + (y-b2)**2) = c

焦点是(a1, b1)(a2, b2)c也是众所周知的。如何使用matplotlib在python中绘制它?

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以在某个变量t中以参数方式表示椭圆。例如,你可以查看Wikipedia以了解如何做到这一点。

在下面的代码中,我从您提供的参数中导出了参数化表格所需的参数。

# Example focii and sum-distance
a1 = 1
b1 = 2
a2 = 5
b2 = 7
c = 9

# Compute ellipse parameters
a = c / 2                                # Semimajor axis
x0 = (a1 + a2) / 2                       # Center x-value
y0 = (b1 + b2) / 2                       # Center y-value
f = np.sqrt((a1 - x0)**2 + (b1 - y0)**2) # Distance from center to focus
b = np.sqrt(a**2 - f**2)                 # Semiminor axis
phi = np.arctan2((b2 - b1), (a2 - a1))   # Angle betw major axis and x-axis

# Parametric plot in t
resolution = 1000
t = np.linspace(0, 2*np.pi, resolution)
x = x0 + a * np.cos(t) * np.cos(phi) - b * np.sin(t) * np.sin(phi)
y = y0 + a * np.cos(t) * np.sin(phi) + b * np.sin(t) * np.cos(phi)

# Plot ellipse
plt.plot(x, y)

# Show focii
plt.plot(a1, b1, 'bo')
plt.plot(a2, b2, 'bo')

plt.axis('equal')
plt.show()

这可以满足您的需求:

Ellipse plot

答案 1 :(得分:1)

您需要2个X或Y列表或数组,以使元素满足椭圆方程

通常的椭圆绘图解决方案通过中心(或焦点)角度参数化椭圆方程,使X,Y函数单值为0到2pi的角度

我在Drawing elliptical orbit in Python (using numpy, matplotlib)中展示了一个解决方案 Y作为X的函数,具有黑客感觉"感觉" xrange,然后将每个x的双Y解决方案拼凑在一起

只需将代码放入等式中的最小模数,对于a1 = a2

就会失败

符号解决方案需要一分钟左右的运行时间

import numpy as np
import matplotlib.pyplot as plt
from sympy import *  

# sqrt((x-a1)**2 + (y-b1)**2) + np.sqrt((x-a2)**2 + (y-b2)**2) = c
coeffs = [1, 0, -1, 0, 4]
xs = [coeffs[0], coeffs[2]]

def ysolv(coeffs):
    x,y,a1,b1,a2,b2,c = symbols('x y a1 b1 a2 b2 c', real = True)
    ellipse = sqrt((x-a1)**2 + (y-b1)**2) + sqrt((x-a2)**2 + (y-b2)**2) - c
    y_sols = solve(ellipse, y)
    print(*y_sols, sep='\n')

    num_coefs = [(a, f) for a, f in (zip([a1,b1,a2,b2,c], coeffs))]
    y_solsf0 = y_sols[0].subs(num_coefs)
    y_solsf1 = y_sols[1].subs(num_coefs)
    print(y_solsf0, '\n', y_solsf1)

    f0 = lambdify([x], y_solsf0)
    f1 = lambdify([x], y_solsf1)
    return f0, f1

f0, f1 = ysolv(coeffs)

y0 = [f0(x) for x in xs]
y1 = [f1(x) for x in xs]

def feeloutXrange(f, midx, endx):
    fxs = []
    x = midx
    while True:
        try: f(x)
        except:
            break
        fxs.append(x)
        x += (endx - midx)/200
    return fxs

midx = (min(xs) + max(xs))/2    

xpos = feeloutXrange(f0, midx, max(xs))
xnegs = feeloutXrange(f0, midx, min(xs))
xs_ellipse = xnegs[::-1] + xpos[1:]

y0s = [f0(x) for x in xs_ellipse]
y1s = [f1(x) for x in xs_ellipse]

ys_ellipse = y0s + y1s[::-1] + [y0s[0]] # add y start point to end to close drawing

xs_ellipse = xs_ellipse + xs_ellipse[::-1] + [xs_ellipse[0]] # added x start point  

plt.plot(xs_ellipse, ys_ellipse)
plt.show()

(-c*sqrt((a1**2 - 2*a1*a2 + a2**2 + b1**2 - 2*b1*b2 + b2**2 - c**2)*(a1**2 + 2*a1*a2 - 4*a1*x + a2**2 - 4*a2*x + b1**2 - 2*b1*b2 + b2**2 - c**2 + 4*x**2))*(-b1 + b2 + c)*(b1 - b2 + c) + (b1**2 - 2*b1*b2 + b2**2 - c**2)*(-a1**2*b1 + a1**2*b2 + 2*a1*b1*x - 2*a1*b2*x + a2**2*b1 - a2**2*b2 - 2*a2*b1*x + 2*a2*b2*x - b1**3 + b1**2*b2 + b1*b2**2 + b1*c**2 - b2**3 + b2*c**2))/(2*(-b1 + b2 + c)*(b1 - b2 + c)*(b1**2 - 2*b1*b2 + b2**2 - c**2))
(c*sqrt((a1**2 - 2*a1*a2 + a2**2 + b1**2 - 2*b1*b2 + b2**2 - c**2)*(a1**2 + 2*a1*a2 - 4*a1*x + a2**2 - 4*a2*x + b1**2 - 2*b1*b2 + b2**2 - c**2 + 4*x**2))*(-b1 + b2 + c)*(b1 - b2 + c) + (b1**2 - 2*b1*b2 + b2**2 - c**2)*(-a1**2*b1 + a1**2*b2 + 2*a1*b1*x - 2*a1*b2*x + a2**2*b1 - a2**2*b2 - 2*a2*b1*x + 2*a2*b2*x - b1**3 + b1**2*b2 + b1*b2**2 + b1*c**2 - b2**3 + b2*c**2))/(2*(-b1 + b2 + c)*(b1 - b2 + c)*(b1**2 - 2*b1*b2 + b2**2 - c**2))
sqrt(-48*x**2 + 192)/8 
 -sqrt(-48*x**2 + 192)/8

enter image description here

其他答案使用参数化变换方法

我特别喜欢表达同情心,为你解决方程,而不是有人亲手解决它

只需要为特定的Ellipse参数化找到一次符号表达式,然后可以简单地对符号表达式进行硬编码:

"""   
for Ellipse equation:
sqrt((x-a1)**2 + (y-b1)**2) + sqrt((x-a2)**2 + (y-b2)**2) = c   

sympy solution to Ellipse equation, only have to run once to get y_sols
symbolic expression to paste into ysolv below

#def symEllipse():
#    x,y,a1,b1,a2,b2,c = symbols('x y a1 b1 a2 b2 c', real = True)
#    ellipse = sqrt((x-a1)**2 + (y-b1)**2) + sqrt((x-a2)**2 + (y-b2)**2) - c
#    y_sols = solve(ellipse, y)
#    print(*y_sols, sep='\n')

"""

coeffs = [1, 1, -1, -1, 3]
xs = [coeffs[0], coeffs[2]]

def ysolv(coeffs):

    x,y,a1,b1,a2,b2,c = symbols('x y a1 b1 a2 b2 c', real = True)

    y_sols = [
        (-c*sqrt((a1**2 - 2*a1*a2 + a2**2 + b1**2 - 2*b1*b2 + b2**2 - c**2)*
          (a1**2 + 2*a1*a2 - 4*a1*x + a2**2 - 4*a2*x + b1**2 - 2*b1*b2 + b2**2
           - c**2 + 4*x**2))*(-b1 + b2 + c)*(b1 - b2 + c) + (b1**2 - 2*b1*b2 +
           b2**2 - c**2)*(-a1**2*b1 + a1**2*b2 + 2*a1*b1*x - 2*a1*b2*x +
           a2**2*b1 - a2**2*b2 - 2*a2*b1*x + 2*a2*b2*x - b1**3 + b1**2*b2 +
           b1*b2**2 + b1*c**2 - b2**3 + b2*c**2))/(2*(-b1 + b2 + c)*
           (b1 - b2 + c)*(b1**2 - 2*b1*b2 + b2**2 - c**2)),
          (c*sqrt((a1**2 - 2*a1*a2 + a2**2 + b1**2 - 2*b1*b2 + b2**2 - c**2)*
          (a1**2 + 2*a1*a2 - 4*a1*x + a2**2 - 4*a2*x + b1**2 - 2*b1*b2 + b2**2
           - c**2 + 4*x**2))*(-b1 + b2 + c)*(b1 - b2 + c) + (b1**2 - 2*b1*b2 +
           b2**2 - c**2)*(-a1**2*b1 + a1**2*b2 + 2*a1*b1*x - 2*a1*b2*x + 
           a2**2*b1 - a2**2*b2 - 2*a2*b1*x + 2*a2*b2*x - b1**3 + b1**2*b2 + 
           b1*b2**2 + b1*c**2 - b2**3 + b2*c**2))/(2*(-b1 + b2 + c)*
           (b1 - b2 + c)*(b1**2 - 2*b1*b2 + b2**2 - c**2))
          ]
    num_coefs = [(a, f) for a, f in (zip([a1,b1,a2,b2,c], coeffs))]
    y_solsf0 = y_sols[0].subs(num_coefs)
    y_solsf1 = y_sols[1].subs(num_coefs)
    print(y_solsf0, '\n', y_solsf1)

    f0 = lambdify([x], y_solsf0)
    f1 = lambdify([x], y_solsf1)
    return f0, f1