diff options
Diffstat (limited to '')
-rw-r--r-- | src/cython/test-rectangle.py | 601 |
1 files changed, 601 insertions, 0 deletions
diff --git a/src/cython/test-rectangle.py b/src/cython/test-rectangle.py new file mode 100644 index 0000000..51f3c50 --- /dev/null +++ b/src/cython/test-rectangle.py @@ -0,0 +1,601 @@ +import unittest +from math import pi, sqrt +from random import randint + +import cy2geom + +from cy2geom import Point, IntPoint + +from cy2geom import Interval, IntInterval, OptInterval, OptIntInterval +from cy2geom import GenericInterval, GenericOptInterval + +from cy2geom import Rect, OptRect, IntRect, OptIntRect +from cy2geom import GenericRect + +from fractions import Fraction + + +class TestPrimitives(unittest.TestCase): + def interval_basic(self, I, J): + #for simplicity + self.assertTrue(I.min() >= 0) + self.assertTrue(J.min() >= 0) + a = I.min() + b = I.max(); + self.assertAlmostEqual(I.middle(), (a+b)/2); + self.assertAlmostEqual(I.extent(), (b-a)); + if a != b: + self.assertFalse(I.is_singular()) + else: + self.assertTrue(I.is_singular()) + + I.expand_by(a) + self.assertAlmostEqual(I.min(), 0); + self.assertAlmostEqual(I.max(), a+b) + I.set_min(a) + I.set_max(b) + + self.assertTrue(I.contains(a+ (b-a)/3 )) + self.assertTrue(I.contains(a)) + self.assertTrue(I.contains_interval(I)) + + if (not I.is_singular()) or I.min() != 0 : + pass + self.assertFalse(I.contains_interval(I+I)) + self.assertFalse(I.contains(a-1)) + + c = J.min() + d = J.max() + self.assertAlmostEqual( (I+J).min(), a+c ) + self.assertAlmostEqual((I|J).min(), min(a, c)) + J.set_min(a+2) + J.set_max(b+2) + self.assertEqual(I+2, J) + I.expand_to(2*b) + self.assertAlmostEqual(I.max(), 2*b) + + def test_interval(self): + I = Interval(1.2, 5) + J = Interval(0, 0.3) + self.interval_basic(I, J) + + self.assertTrue(I.interior_contains(I.middle())) + self.assertFalse(I.interior_contains(I.min())) + self.assertFalse(I.interior_contains_interval(I)) + self.assertTrue(I.interior_contains_interval(Interval(I.min()+1, I.max()-1))) + + self.assertTrue(I.interior_intersects(I)) + self.assertFalse(I.interior_intersects(-I)) + p = [1, 2, 3.442, 3] + K = Interval.from_list(p) + self.assertAlmostEqual(K.max(), max(p)) + self.assertAlmostEqual((K+Interval(1.0)).min(), min(p)+1) + L = Interval(10/3.0) + for i in range(3): + K+=L + self.assertAlmostEqual(K.max(), max(p)+10) + + #TODO This 2geom behaviour is a bit strange + self.assertEqual(Interval(3.0)|Interval(5.0), + Interval(3.0, 5.0)) + self.assertAlmostEqual((K-L).max(), (K-10/3.0).max()) + + self.assertAlmostEqual((K*3.4).max(), 3.4*K.max()) + self.assertAlmostEqual((K/3).extent(), K.extent()/3) + + def test_optInterval(self): + I = OptInterval(2.2, 9.3) + J = Interval(3, 13) + K = OptInterval.from_Interval(J) + self.assertEqual(K.Interval, J) + self.interval_basic(K.Interval, I.Interval) + + L = OptInterval() + + self.assertFalse(L) + self.assertTrue( (L&I).is_empty() ) + L.intersect_with(I) + self.assertFalse(L) + + L |= I + + self.assertEqual(L.Interval, I.Interval) + + self.assertEqual((I & K).Interval, Interval(3, 9.3)) + + def test_intInterval(self): + I = IntInterval(2, 6) + J = IntInterval(0, 1) + self.interval_basic(I, J) + p = [3, 2.3, 65.3, 43] + K = IntInterval.from_list(p) + self.assertAlmostEqual(K.max(), int(max(p))) + self.assertAlmostEqual(int((K+IntInterval(1.0)).min()), int(min(p)+1)) + L = IntInterval(3) + for i in range(3): + K+=L + self.assertAlmostEqual(K.max(), int(max(p))+9) + + self.assertEqual(Interval(3)|Interval(5), + Interval(3, 5)) + self.assertAlmostEqual((K-L).max(), (K-3).max()) + + def test_optIntInterval(self): + I = OptIntInterval(2, 9) + J = IntInterval(3, 13) + K = OptIntInterval.from_Interval(J) + self.assertEqual(K.Interval, J) + self.interval_basic(K.Interval, I.Interval) + + L = OptIntInterval() + + self.assertFalse(L) + self.assertTrue( (L&I).is_empty() ) + L.intersect_with(I) + self.assertFalse(L) + + L |= I + + self.assertEqual(L.Interval, I.Interval) + + self.assertEqual((I & K).Interval, IntInterval(3, 9)) + + def test_genericInterval(self): + maxv = 100000 + test_vars = [ + ( (randint(0, maxv), randint(0, maxv)), (randint(0, maxv), randint(0, maxv)) ), + ( (3,), (2, 0) ), + ( (0.0, 9), (4, 1.3)), + ((2.98, sqrt(2)), (sqrt(7),)), + ( (Fraction(1,2), Fraction(3, 7)), ( Fraction(2, 1), ) ) + ] + for a,b in test_vars: + self.interval_basic( GenericInterval(*a), GenericInterval(*b) ) + + def test_genericOptInterval(self): + test_vars = [ + ( (3,), (2, 0) ), + ( (0.0, 9), (4, 1.3)), + ((2.98, sqrt(2)), (sqrt(7),)), + ( (Fraction(1,2), Fraction(3, 7)), ( Fraction(2, 1), ) ) + ] + + for a, b in test_vars: + I = GenericOptInterval(*a) + J = GenericInterval(*b) + K = GenericOptInterval.from_Interval(J) + + self.assertEqual(I, GenericOptInterval.from_Interval(I)) + + self.assertEqual(K.Interval, J) + self.interval_basic(K.Interval, I.Interval) + + L = GenericOptInterval() + + self.assertFalse(L) + self.assertTrue( (L&I).is_empty() ) + L.intersect_with(I) + self.assertFalse(L) + + L |= I + + self.assertEqual(L.Interval, I.Interval) + + if I.intersect_with(K): + if I.Interval.min() <= K.Interval.min(): + if I.Interval.max() >= K.Interval.max(): + self.assertEqual( I & K, K) + else: + self.assertEqual( I & K, GenericInterval(K.min(), I.max())) + else: + if I.Interval.max() >= K.Interval.max(): + self.assertEqual( I & K, GenericInterval(I.min(), K.max())) + else: + self.assertEqual( I & K, I) + + def test_genericRect(self): + A = GenericRect(1, 1, 4, 4) + self.assertEqual( A.min(), (1, 1) ) + B = GenericRect(Fraction(1,4), Fraction(9, 94), Fraction(2, 3), Fraction(23, 37)) + + amin = A.min() + amax = A.max() + + self.assertAlmostEqual(amin[0], A[0].min()) + self.assertAlmostEqual(amax[1], A[1].max()) + self.assertEqual(amin, A.corner(0)) + + self.assertEqual(amin, (A.left(), A.top())) + self.assertEqual(amax, (A.right(), A.bottom())) + + self.assertAlmostEqual( A.width(), A[0].extent() ) + self.assertAlmostEqual( A.height(), A[1].extent() ) + + self.assertEqual( A.dimensions(), ( A.width(), A.height() ) ) + #~ self.assertEqual( A.midpoint(), (A.min() + A.max())/2 ) + self.assertAlmostEqual(A.area(), A.width()*A.height()) + #TODO export EPSILON from 2geom + if A.area() > 0: + self.assertFalse(A.has_zero_area()) + else: + self.assertTrue(A.has_zero_area()) + self.assertAlmostEqual(A.max_extent(), max(A.width(), A.height())) + self.assertGreaterEqual(A.max_extent(), A.min_extent()) + + bmin = B.min() + bmax = B.max() + + pdiag = sqrt((amax[0]-amin[0])**2+(amax[1]-amin[1])**2) + + B.set_min(A.midpoint()) + B.set_max(A.midpoint()) + + self.assertTrue(B.has_zero_area()) + + B.expand_by(A.min_extent()/3.0) + + self.assertTrue(A.contains_rect(B)) + self.assertTrue(A.intersects(B)) + self.assertTrue(B.intersects(A)) + self.assertFalse(B.contains_rect(A)) + + self.assertTrue(A.contains(A.midpoint())) + self.assertFalse(A.contains( (A.midpoint()[0]*3, A.midpoint()[1]*3) )) + + A.union_with(B) + + self.assertEqual( A.min(), amin ) + + B.set_left(bmin[0]) + B.set_top(bmin[1]) + B.set_right(bmax[0]) + B.set_bottom(bmax[1]) + + self.assertEqual(B.min(), bmin) + self.assertEqual(B.max(), bmax) + + B.expand_to( (0, 0) ) + self.assertEqual((0, 0), B.min()) + + B.expand_by(*bmax) + self.assertEqual(bmax, (- (B.min()[0]), - (B.min()[1])) ) + + B.expand_by(-bmax[0], -bmax[1]) + self.assertEqual(B.max(), bmax) + + self.assertEqual( (A+B.min()).max()[0], A.max()[0] + B.min()[0] ) + + #~ self.assertEqual( (A-B.max()).min(), A.min() - B.max() ) + + self.assertEqual( A|A, A ) + + self.assertFalse( A != A ) + + B.set_left(bmin[0]) + B.set_top(bmin[1]) + B.set_right(bmax[0]) + B.set_bottom(bmax[1]) + + #~ self.assertAlmostEqual(Rect.distance(Point(), A), A.min().length()) + #~ self.assertAlmostEqual(Rect.distanceSq(B.min(), A), Rect.distance(B.min(), A)**2 ) + + + + def rect_basic(self, P, Q): + pmin = P.min() + pmax = P.max() + #for simplicity + self.assertTrue(pmin.x > 0) + self.assertTrue(pmin.y > 0) + + self.assertAlmostEqual(pmin.x, P[0].min()) + self.assertAlmostEqual(pmax.y, P[1].max()) + self.assertEqual(pmin, P.corner(0)) + + self.assertEqual(pmin, Point(P.left(), P.top())) + self.assertEqual(pmax, Point(P.right(), P.bottom())) + + self.assertAlmostEqual( P.width(), P[0].extent() ) + self.assertAlmostEqual( P.height(), P[1].extent() ) + + self.assertAlmostEqual( P.aspect_ratio(), P.width()/P.height() ) + self.assertEqual( P.dimensions(), Point( P.width(), P.height() ) ) + self.assertEqual( P.midpoint(), (P.min() + P.max())/2 ) + self.assertAlmostEqual(P.area(), P.width()*P.height()) + #TODO export EPSILON from 2geom + if P.area() > 1e-7: + self.assertFalse(P.has_zero_area()) + self.assertTrue(P.has_zero_area(P.area())) + else: + self.assertTrue(P.has_zero_area()) + self.assertAlmostEqual(P.max_extent(), max(P.width(), P.height())) + self.assertGreaterEqual(P.max_extent(), P.min_extent()) + + qmin = Q.min() + qmax = Q.max() + + pdiag = (pmax-pmin).length() + + Q.set_min(P.midpoint()) + Q.set_max(P.midpoint()) + self.assertTrue(Q.has_zero_area()) + + #print P,Q + Q.expand_by(P.min_extent()/3.0) + + #print P, Q + + self.assertTrue(P.contains_rect(Q)) + self.assertTrue(P.intersects(Q)) + self.assertTrue(Q.intersects(P)) + self.assertFalse(Q.contains_rect(P)) + + self.assertTrue(P.interior_contains_rect(Q)) + self.assertFalse(P.interior_contains_rect(P)) + self.assertTrue(P.interior_intersects(Q)) + self.assertTrue(P.interior_intersects(P)) + + self.assertTrue(P.contains(P.midpoint())) + self.assertFalse(P.contains(P.midpoint()*3)) + + P.union_with(Q) + + self.assertEqual( P.min(), pmin ) + + Q.set_left(qmin.x) + Q.set_top(qmin.y) + Q.set_right(qmax.x) + Q.set_bottom(qmax.y) + + self.assertEqual(Q.min(), qmin) + self.assertEqual(Q.max(), qmax) + + Q.expand_to( Point() ) + self.assertEqual(Point(), Q.min()) + Q.expand_by(qmax) + self.assertEqual(qmax, -Q.min()) + + Q.expand_by(-qmax.x, -qmax.y) + self.assertEqual(Q.max(), qmax) + + self.assertEqual( (P+Q.min()).max(), P.max() + Q.min() ) + + self.assertEqual( (P-Q.max()).min(), P.min() - Q.max() ) + + self.assertEqual( P|P, P ) + + self.assertFalse( P != P ) + + Q.set_left(qmin.x) + Q.set_top(qmin.y) + Q.set_right(qmax.x) + Q.set_bottom(qmax.y) + + self.assertAlmostEqual(Rect.distance(Point(), P), P.min().length()) + self.assertAlmostEqual(Rect.distanceSq(Q.min(), P), Rect.distance(Q.min(), P)**2 ) + + self.assertEqual(P.round_outwards()[0], P[0].round_outwards()) + if P.round_inwards(): + self.assertEqual(P.round_inwards().Rect[1], P[1].round_inwards().Interval) + + + def intrect_basic(self, P, Q): + pmin = P.min() + pmax = P.max() + #for simplicity + self.assertTrue(pmin.x > 0) + self.assertTrue(pmin.y > 0) + + self.assertAlmostEqual(pmin.x, P[0].min()) + self.assertAlmostEqual(pmax.y, P[1].max()) + self.assertEqual(pmin, P.corner(0)) + + self.assertEqual(pmin, IntPoint(P.left(), P.top())) + self.assertEqual(pmax, IntPoint(P.right(), P.bottom())) + + self.assertAlmostEqual( P.width(), P[0].extent() ) + self.assertAlmostEqual( P.height(), P[1].extent() ) + + self.assertAlmostEqual( P.aspect_ratio(), float(P.width())/float(P.height()) ) + self.assertEqual( P.dimensions(), IntPoint( P.width(), P.height() ) ) + self.assertEqual( P.midpoint().x, (P.min() + P.max()).x/2 ) + self.assertAlmostEqual(P.area(), P.width()*P.height()) + + if P.area() > 0: + self.assertFalse(P.has_zero_area()) + else: + self.assertTrue(P.has_zero_area()) + self.assertAlmostEqual(P.max_extent(), max(P.width(), P.height())) + self.assertGreaterEqual(P.max_extent(), P.min_extent()) + + qmin = Q.min() + qmax = Q.max() + + Q.set_min(P.midpoint()) + Q.set_max(P.midpoint()) + self.assertTrue(Q.has_zero_area()) + + Q.expand_by(P.min_extent()/3.0) + + self.assertTrue(P.contains_rect(Q)) + self.assertTrue(P.intersects(Q)) + self.assertTrue(Q.intersects(P)) + self.assertFalse(Q.contains_rect(P)) + + self.assertTrue(P.contains(P.midpoint())) + self.assertFalse(P.contains(P.midpoint()+P.midpoint()+P.midpoint())) + + P.union_with(Q) + + self.assertEqual( P.min(), pmin ) + + Q.set_left(qmin.x) + Q.set_top(qmin.y) + Q.set_right(qmax.x) + Q.set_bottom(qmax.y) + + self.assertEqual(Q.min(), qmin) + self.assertEqual(Q.max(), qmax) + + Q.expand_to( IntPoint() ) + self.assertEqual(IntPoint(), Q.min()) + Q.expand_by(qmax) + self.assertEqual(qmax, IntPoint()-Q.min()) + + Q.expand_by(-qmax.x, -qmax.y) + self.assertEqual(Q.max(), qmax) + + self.assertEqual( (P+Q.min()).max(), P.max() + Q.min() ) + + self.assertEqual( (P-Q.max()).min(), P.min() - Q.max() ) + + self.assertEqual( P|P, P ) + + self.assertFalse( P != P ) + + Q.set_left(qmin.x) + Q.set_top(qmin.y) + Q.set_right(qmax.x) + Q.set_bottom(qmax.y) + + + + def test_rect(self): + + P = Rect(0.298, 2, 4, 5) + + self.interval_basic(P[0], P[1]) + G = Rect(sqrt(2), sqrt(2), sqrt(3), sqrt(3)) + H = Rect.from_xywh(3.43232, 9.23214, 21.523, -0.31232) + + self.rect_basic(P, G) + self.rect_basic(G, H) + + lst = [Point(randint(-100, 100), randint(-100, 100)) for i in range(10)] + + R = Rect.from_list(lst) + + for p in lst: + self.assertTrue(R.contains(p)) + + self.assertAlmostEqual(min(lst).y, R.min().y) + self.assertAlmostEqual(max(lst).y, R.max().y) + + + + def test_optRect(self): + + P = OptRect(0.298, 2, 4, 5) + self.interval_basic(P.Rect[0], P.Rect[1]) + + + G = Rect(sqrt(2), sqrt(2), sqrt(3), sqrt(3)) + H = OptRect.from_rect(G) + + self.rect_basic(P.Rect, G) + + lst = [Point(randint(-100, 100), randint(-100, 100)) for i in range(10)] + + R = OptRect.from_list(lst) + + for p in lst: + self.assertTrue(R.Rect.contains(p)) + + self.assertAlmostEqual(min(lst).y, R.Rect.min().y) + self.assertAlmostEqual(max(lst).y, R.Rect.max().y) + + Q = OptRect() + self.assertFalse(Q) + self.assertTrue(P) + + self.assertTrue(Q.is_empty()) + self.assertFalse(P.is_empty()) + + self.assertTrue(P.contains_rect( P )) + self.assertTrue(P.contains_rect(Q)) + self.assertFalse(Q.contains_rect(P)) + self.assertFalse(P.intersects(Q)) + self.assertTrue(P.contains_rect(P.Rect)) + self.assertTrue(P.contains(P.Rect.midpoint())) + + self.assertEqual(P, OptRect.from_rect(P)) + + P.union_with(G) + P.union_with(H) + self.assertTrue(P.contains_rect(H)) + + P.intersect_with(G) + self.assertEqual(P, G) + + self.assertEqual( P|H, G ) + self.assertEqual( (P|R).Rect.min().x , min( P.Rect.min().x, R.Rect.min().x )) + + self.assertFalse(P & Q) + self.assertEqual(P, P&P) + + self.assertEqual( P & (R | H), (P & R) | (P & H) ) + + def test_intRect(self): + A = IntRect(2, 6, 9, 23) + B = IntRect.from_intervals(IntInterval(1, 5), IntInterval(8, 9)) + C = IntRect.from_points(IntPoint(1, 8), IntPoint(5, 9)) + + self.assertEqual(B, C) + + self.intrect_basic(A, B) + self.intrect_basic(B, C) + self.intrect_basic(C, A) + + def test_optIntRect(self): + P = OptIntRect(1, 2, 4, 5) + self.interval_basic(P.Rect[0], P.Rect[1]) + + + G = IntRect(2, 2, 3, 3) + H = OptIntRect.from_rect(G) + + self.intrect_basic(P.Rect, G) + + lst = [IntPoint(randint(-100, 100), randint(-100, 100)) for i in range(10)] + + R = OptIntRect.from_list(lst) + + for p in lst: + self.assertTrue(R.Rect.contains(p)) + + self.assertAlmostEqual(min(lst).y, R.Rect.min().y) + self.assertAlmostEqual(max(lst).y, R.Rect.max().y) + + Q = OptIntRect() + self.assertFalse(Q) + self.assertTrue(P) + + self.assertTrue(Q.is_empty()) + self.assertFalse(P.is_empty()) + + self.assertTrue(P.contains_rect( P )) + self.assertTrue(P.contains_rect( P.Rect )) + self.assertTrue(P.contains_rect(Q)) + self.assertFalse(Q.contains_rect(P)) + self.assertFalse(P.intersects(Q)) + self.assertTrue(P.contains_rect(P.Rect)) + self.assertTrue(P.contains(P.Rect.midpoint())) + + self.assertEqual(P, OptIntRect.from_rect(P)) + + P.union_with(G) + P.union_with(H) + self.assertTrue(P.contains_rect(H)) + + P.intersect_with(G) + self.assertEqual(P, G) + + self.assertEqual( P|H, G ) + self.assertEqual( (P|R).Rect.min().x , min( P.Rect.min().x, R.Rect.min().x )) + + self.assertFalse(P & Q) + self.assertEqual(P, P&P) + + self.assertEqual( P & (R | H), (P & R) | (P & H) ) + +unittest.main() |