如何仅使用数学方程计算直线和椭圆之间的交点

问题描述 投票:0回答:1
我想使用 python 计算椭圆和直线之间的交点。 但是,当给定直线的两个端点以及椭圆的中心点和半径时,如何仅使用数学二次方程来实现呢?

stackoverflow 上的解决方案都没有描述我正在寻找的解决方案。 他们使用 numpy、scipy 和其他库或使用三角学 - 他们都不使用纯粹的数学过程。

比较

这篇文章中的解决方案例如:

你有椭圆公式:

(x - center_x)^2 / a^2 + (y - center_y)^2 / b^2 = 1

以及直线公式:

y = m*x + c

链接帖子中的解决方案描述了在重排时从中导出的二次公式:

A=a2m2+b2

B=2a2m(c-k)-2b2h

C=b2h2+a2(c-k)2-a2b2

我想仅使用数学来求解这个方程,求解 x,然后使用直线公式求解 y。

但是,当使用上述公式时,得到的交点是错误的,并且不位于椭圆或直线上。

这是我尝试过的代码:

from math import * def GetIntersectionPoints(line_point_a, line_point_b, center_x, center_y, rad_x, rad_y): # use line formula to calculate m and c: x1, y1, x2, y2 = *line_point_a, *line_point_b m = (y1 - y2) / (x1 - x2) if not x1 - x2 == 0 else 0 c = y2 - (m * x2) # Using quadratic equation provided in linked solution: A = (rad_y ** 2) + ((rad_x ** 2) * (m ** 2)) B = (2 * (rad_x ** 2) * m * (c - center_y)) - 2 * (rad_y ** 2) * center_x C = (rad_y ** 2) * (center_x ** 2) + (rad_x ** 2) * (c - center_y) * 2 - (rad_x ** 2) * (rad_y ** 2) # Solving quadratic equation: xi1 = (-B - sqrt((B ** 2) - (4 * A * C))) / (2 * A) xi2 = (-B + sqrt((B ** 2) - (4 * A * C))) / (2 * A) # Solving for y: yi1 = m * xi1 + c yi2 = m * xi2 + c return [[xi1, yi1], [xi2, yi2]]
如何在不使用 scipy、numpy 等(或 stackoverflow 上描述的三角学和其他解决方案)的情况下,以纯数学方式在 python 中正确求解方程和公式,以检索位于椭圆上的正确交点?

python math formula intersection ellipse
1个回答
0
投票
参见代码中的解释如何计算交点。该代码不使用任何模块,并在纯 Python 中完成所有计算:

def get_intersection_points(line_point_a, line_point_b, center_x, center_y, rad_x, rad_y): # Line endpoints x1, y1 = line_point_a x2, y2 = line_point_b # Calculate line slope (m) and intercept (c) if x1 != x2: m = (y2 - y1) / (x2 - x1) else: m = float('inf') # Vertical line case c = y1 - m * x1 if m != float('inf') else x1 # If line is vertical, c is x1 # Ellipse parameters h = center_x k = center_y a = rad_x b = rad_y if m != float('inf'): # Coefficients of the quadratic equation A = b**2 + a**2 * m**2 B = 2 * a**2 * m * (c - k) - 2 * b**2 * h C = b**2 * h**2 + a**2 * (c - k)**2 - a**2 * b**2 # Discriminant D = B**2 - 4 * A * C if D < 0: return [] # No intersection points # Calculate the x-coordinates of the intersection points sqrt_D = D**0.5 # math.sqrt(D) xi1 = (-B - sqrt_D) / (2 * A) xi2 = (-B + sqrt_D) / (2 * A) # Calculate the y-coordinates of the intersection points yi1 = m * xi1 + c yi2 = m * xi2 + c return [[xi1, yi1], [xi2, yi2]] else: # Vertical line case (x = c) x = c A = 1 / a**2 B = -2 * k / b**2 C = (h**2 / a**2) + (k**2 / b**2) - 1 # Quadratic equation for y A_y = 1 / b**2 B_y = -2 * k / b**2 C_y = (x - h)**2 / a**2 + k**2 / b**2 - 1 # Discriminant D_y = B_y**2 - 4 * A_y * C_y if D_y < 0: return [] # No intersection points # Calculate the y-coordinates of the intersection points sqrt_D_y = D_y**0.5 # math.sqrt(D_y) yi1 = (-B_y - sqrt_D_y) / (2 * A_y) yi2 = (-B_y + sqrt_D_y) / (2 * A_y) return [ [x , yi1], [ x , yi2] ] # Example usage: line_point_a = (1, 2) line_point_b = (4, 3) center_x = 2 center_y = 2 rad_x = 5 rad_y = 3 print(get_intersection_points(line_point_a, line_point_b, center_x, center_y, rad_x, rad_y)) from turtle import * Screen().setworldcoordinates(-10, -10, 10, 10) color("blue") shape("circle") pensize(5) up(); goto( center_x, center_y - rad_x ); down(); circle(rad_x) up(); goto( center_x, center_y - rad_y ); down(); circle(rad_y) up(); goto( *line_point_a) down(); goto(*line_point_b) up() for point in get_intersection_points(line_point_a, line_point_b, center_x, center_y, rad_x, rad_y) : goto(*point) stamp() shape("turtle") color("black") goto(-8,-8) done()
为了检查代码是否正确工作,海龟绘制了两个圆圈和线点:

intersection

© www.soinside.com 2019 - 2024. All rights reserved.