53 lines
1.9 KiB
Python
53 lines
1.9 KiB
Python
|
|
import importlib.util
|
||
|
|
import unittest
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import numpy as np
|
||
|
|
|
||
|
|
spec = importlib.util.spec_from_file_location("alignment", Path(__file__).with_name("alignment.py"))
|
||
|
|
alignment = importlib.util.module_from_spec(spec)
|
||
|
|
spec.loader.exec_module(alignment)
|
||
|
|
|
||
|
|
|
||
|
|
def straight(ch):
|
||
|
|
"""Alignment along +e from (0, 0); chainage == e."""
|
||
|
|
return np.array([float(ch), 0.0]), np.array([1.0, 0.0])
|
||
|
|
|
||
|
|
|
||
|
|
def area(ring):
|
||
|
|
a = 0.0
|
||
|
|
for i in range(len(ring)):
|
||
|
|
x1, y1 = ring[i]; x2, y2 = ring[(i + 1) % len(ring)]
|
||
|
|
a += x1 * y2 - x2 * y1
|
||
|
|
return abs(a) / 2
|
||
|
|
|
||
|
|
|
||
|
|
class AlignmentTests(unittest.TestCase):
|
||
|
|
def test_band_key(self):
|
||
|
|
self.assertEqual(alignment.band_key(240, 260), "ch240-260")
|
||
|
|
|
||
|
|
def test_bands_cover_range_in_20m_steps(self):
|
||
|
|
self.assertEqual(alignment.bands(235.0, 281.0), [(220, 240), (240, 260), (260, 280), (280, 300)])
|
||
|
|
|
||
|
|
def test_clip_square_into_bands(self):
|
||
|
|
ring = [(0, -5), (50, -5), (50, 5), (0, 5)] # 50 m long, 10 m wide
|
||
|
|
parts = [alignment.clip_ring_to_band(ring, straight, lo, hi, lo == 0, hi == 60)
|
||
|
|
for lo, hi in [(0, 20), (20, 40), (40, 60)]]
|
||
|
|
self.assertAlmostEqual(area(parts[0]), 200)
|
||
|
|
self.assertAlmostEqual(area(parts[1]), 200)
|
||
|
|
self.assertAlmostEqual(area(parts[2]), 100)
|
||
|
|
|
||
|
|
def test_first_band_keeps_area_before_alignment_start(self):
|
||
|
|
ring = [(-10, -5), (10, -5), (10, 5), (-10, 5)]
|
||
|
|
part = alignment.clip_ring_to_band(ring, straight, 0, 20, True, False)
|
||
|
|
self.assertAlmostEqual(area(part), 200) # nothing lost before ch 0
|
||
|
|
|
||
|
|
def test_last_band_keeps_area_after_alignment_end(self):
|
||
|
|
ring = [(30, -5), (70, -5), (70, 5), (30, 5)]
|
||
|
|
part = alignment.clip_ring_to_band(ring, straight, 20, 40, False, True)
|
||
|
|
self.assertAlmostEqual(area(part), 400) # 30..70 all kept
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
unittest.main()
|