我想知道如何使用方程ay 2 + bxy + cx + dy + e = x 2 绘制椭圆轨道?
我首先确定了a,b,c,d,e常数,现在我假设通过给出x值,我将得到y,这将给出我想要的图形,但我不能通过使用matplotlib来实现。
如果你能帮助我,我真的很感激!
编辑:我在这里添加了代码。
return Object.assign ( {}, baseParams, overrideParams )
编辑:以下是常数值:
from numpy import linalg
from numpy import linspace
import numpy as np
from numpy import meshgrid
import random
import matplotlib.pyplot as plt
from scipy import optimize
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]
my_list = [] #It is the main list.
b = [0] * len(x) # That is the list that contains the results that are given as x^2 from the equation.
def fxn(): # That is the function that solves the given equation to find each parameter.
global my_list
global b
for z in range(len(x)):
w = [0] * 5
w[0] = y[z] ** 2
w[1] = x[z] * y[z]
w[2] = x[z]
w[3] = y[z]
w[4] = 1
my_list.append(w)
b[z] = x[z] ** 2
t = linalg.lstsq(my_list, b)[0]
print 'List of list representation is', my_list
print 'x^2, the result of the given equation is', b
print '\nThe list that contains the parameters is', t
fxn()
t = linalg.lstsq(my_list, b)[0]
print '\nThe constant a is', t[0]
print 'The constant b is', t[1]
print 'The constant c is', t[2]
print 'The constant d is', t[3]
print 'The constant e is', t[4]
答案 0 :(得分:2)
最简单的方法是对这个等式进行参数化。正如@Escualo建议的那样,您可以引入变量t
并参数化x
和y
。参数化意味着根据x
将您的等式分别分为y
和t
两个单独的等式。因此,对于x = f(t)
的某些值,您会有y = g(t)
和t
。然后,您可以为x, y
的每个值绘制t
对的结果。
这里的问题是你的椭圆是旋转的(x*y
耦合项是指示的)。要分离方程式,您必须首先转换方程式以消除耦合项。这与找到一组与椭圆旋转相同角度的轴相同,沿这些轴进行参数化,然后将结果旋转回来。查看this forum post以获取一般概述。
首先需要找到椭圆轴相对于x-y坐标平面的旋转角度。
然后你的等式转换为
,其中
要找到椭圆的(近似)标准形式,您可以完成和部分的方块并稍微重新排列等式:
,其中
由于您知道,现在可以参数化和的等式:
然后,您将使用公式
旋转回正常的x-y空间
和
将x和y数组传递给plt.plot
的代码现在相对简单:
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
实际使用代码:
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))
要在椭圆上绘制原始点:
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.')
结果如下图所示:
请注意,我链接的论坛帖子使用的语法与您所使用的不同。它们的等式是 Ax 2 + Bxy + Cy 2 + Dx + Ey + F = 0。这比你的 2 + bxy - x 2 + cx + dy + e = 0的形式更标准。所有数学都是根据你的符号表达的。
答案 1 :(得分:1)
y可以解决问题,作为x
的函数关键是每个有效x都有2个y值,而椭圆范围x之外没有(或虚构)y解
下面是3.5代码,sympy 1.0应该没问题但是打印,list comps可能不会向后兼容到2.x
from numpy import linalg
from numpy import linspace
import numpy as np
from numpy import meshgrid
import random
import matplotlib.pyplot as plt
from scipy import optimize
from sympy import *
xs = [1.02, 0.95, 0.87, 0.77, 0.67, 0.56, 0.44, 0.30, 0.16, 0.01]
ys = [0.39, 0.32, 0.27, 0.22, 0.18, 0.15, 0.13, 0.12, 0.12, 0.15]
b = [i ** 2 for i in xs] # That is the list that contains the results that are given as x^2 from the equation.
def fxn(x, y): # That is the function that solves the given equation to find each parameter.
my_list = [] #It is the main list.
for z in range(len(x)):
w = [0] * 5
w[0] = y[z] ** 2
w[1] = x[z] * y[z]
w[2] = x[z]
w[3] = y[z]
w[4] = 1
my_list.append(w)
return my_list
t = linalg.lstsq(fxn(xs, ys), b)
def ysolv(coeffs):
x,y,a,b,c,d,e = symbols('x y a b c d e')
ellipse = a*y**2 + b*x*y + c*x + d*y + e - x**2
y_sols = solve(ellipse, y)
print(*y_sols, sep='\n')
num_coefs = [(a, f) for a, f in (zip([a,b,c,d,e], coeffs))]
y_solsf0 = y_sols[0].subs(num_coefs)
y_solsf1 = y_sols[1].subs(num_coefs)
f0 = lambdify([x], y_solsf0)
f1 = lambdify([x], y_solsf1)
return f0, f1
f0, f1 = ysolv(t[0])
y0 = [f0(x) for x in xs]
y1 = [f1(x) for x in xs]
plt.scatter(xs, ys)
plt.scatter(xs, y0, s=100, color = 'red', marker='+')
plt.scatter(xs, y1, s=100, color = 'green', marker='+')
plt.show()
当上述内容在Spyder中运行时:
runfile('C:/Users/john/mypy/mySE_answers/ellipse.py', wdir='C:/Users/john/mypy/mySE_answers')
(-b*x - d + sqrt(-4*a*c*x - 4*a*e + 4*a*x**2 + b**2*x**2 + 2*b*d*x + d**2))/(2*a)
-(b*x + d + sqrt(-4*a*c*x - 4*a*e + 4*a*x**2 + b**2*x**2 + 2*b*d*x + d**2))/(2*a)
f0(0.1), f1(0.1)
Out[5]: (0.12952825130864626, 0.6411040771593166)
f0(2)
Traceback (most recent call last):
File "<ipython-input-6-9ce260237dcd>", line 1, in <module>
f0(2)
File "<string>", line 1, in <lambda>
ValueError: math domain error
In [7]:
域名错误需要尝试/执行才能感觉到&#34;有效的x范围或更多的数学
喜欢尝试/以下:(编辑为&#34;关闭&#34;绘制评论)
def feeloutXrange(f, midx, endx):
fxs = []
x = midx
while True:
try: f(x)
except:
break
fxs.append(x)
x += (endx - midx)/100
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.scatter(xs, ys)
plt.scatter(xs, y0, s=100, color = 'red', marker='+')
plt.scatter(xs, y1, s=100, color = 'green', marker='+')
plt.plot(xs_ellipse, ys_ellipse)
plt.show()
编辑:将重复的起点添加到椭圆点列表的末尾以关闭绘图图
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
答案 2 :(得分:0)
最简单的方法是以参数形式重写,以便最终得到表达式x = A cos(t)
; y = B sin(t)
。然后,您可以通过指定t = [0, 2 * pi]
并计算相应的x
和y
来创建完整的椭圆。
阅读this article,其中介绍了如何从一般二次形式转换为参数形式。