3

I am using SymPy's geometry module to intersect line segments and circles. It seems only some intersection points are being counted, while many others are ignored.

Here is some test code for finding the intersection points:

from sympy.geometry import Point2D, Segment2D, Circle

# Point A, B and C
A = Point2D(1, 1)
B = Point2D(3, -1)
C = Point2D(-2, -2)

# Segment from A to B
f_0 = Segment2D(A, B)
# Segment from A to C
f_1 = Segment2D(A, C)
# Circle with center A and radius 0.8
c = Circle(A, .8)

i_0 = c.intersection(f_0)
i_1 = c.intersection(f_1)

print(i_0)
print(i_1)

This should work, and does catch all intersection-points when doing line-circle intersection or circle-circle intersection, but not segment-circle nor ray-circle intersection. Here is the output:

[]
[Point2D(217157287525381/500000000000000, 217157287525381/500000000000000)]

It's obviously not working as intended. I don't know what causes this, and I'd like to know how to fix it or find any alternatives (preferably still using SymPy).

[geogebra depiction of geometry]

Rodrigo de Azevedo
  • 1,097
  • 9
  • 17
  • This looks like an interesting problem--I wish I had time to work on it. You would make your question more attractive and better fit the rules of this site by making the code more **minimal**. Use just two points, one line segment, and one circle, and find where the code does not work as it should. Read and follow [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) and you will get more, better answers. You should also make the code **complete** by including all the needed import statements. – Rory Daulton Jun 30 '18 at 11:58
  • Thank you for the suggestion @RoryDaulton . I've simplified + completed the code down so only relevant information is left. Always nice to learn Stackoverflow etiquette. – Cornelius Sevald Jun 30 '18 at 14:14

1 Answers1

3

I still do not know why my previous method did not work, but i know one that will. After messing around in Wolfram|Alpha i realized the coordinates of intersection where all irrational. Seeing the output of the program being a fraction, something was obviously wrong. It turns out that the radius of the circle, 0.8, caused all of the trouble.

Instead of giving a float as an argument, you need to sympify it first. It is important to remember two things:

  1. The argument needs to be a string and not a float.
  2. The 'rational' flag needs to be True.

With this in mind, the new code becomes:

from sympy import sympify
from sympy.geometry import Point2D, Segment2D, Circle

# Point A, B and C
A = Point2D(1, 1)
B = Point2D(3, -1)
C = Point2D(-2, -2)

# Segment from A to B
f_0 = Segment2D(A, B)
# Segment from A to C
f_1 = Segment2D(A, C)
# Circle with center A and radius 0.8
c = Circle(A, sympify('.8', rational=True))

i_0 = c.intersection(f_0)
i_1 = c.intersection(f_1)

print(i_0)
print(i_1)

The output then becomes:

[Point2D(2*sqrt(2)/5 + 1, -2*sqrt(2)/5 + 1)]
[Point2D(-2*sqrt(2)/5 + 1, -2*sqrt(2)/5 + 1)]
  • Yes, SymPy has a lot of trouble with equations that involve floating point numbers. I suggest `Rational('.8')` as a shorter way of forming rationals like this (a shorter yet is `S(4)/5` where S is a built-in shortcut for "sympify"). –  Jul 02 '18 at 14:11