Distance from point to line produces exception instead of 0.
Opened this issue · 1 comments
GoogleCodeExporter commented
What steps will reproduce the problem?
1. Create a line and a colinear point.
problem_point = euclid.Point2(0, 30)
problem_line = euclid.Line2(euclid.Point2(0, 0), euclid.Point2(0, 50))
2. Attempt to find the distance from the point to the line.
distance = problem_point.distance(problem_line)
What is the expected output?
0, at least approximately.
What do you see instead?
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import euclid
>>> problem_point = euclid.Point2(0.0, 30.0)
>>> problem_line = euclid.Line2(euclid.Point2(0.0, 0.0), euclid.Point2(0.0, 50.0
))
>>> problem_point.distance(problem_line)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files\Python 2.7.1\lib\site-packages\euclid.py", line 1589, i
n distance
c = self.connect(other)
File "C:\Program Files\Python 2.7.1\lib\site-packages\euclid.py", line 1713, i
n connect
return other._connect_point2(self)
File "C:\Program Files\Python 2.7.1\lib\site-packages\euclid.py", line 1792, i
n _connect_point2
return _connect_point2_line2(other, self)
File "C:\Program Files\Python 2.7.1\lib\site-packages\euclid.py", line 1652, i
n _connect_point2_line2
L.p.y + u * L.v.y))
File "C:\Program Files\Python 2.7.1\lib\site-packages\euclid.py", line 1757, i
n __init__
raise AttributeError, 'Line has zero-length vector'
AttributeError: Line has zero-length vector
>>>
What version of the product are you using? On what operating system?
Unexcepted behavior exists in latest revision located at
http://code.google.com/p/pyeuclid/source/browse/trunk/euclid.py. Tested on
python 2.7.1 running on Windows XP.
Please provide any additional information below.
I believe the error is the result of this code here:
return LineSegment2(P,
Point2(L.p.x + u * L.v.x,
L.p.y + u * L.v.y))
on lines 1666-1668.
That line segment appears to be the shortest line segment between the point and
the line, but since the point is colinear with the line, its length would be
zero and its constructor raises an exception. The Geometry class defines
distance on line 1604 to return 0.0 if the connection returns None, but it
isn't prepared to handle the exception, which is therefore allowed to propagate
to the caller.
Not sure if this is really a bug. It seems like the distance function should
return 0 in this case.
I don't have any practice writing real test cases ... but maybe this would help.
def test():
import euclid
point = euclid.Point2(0.0, 30.0)
line = euclid.Line2(euclid.Point2(0.0, 0.0), euclid.Point2(0.0, 50.0))
try:
distance = point.distance(line)
except AttributeError:
return False
if (distance < EPSILON):
return True
else:
return False
It returns False, failure, for me with the unmodified latest code.
When I replace _connect_point2_line2 with this (added some code to catch the
exception and return None, indicating the inability to connect):
def _connect_point2_line2(P, L):
d = L.v.magnitude_squared()
assert d != 0
u = ((P.x - L.p.x) * L.v.x + \
(P.y - L.p.y) * L.v.y) / d
if not L._u_in(u):
u = max(min(u, 1.0), 0.0)
try:
return LineSegment2(P,
Point2(L.p.x + u * L.v.x,
L.p.y + u * L.v.y))
except AttributeError:
# LineSegment2 is complaining because it's of length 0.
return None
test() returns True.
Original issue reported on code.google.com by asd454...@yahoo.com
on 23 May 2011 at 1:51
GoogleCodeExporter commented
Whoops.
"problem_point = euclid.Point2(0, 30)
problem_line = euclid.Line2(euclid.Point2(0, 0), euclid.Point2(0, 50))"
In the steps to reproduce should be
"problem_point = euclid.Point2(0.0, 30.0)
problem_line = euclid.Line2(euclid.Point2(0.0, 0.0), euclid.Point2(0.0, 50.0))"
The direct copy and paste from my interpreter under "What do you see instead?"
correctly uses floats instead of integers.
Sorry.
Original comment by asd454...@yahoo.com
on 23 May 2011 at 1:55
- Added labels: ****
- Removed labels: ****