如何从一般形式在椭圆上画一个点

How to draw a point on an ellipse from general form

提问人:Andrew 提问时间:10/22/2023 最后编辑:phoAndrew 更新时间:10/22/2023 访问量:30

问:

以下程序从以一般形式给出的方程中绘制一个旋转的椭圆:

import matplotlib as mpl
import matplotlib.pyplot as plt

x_range = np.linspace(-6, +6)
y_range = np.linspace(-10, +1)
x, y = np.meshgrid(x_range, y_range)

A, B, C, D, E, F = 0.25, 0.40, 0.25, 1.50, 2.00, 1.50

f = lambda x, y, A, B, C, D, E, F: A*x**2 + B*x*y +C*y**2 + D*x + E*y + F
equation = f(x, y, A, B, C, D, E, F)

fig, ax = plt.subplots(1, 1, figsize = (4, 4), tight_layout = True)

ax.contour(x, y, equation, levels = [0], colors = color)

plt.show()

有没有一种简单的方法可以在这个椭圆画一个点,无论它在哪里?

我的问题来自这样一个事实,即我有时会使用 and,在 中,如果您通过输入绘制一个椭圆,您可以轻松地在椭圆上放置一个您想要的点(甚至移动它),使用简单的指令......GeogebraGeogebra0.25*x^2 + 0.40*x*y + 0.25*y^2 + 1.5*x + 2*y + 1.5 = 0Point on Object

我想知道是否可以在 Python 中实现类似的东西,从我上面写的一个小程序开始?

Python 绘制

评论


答:

1赞 pho 10/22/2023 #1

你的代码以一种相当迂回的方式绘制椭圆 -- 它绘制了 2d 数组中值的轮廓,这是通过计算由 和 定义的网格上每个点的值来获得的。f == 0equationfxy

也就是说,返回一个 QuadContourSet,您可以从中提取正在绘制的坐标,如下所示:ax.contour

qcs = ax.contour(x, y, equation, levels = [0], colors = color)
pts = qcs.collections[0].get_paths()[0].vertices

pts是形状的二维数组。此数组的任何行都是椭圆上的一个点。例如:(N, 2)

ax.plot(pts[5, 0], pts[5, 1], 'xk')

在下面绘制黑色 X:

enter image description here


如果你想为任何任意值找到一个点,你只需要获得求解方程的值。scipy.optimize.fsolve 可以为您做到这一点。由于接受一个函数并解决问题,我们需要重新定义我们的函数,以便第一个参数是我们试图找到的未知坐标,并提供其余的:xyf(x, ...) == 0fsolveFF(X, args) == 0argsfsolve

from scipy.optimize import fsolve
def get_ellipse_point(x, A, B, C, D, E, F, y0):

    def ellipse_func(y, x, A, B, C, D, E, F):
        return A*x**2 + B*x*y +C*y**2 + D*x + E*y + F

    y_pt = fsolve(ellipse_func, y0, (x, A, B, C, D, E, F)
    return (x, y_pt[0])

y0是你对点的初步猜测。例如,调用此函数以查找具有以下条件的点:yx == 0

# Initial guess of y is -10, which will find the point at the bottom of the ellipse
pt_x0_bottom = get_ellipse_point(0, A, B, C, D, E, F, -10)  # (0, -7.16227766016838)

# Initial guess of y is +10, which will find the point at the top of the ellipse
pt_x0_top = get_ellipse_point(0, A, B, C, D, E, F, 10)  # (0, -0.8377223398316207)

我们可以绘制这些点以确保我们有正确的答案:

ax.plot(*pt_x0_bottom, 'ob') # Plot bottom point with blue circle
ax.plot(*pt_x0_top, '^g')    # Plot top point with green triangle

enter image description here


请注意,我使用了关键字来定义椭圆的功能。我本可以像您一样用 lambda 定义它以获得相同的结果,但这不是一个好的做法(参见 是 pythonic 吗:命名 lambdadef)

评论

0赞 Andrew 10/22/2023
嗨,这真的很有趣,我学到了很多新东西。这对我有很大帮助!phoax.contour