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]

2
  • 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 and you will get more, better answers. You should also make the code complete by including all the needed import statements. Commented Jun 30, 2018 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. Commented Jun 30, 2018 at 14:14

1 Answer 1

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)] 
Sign up to request clarification or add additional context in comments.

1 Comment

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").