Drawing elliptical orbit in Python (using numpy, matplotlib)

后端 未结 3 637
轻奢々
轻奢々 2020-12-21 13:12

I wonder how can I draw elliptical orbit by using the equation ay2 + bxy + cx + dy + e = x2 ?

I have first determined the a,b,c,d,e constants a

3条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-21 13:34

    Intro

    Easiest thing would be to parametrize this equation. As @Escualo suggests, you could introduce a variable t and parametrize x and y along that. Parametrizing means separating your equation into two separate equations for x and y individually in terms of t. So you would have x = f(t) and y = g(t) for some values of t. You could then plot the x, y pairs that result for each value of t.

    The catch here is that your ellipse is rotated (the x*y coupling term is an indication of that). To separate the equations, you have to first transform the equation to get rid of the coupling term. This is the same as finding a set of axes that are rotated by the same angle as the ellipse, parametrzing along those axes, then rotating the result back. Check out this forum post for a general overview.

    Math

    You first need to find the angle of rotation of the ellipse's axes with respect to the x-y coordinate plane.

    \theta = \frac{1}{2} tan^{-1}(\frac{b}{-1 - a})

    Your equation then transforms to

    a'x'^2+b'y'^2+c'x+d'y'+e=0

    where

    a'=-cos^2(\theta)+b*sin(\theta)cos(\theta)+a*sin^2(\theta)

    b'=-sin^2(\theta)-b*sin(\theta)cos(\theta)+a*cos^2(\theta)

    c'=c*cos(\theta)+d*sin(\theta)

    d'=-c*sin(\theta)+d*cos(\theta)

    e'=e

    To find the (nearly) standard form of the ellipse, you can complete the squares for the x' and y' portions and rearrange the equation slightly:

    \frac{(x'-h)^2}{a''^2}+\frac{(y'-k)^2}{b''^2}=c''

    where

    a''=\frac{1}{\sqrt{a'}}

    b''=\frac{1}{\sqrt{b'}}

    c''=\frac{c'^2}{4a'}+\frac{d'^2}{4b'}-e'

    h=-\frac{c'}{2a'}

    k=-\frac{d'}{2b'}

    Since you know \theta, you can now parametrize the equations for x' and y':

    x'=h+a''\sqrt{c''}sin(t)

    y'=k+b''\sqrt{c''}cos(t)

    You would then rotate back into normal x-y space using the formulas

    x=x'cos(\theta)-y'sin(\theta)

    and

    y=x'sin(\theta)+y'cos(\theta)

    Code

    The code to get the x- and y- arrays to pass to plt.plot is now relatively straightforward:

    def computeEllipse(a, b, c, d, e):
        """
        Returns x-y arrays for ellipse coordinates.
        Equation is of the form a*y**2 + b*x*y + c*x + d*y + e = x**2
        """
        # Convert x**2 coordinate to +1
        a = -a
        b = -b
        c = -c
        d = -d
        e = -e
        # Rotation angle
        theta = 0.5 * math.atan(b / (1 - a))
        # Rotated equation
        sin = math.sin(theta)
        cos = math.cos(theta)
        aa = cos**2 + b * sin * cos + a * sin**2
        bb = sin**2 - b * cos * sin + a * cos**2
        cc = c * cos + d * sin
        dd = -c * sin + d * cos
        ee = e
        # Standard Form
        axMaj = 1 / math.sqrt(aa)
        axMin = 1 / math.sqrt(bb)
        scale = math.sqrt(cc**2 / (4 * aa) + dd**2 / (4 * bb) - ee)
        h = -cc / (2 * aa)
        k = -dd / (2 * bb)
        # Parametrized Equation
        t = np.linspace(0, 2 * math.pi, 1000)
        xx = h + axMaj * scale * np.sin(t)
        yy = k + axMin * scale * np.cos(t)
        # Un-rotated coordinates
        x = xx * cos - yy * sin
        y = xx * sin + yy * cos
    
        return x, y
    

    To actually use the code:

    from matplotlib import pyplot as plt
    
    a = -4.10267300566
    b = 1.10642410023
    c = 0.39735696603
    d = 3.05101004127
    e = -0.370426134994
    
    lines = plt.plot(*computeEllipse(a, b, c, d, e))
    

    To overplot your original points on the ellipse:

    x = [1.02, 0.95, 0.87, 0.77, 0.67, 0.56, 0.44, 0.30, 0.16, 0.01]
    y = [0.39, 0.32, 0.27, 0.22, 0.18, 0.15, 0.13, 0.12, 0.12, 0.15]
    ax = lines[0].axes
    ax.plot(x, y, 'r.')
    

    The result is the following image:

    plot

    Note

    Keep in mind that the forum post I linked to uses a different notation than the one you do. Their equation is Ax2 + Bxy + Cy2 + Dx + Ey + F = 0. This is a bit more standard than your form of ay2 + bxy - x2 + cx + dy + e = 0. All of the math is in terms of your notation.

提交回复
热议问题