Skip to content

Commit

Permalink
fixed some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
internaut committed Feb 15, 2017
1 parent e41a4d0 commit 8775cc3
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 19 deletions.
25 changes: 18 additions & 7 deletions pdftabextract/geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,21 @@ def ptdist(p1, p2):

def vecangle(v1, v2):
"""angle between two vectors v1, v2 in radians"""
denom = (np.linalg.norm(v1) * np.linalg.norm(v2))
if denom == 0:
v0 = pt(0, 0)

if np.allclose(v1, v0) or np.allclose(v2, v0):
return np.nan
return math.acos(np.vdot(v1, v2) / denom)

if np.allclose(v1, v2):
return 0

num = np.vdot(v1, v2)
denom = (np.linalg.norm(v1) * np.linalg.norm(v2))

if np.isclose(num, denom):
return 0

return math.acos(num / denom)


def vecrotate(v, theta, about=np.array((0,0))):
Expand Down Expand Up @@ -215,18 +226,18 @@ def normalize_angle(theta):

if theta >= twopi:
m = math.floor(theta/twopi)
if theta/twopi - m > 0.9999: # account for rounding errors
if theta/twopi - m > 0.99999: # account for rounding errors
m += 1
theta_norm = theta - m * twopi
elif theta < 0:
m = math.ceil(theta/twopi)
if theta/twopi - m < -0.9999: # account for rounding errors
if theta/twopi - m < -0.99999: # account for rounding errors
m -= 1
theta_norm = abs(theta - m * twopi)
else:
theta_norm = theta
return theta_norm

return round(theta_norm, 5)


def normalize_angle_halfcircle(theta):
Expand Down
36 changes: 24 additions & 12 deletions tests/test_geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
rect, rectcenter, rectarea, rectintersect,
normalize_angle, normalize_angle_halfcircle)

FMIN = np.finfo(np.float32).min
FMAX = np.finfo(np.float32).max


def test_pt():
x = 0
y = 1
Expand All @@ -42,7 +45,7 @@ def test_ptdist():
assert ptdist(p2, p1) == ptdist(p1, p2)

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


def test_vecangle():
v1 = pt(1, 0)
Expand All @@ -58,6 +61,23 @@ def test_vecangle():
assert vecangle(v2, v5) == math.radians(90) # always the smaller angle


@given(st.floats(min_value=FMIN, max_value=FMAX),
st.floats(min_value=FMIN, max_value=FMAX),
st.floats(min_value=FMIN, max_value=FMAX),
st.floats(min_value=FMIN, max_value=FMAX))
def test_vecangle_2(x1, y1, x2, y2):
v0 = pt(0, 0)
v1 = pt(x1, y1)
v2 = pt(x2, y2)

alpha = vecangle(v1, v2)

if np.allclose(v1, v0) or np.allclose(v2, v0):
assert np.isnan(alpha)
else:
assert 0 <= alpha <= np.pi


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))
Expand Down Expand Up @@ -195,19 +215,11 @@ def test_rectintersect():
assert rectintersect(a, b) is None


@given(st.floats(min_value=-1000*np.pi, max_value=1000*np.pi))
def test_normalize_angle(theta):
assert 0 <= normalize_angle(theta) < 2 * np.pi


def test_normalize_angle_2():
for i in range(-1000, 1000):
def test_normalize_angle():
for i in range(-10, 10):
theta = i * np.pi
norm = normalize_angle(theta)
assert 0 <= norm < 2 * np.pi
assert round(norm / np.pi, 6) == i % 2
assert np.isclose(round(norm / np.pi, 6), i % 2)


@given(st.floats(min_value=-1000*np.pi, max_value=1000*np.pi))
def test_normalize_angle_halfcircle(theta):
assert 0 <= normalize_angle_halfcircle(theta) < np.pi

0 comments on commit 8775cc3

Please sign in to comment.