0

I have a system of two equations that calculate the coordinates of two points T1(u1,v1) and T2(u2,v2), where lines starting from point A to those points are tangent with a given circle. Point A is always outside of the circle, so there should always be two solutions. The system of equations is given as follows:

eq1 = Eq((xpos-u)**2 + (ypos-v)**2, tglensq)
eq2 = Eq((oxpos-u)**2 + (oypos-v)**2, radsq)

where xpos,ypos are coordinates of A, and oxpos, oypos are coordinates of the center of the circle. tglensq represents the length of the tangent squared, and radsq the radius of the circle squared. The solutions need to be calculated continuously in a loop. I want to solve the equation first for u and v, and then plugin the other values (as described here). Solving for each iteration of the loop turns out to be quite expensive, although it always produces the two solutions.

After getting the solution, in the loop I substitute the other values, like so:

u1 = first_solution[0].subs([(xpos, robot_pos[0]), (ypos, robot_pos[1]), (oxpos, obstacle_pos[0]), (oypos, obstacle_pos[1]), (tglensq, tangent_len_squared), (minkradsq, minkowski_radius_sq)])

However, sympy fails to find the real solutions, and ends up giving imaginary ones, like:

628644.458063364 - 3693.82126269719*I

I saw here a similar issue about solving first then substituting, but I am not sure how to proceed from here. Any help would be greatly appreciated :).

1 Answers1

0

Does defining the location of one circle relative to the other help? Let dx,dy = Point(oxpos,oypos)-Point(xpos,ypos) so the equations are

>>> dx,dy = symbols('dx,dy') # and your other symbols
>>> eq1,eq2 = Eq((u)**2 + (v)**2, tglensq),Eq((dx-u)**2 + (dy-v)**2, radsq)
>>> sol=solve((eq1,eq2), (u,v))
>>> sol[0]
(-(-dx**2 - dy**2 + 2*dy*(-dx*sqrt(-dx**4 - 2*dx**2*dy**2 + 2*dx**2*radsq + 2*dx**2*tglensq - dy**4 + 2*dy**2*radsq + 2*dy**2*tglensq - radsq**2 + 2*radsq*tglensq - tglensq**2)/(2*(dx**2 + dy**2)) + dy*(dx**2 + dy**2 - radsq + tglensq)/(2*(dx**2 + dy**2))) + radsq - tglensq)/(2*dx), -dx*sqrt(-dx**4 - 2*dx**2*dy**2 + 2*dx**2*radsq + 2*dx**2*tglensq - dy**4 + 2*dy**2*radsq + 2*dy**2*tglensq - radsq**2 + 2*radsq*tglensq - tglensq**2)/(2*(dx**2 + dy**2)) + dy*(dx**2 + dy**2 - radsq + tglensq)/(2*(dx**2 + dy**2)))
>>> sol[1]
(-(-dx**2 - dy**2 + 2*dy*(dx*sqrt(-dx**4 - 2*dx**2*dy**2 + 2*dx**2*radsq + 2*dx**2*tglensq - dy**4 + 2*dy**2*radsq + 2*dy**2*tglensq - radsq**2 + 2*radsq*tglensq - tglensq**2)/(2*(dx**2 + dy**2)) + dy*(dx**2 + dy**2 - radsq + tglensq)/(2*(dx**2 + dy**2))) + radsq - tglensq)/(2*dx), dx*sqrt(-dx**4 - 2*dx**2*dy**2 + 2*dx**2*radsq + 2*dx**2*tglensq - dy**4 + 2*dy**2*radsq + 2*dy**2*tglensq - radsq**2 + 2*radsq*tglensq - tglensq**2)/(2*(dx**2 + dy**2)) + dy*(dx**2 + dy**2 - radsq + tglensq)/(2*(dx**2 + dy**2)))

To calculate u,v try

>>> dif = (Point(oxpos,oypos)-Point(xpos,ypos)).subs(dict(zip((xpos,ypos,oxpos,oypos),(1,2,3,4))))
>>> Tuple(*sol).subs(dict(zip((tglensq,radsq),(5,6)))).subs(dict(zip((dx,dy),dif)))

Replace 1,2,3,4,5,6 with the actual values. Does that give you two real solutions?

smichr
  • 16,948
  • 2
  • 27
  • 34
  • Hi, thanks for the answer, I will try this. In the end, I ended up solving it with trig. But I am still interested to know how one approaches this case. – highWaters May 16 '22 at 11:49