Skip to content

Commit

Permalink
added some tests for geom
Browse files Browse the repository at this point in the history
fixed some bugs in geom
  • Loading branch information
internaut committed Feb 13, 2017
1 parent 40efd8a commit 9478348
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ build/
dist/
pdftabextract.egg-info/
ipynotes.py
.cache/
10 changes: 5 additions & 5 deletions pdftabextract/geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def vecrotate(v, theta, about=np.array((0,0))):
"""rotate a vector v by angle theta (in radians) about point <about>"""
cth = math.cos(theta)
sth = math.sin(theta)

return pt(
cth * v[0] - sth * v[1] + about[0] - cth * about[0] + sth * about[1],
sth * v[0] + cth * v[1] + about[1] - sth * about[0] - cth * about[1]
Expand All @@ -54,12 +54,12 @@ def overlap(a1, a2, b1, b2):
a_min <= b_max <= a_max or b_min <= a_max <= b_max


def pointintersect(p1, p2, p3, p4, check_in_segm=True):
def lineintersect(p1, p2, p3, p4, check_in_segm=True):
"""
Check if two lines made from (p1, p2) and (p3, p4) respectively, intersect.
If check_in_segm is True, will check that the line segments actually intersect,
will calculate intersection of inifite lines.
otherwise will calculate intersection of inifite lines.
If no intersection is found, returns None
For parallel lines, returns pt(np.nan, np.nan) if they are coincident.
Expand Down Expand Up @@ -99,7 +99,7 @@ def pointintersect(p1, p2, p3, p4, check_in_segm=True):
return P

if parallel: # check if parallel segments are coincident
if overlap(p1[0], p2[0], p3[0], p4[0]) and overlap(p1[1], p2[1], p3[1], p4[1]):
if not check_in_segm or (overlap(p1[0], p2[0], p3[0], p4[0]) and overlap(p1[1], p2[1], p3[1], p4[1])):
return P # lines coincident -> return pt(np.nan, np.nan)
else:
return None # no intersection in segment, only parallel
Expand Down Expand Up @@ -152,7 +152,7 @@ def rectcenter_dist(r1, r2):


def rectarea(r):
"""Return the area of rectangle <r>""""
"""Return the area of rectangle <r>"""
return (r[1][0] - r[0][0]) * (r[1][1] - r[0][1])


Expand Down
96 changes: 96 additions & 0 deletions tests/test_geom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 13 09:50:51 2017
@author: mkonrad
"""

import math

import numpy as np

from pdftabextract.geom import pt, ptdist, vecangle, vecrotate, overlap, lineintersect


def test_pt():
x = 0
y = 1
pt0 = pt(x, y)
assert pt0.dtype == np.float
assert pt0[0] == x
assert pt0[1] == y

pt1 = pt(x, y, np.int)
assert pt1.dtype == np.int
assert pt1[0] == x
assert pt1[1] == y


def test_ptdist():
p1 = pt(0, 0)
p2 = pt(1, 0)
p3 = pt(1, 1)

assert ptdist(p1, p1) == 0
assert ptdist(p1, p2) == 1
assert ptdist(p2, p1) == ptdist(p1, p2)

assert ptdist(p1, p3) == math.sqrt(2)


def test_vecangle():
v1 = pt(1, 0)
v2 = pt(2, 0)
v3 = pt(1, 1)
v4 = pt(0, 1)
v5 = pt(0, -1)

assert np.isnan(vecangle(pt(0, 0), v1)) # pt(0, 0) is vec of no length
assert vecangle(v1, v2) == 0
assert round(vecangle(v1, v3), 4) == round(math.radians(45), 4)
assert vecangle(v2, v4) == vecangle(v1, v4) == math.radians(90)
assert vecangle(v2, v5) == math.radians(90) # always the smaller angle


def test_vecrotate():
assert np.array_equal(vecrotate(pt(0, 0), 0.123), pt(0, 0))
assert np.allclose(vecrotate(pt(1, 0), math.radians(90)), pt(0, 1))
assert np.allclose(vecrotate(pt(1, 0), math.radians(90), about=pt(1, 1)), pt(2, 1))


def test_overlap():
assert overlap(0, 1, 0, 1) is True
assert overlap(0, 0, 1, 1) is False
assert overlap(0, 10, 5, 15) is True
assert overlap(-10, 10, -20, -10) is True
assert overlap(-9, 10, -20, -10) is False


def test_lineintersect():
# first with check_in_segm = True
X = lineintersect(pt(0, 0), pt(0, 0), pt(0, 0), pt(0, 0)) # coincident I
assert sum(np.isnan(X)) == len(X)

X = lineintersect(pt(0, 0), pt(0, 1), pt(0, 0), pt(0, 1)) # coincident II
assert sum(np.isnan(X)) == len(X)

assert lineintersect(pt(0, 0), pt(0, 1), pt(1, 0), pt(1, 1)) is None # parallel, non coincident
assert lineintersect(pt(0, 0), pt(0, 1), pt(1, 1), pt(2, 2)) is None # non-parellel, no intersection
assert lineintersect(pt(0, 0), pt(2, 2), pt(0, 5), pt(5, 0)) is None # non-parellel, no intersection II
assert np.array_equal(lineintersect(pt(0, 0), pt(0, 1), pt(0, 1), pt(2, 2)), pt(0, 1)) # intersection - touch
assert np.array_equal(lineintersect(pt(0, 0), pt(2, 2), pt(0, 2), pt(2, 0)), pt(1, 1)) # intersection

# now with check_in_segm = False
X = lineintersect(pt(0, 0), pt(0, 0), pt(0, 0), pt(0, 0), False) # coincident I
assert sum(np.isnan(X)) == len(X)

X = lineintersect(pt(0, 0), pt(0, 1), pt(0, 0), pt(0, 1), False) # coincident II
assert sum(np.isnan(X)) == len(X)

X = lineintersect(pt(0, 0), pt(1, 1), pt(2, 2), pt(3, 3), False) # coincident III
assert sum(np.isnan(X)) == len(X)

assert np.array_equal(lineintersect(pt(0, 0), pt(0, 1), pt(1, 1), pt(2, 2), False), pt(0, 0)) # intersection (out of segments)
assert np.array_equal(lineintersect(pt(0, 0), pt(0, 1), pt(0, 1), pt(2, 2), False), pt(0, 1)) # intersection - touch
assert np.array_equal(lineintersect(pt(0, 0), pt(2, 2), pt(0, 2), pt(2, 0), False), pt(1, 1)) # intersection

0 comments on commit 9478348

Please sign in to comment.