0

I want to compute in python 1) whether a rotated ellipse and line intersect, and 2) if they do, xy coordinates of intersections points. I have:

  • Line defined by: slope m & a reference point on the line x1 & y1
  • Ellipse defined by: center x0 & y0, semi axes a & b, rotation in radians theta.

Specifically, the intersection point I need is the one closer to the reference point. Can someone please help me figure this out?

Edit: Similar to this question but the ellipse is rotated by theta.

Ntwk
  • 21
  • 4
  • welcome to stackoverflow. please take the [tour](http://stackoverflow.com/tour) and read [the help pages](http://stackoverflow.com/help). helpful may be [how to ask good questions](http://stackoverflow.com/help/how-to-ask) and this [question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). sample input and desired output would be really helpful. – hiro protagonist Feb 14 '22 at 21:06
  • 1
    The second answer to linked question describes approach for rotated ellipse with proper tranformation like Yves Daoust wrote here (just line description is different there) – MBo Feb 15 '22 at 04:02

2 Answers2

2

Hint:

If you perform the following operations:

  • translate by -(X0, Y0),

  • rotate by -Θ,

  • scale X by 1/a and Y by 1/b,

the ellipse becomes the unit circle and the line becomes another line, say of equation Ax + By = C. So you get a classical trigonometric equation A cos α + B sin α = C**.

After finding the solutions, you apply the inverse transformations.

To find the transformed line equation, you can use the points (X1, Y1) and (X1 + 1, Y1 + M), transform them and write the implicit equation of a line by two points.


**A cos α = C - B sin α --> A² (1 - sin²α) = C² - 2 BC sin α + B² sin²α is a quadratic equation in sin α.

0

as there is not much in your question to work with, i started solving the equations using sympy (there is no theta so far...):

from sympy import var, Eq, solveset

# line:
# x(alpha) = x1 + alpha
# y(alpha) = y1 + m * alpha

# ellipse:
# (x - x0) ** 2 / a ** 2 + (y - y0) ** 2 / b ** 2 == 1

x0, y0 = var("x0 y0")
x, y = var("x y")
a, b = var("a b")
x1, y1 = var("x1 y1")
m = var("m")
alpha = var("alpha")
ell = Eq((x - x0) ** 2 / a ** 2 + (y - y0) ** 2 / b ** 2, 1)

ell_line = ell.subs({x: x1 + alpha, y: y1 + m * alpha})

sol = solveset(ell_line, alpha)
print(sol)

this produces the solutions

FiniteSet(a*b*sqrt(a**2*m**2 + b**2 - m**2*x0**2 + 2*m**2*x0*x1 - m**2*x1**2 + 2*m*x0*y0 - 2*m*x0*y1 - 2*m*x1*y0 + 2*m*x1*y1 - y0**2 + 2*y0*y1 - y1**2)/(a**2*m**2 + b**2) + (a**2*m*y0 - a**2*m*y1 + b**2*x0 - b**2*x1)/(a**2*m**2 + b**2),
          -a*b*sqrt(a**2*m**2 + b**2 - m**2*x0**2 + 2*m**2*x0*x1 - m**2*x1**2 + 2*m*x0*y0 - 2*m*x0*y1 - 2*m*x1*y0 + 2*m*x1*y1 - y0**2 + 2*y0*y1 - y1**2)/(a**2*m**2 + b**2) + (a**2*m*y0 - a**2*m*y1 + b**2*x0 - b**2*x1)/(a**2*m**2 + b**2))

for the parameters (that i chose at random...):

print(sol.subs({a: 1, b: 2, x0: -1, y0: 3, x1: 2, y1: -3, m: -2}))

i get (for alpha):

FiniteSet(-3 - sqrt(2)/2, -3 + sqrt(2)/2)

if the solutions are real (and not complex) there is an intersection. all you'd need to do is then calculate the distance to your reference point and choose the point you are interested in.

WARNING: none of this is really tested... this is just a first shot at what i would try...

hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
  • Working with sympy this way has the disadvantage that it generates heavy expanded expressions which are hard to read and possibly inefficient as regards evaluation. It can be better to keep intermediate, meaningful quantities. –  Feb 15 '22 at 10:47
  • 1
    i agree. but as there was nothing to start from i thought this may give the OP some hints where to start in order to sort the math out. the results of `sympy` could then be simplified and used in 'pure' python. i did not mean for this code to be run when looking for the point - only to have the equations in place on how to find the point. – hiro protagonist Feb 15 '22 at 10:52