def test_bezier(self): B = Bezier() C = Bezier(2) D = Bezier(2, 4) E = Bezier(1, 3, 9) F = Bezier(-2, 5, -1, 2) self.assertTrue( B.is_zero() ) self.assertTrue( C.is_constant() ) self.assertTrue( D.is_finite() ) C.clear() self.assertEqual(D.degree(), 1) self.assertEqual(E.at0(), 1) self.assertEqual(E.at1(), 9) self.assertEqual(E[2], 9) for i in range(11): t = i/10.0 self.assertAlmostEqual( D(t), lerp(t, 2, 4) ) self.assertAlmostEqual( D(t), D.value_at(t)) self.assertAlmostEqual( D.value_and_derivatives(t, 0)[0], D(t) ) self.assertAlmostEqual( D.value_and_derivatives(t, 1)[1], Bezier.derivative(D)(t) ) self.assertAlmostEqual( Bezier.integral(D).value_and_derivatives(t, 1)[1], D(t) ) #~ self.assertAlmostEqual( D.elevate_degree().reduce_degree()(t), D(t) ) self.assertAlmostEqual( (D+2)(t), D(t)+2 ) self.assertAlmostEqual( (D-1)(t), D(t)-1 ) self.assertAlmostEqual( (D*2)(t), D(t)*2 ) self.assertAlmostEqual( (D/4)(t), D(t)/4 ) self.assertTrue( Bezier.bounds_fast(F).Interval.contains(F(t)) ) self.assertTrue( Bezier.bounds_exact(F).Interval.contains(F(t)) ) self.assertTrue( Bezier.bounds_local(F, OptInterval(t-0.05, t+0.05)).Interval.contains(F(t)) ) for r in F.roots(): self.assertAlmostEqual(F(r), 0) #TODO: bug in 2geom? #~ for r in F.roots(Interval(0.1, 0.8)): #~ self.assertAlmostEqual(F(r), 0) #~ self.assertTrue( 0.1 <= r <= 0.8 ) self.assertIsInstance(F.forward_difference(1), Bezier) self.assertIsInstance(F.elevate_degree(), Bezier) self.assertIsInstance(E.reduce_degree(), Bezier) #F.reduce_degree() fails with # *** glibc detected *** python2: malloc(): memory corruption: self.assertIsInstance(F.elevate_to_degree(4), Bezier) self.assertIsInstance(F.deflate(), Bezier) S = F.to_SBasis() self.assertIsInstance(S, SBasis) for i in range(11): t = i/10.0 self.assertAlmostEqual(S(t), F(t))
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_sBasis(self): S = SBasis() T = SBasis(2) U = SBasis(1, 7) V = SBasis.from_linear( Linear(2, 8) ) self.assertEqual(V[0], Linear(2, 8)) self.assertEqual(V.back(), Linear(2, 8)) #~ self.assertTrue(S.empty()) self.assertFalse(T.empty()) T.pop_back() self.assertTrue(T.empty()) self.assertEqual(S.size(), 0) self.assertEqual(U.size(), 1) self.assertEqual((U*V).size(), 2) T.resize(1, Linear(2, 3)) self.assertEqual(T[0], Linear(2, 3)) T.clear() self.assertTrue(T.empty()) #TODO #~ T.reserve(5) #~ print T.size() self.assertEqual(V.at(0), V[0]) self.assertEqual(V, U+1) self.assertNotEqual(V, U) self.assertTrue(T.is_zero()) self.assertTrue(SBasis(1).is_constant()) def f(A, B): return (-A)*(A+B*2.2)*(A*B-B*B/3) W = f(U, V) self.assertAlmostEqual(W(0), W.at0()) self.assertAlmostEqual(W(1), W.at1()) for i in range(11): t = i/10.0 self.assertAlmostEqual(W(t), W.value_at(t)) self.assertAlmostEqual(W(t), f(U(t), V(t))) vd_UV = (U*V).value_and_derivatives(t, 1) vd_U = U.value_and_derivatives(t, 1) vd_V = V.value_and_derivatives(t, 1) self.assertAlmostEqual( vd_UV[1], vd_U[1]*V(t)+U(t)*vd_V[1] ) self.assertAlmostEqual( U(V)(t), U(V(t)) ) self.assertEqual(T.degrees_of_freedom(), 0) self.assertEqual(U.degrees_of_freedom(), 2) self.assertEqual(T, T.to_SBasis()) U2 = SBasis(U(0), U(1)) U2.resize(10) self.assertNotEqual(U2, U) U2.truncate(U.size()) self.assertEqual(U2, U) #TODO: normalize() sL = Linear.sin(Linear(0, 1), 3) cL = Linear.cos(Linear(0, 1), 3) sqrtU = SBasis.sqrt( U, 3 ) rL = Linear.reciprocal(Linear(1,2), 3) # cy2geom.inverse seems to return nans for degrees > 1 #~ asin = cy2geom.inverse( cy2geom.sqrt( SBasis(Linear(0, 1)), 3 ), 1) for i in range(11): t = i/10.0 self.assertAlmostEqual(sL(t), math.sin(t)) self.assertAlmostEqual(cL(t), math.cos(t)) #cy2geom.sqrt is not that precise self.assertAlmostEqual(sqrtU(t), math.sqrt(U(t)), places = 1) self.assertAlmostEqual(rL(t), 1/(1+t), places = 1 ) #~ self.assertAlmostEqual( asin(t), math.asin(t) ) self.assertAlmostEqual( SBasis.compose(U, V)(t), U(V)(t) ) self.assertAlmostEqual( SBasis.divide(U, V, 3)(t), U(t)/V(t), places = 1) self.assertAlmostEqual( SBasis.derivative(SBasis.integral(W))(t), W(t)) self.assertAlmostEqual( cy2geom.reverse(W)(t), W(1-t) ) self.assertAlmostEqual( SBasis.multiply(U, V)(t), (U*V)(t)) #TODO looks like bug in 2geom #~ print cy2geom.multiply_add(U, V, W)(t), (U*V+W)(t) self.assertAlmostEqual( SBasis.multiply_add(U, W, V)(t), (U*W+V)(t)) self.assertTrue( SBasis.bounds_exact(U).Interval.contains(U(t)) ) self.assertTrue( SBasis.bounds_fast(U).Interval.contains(U(t)) ) self.assertTrue( SBasis.bounds_local(U, OptInterval(t-0.05, t+0.05)).Interval.contains(U(t)) ) for r in SBasis.roots(W): self.assertAlmostEqual(W(r), 0) for r in SBasis.roots(W, Interval(0, 0.7)): self.assertAlmostEqual(W(r), 0) self.assertTrue(Interval(0, 0.7).contains(r)) levels = [0, 3, 22, -21] for i, roots in enumerate( SBasis.multi_roots(W, levels) ): level = levels[i] for r in roots: self.assertAlmostEqual(W(r), level) self.assertEqual(SBasis.valuation(W), 0) #TODO: why is this still 0? #~ print cy2geom.valuation(cy2geom.shift(W, 6)) self.assertEqual( U[0], SBasis.shift(U, 2)[2] ) for I in SBasis.level_set(W, 2, tol = 1e-7): self.assertAlmostEqual( W(I.mid()), 2 ) for I in SBasis.level_set(W, Interval(0, 1), tol = 1e-7, vtol = 1e-7): self.assertTrue( 0 <= W(I.begin()) <= 1 ) self.assertTrue( 0 <= W(I.mid()) <= 1 ) self.assertTrue( 0 <= W(I.end()) <= 1 )
def curve(self, C): self.assertAlmostEqual(C.initial_point(), C(0)) self.assertAlmostEqual(C.final_point(), C.point_at(1)) #Doesn't have to be true #~ if C.length() > 0.01: #~ self.assertFalse(C.is_degenerate()) if C.is_degenerate(): #trivial special case return for i in range(11): t = i/10.0 self.assertAlmostEqual(C(t).x, C.point_at(t).x) self.assertAlmostEqual(C(t).y, C.value_at(t, 1)) self.assertEqual( C(t), C.point_and_derivatives(t, 1)[0] ) self.assertTrue( C.bounds_exact().contains(C(t)) ) self.assertTrue( C.bounds_fast().contains(C(t)) ) #TODO why this works only with degree = 0? if C.bounds_local(OptInterval(t-0.05, t+0.05), 0 ) and ( C.bounds_local(OptInterval(t-0.05, t+0.05), 0).Rect.area() > 1e-10): #ruling out too small rectangles, they have problems with precision self.assertTrue( C.bounds_local( OptInterval(t-0.05, t+0.05), 0 ).Rect.contains(C(t))) D = C.duplicate() D.set_initial(Point()) self.assertAlmostEqual(D.initial_point(), Point()) D.set_final(Point(1, 1)) self.assertAlmostEqual(D.final_point(), Point(1, 1)) A = Affine( uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10)) E = C.transformed(A) for i in range(11): t = i/10.0 # self.assertAlmostEqual( E(t), C(t)*A ) G1 = C.portion(0.2, 0.8) G2 = C.portion( interval=Interval(2, 8)/10 ) self.assertAlmostEqual( G1(0), C(0.2) ) self.assertAlmostEqual( G2(0.5), C( lerp(0.5, 0.2, 0.8) )) self.assertAlmostEqual( G1(1), G2(1) ) for i in range(11): t = i/10.0 self.assertAlmostEqual( C.reverse()(t), C(1-t) ) self.assertAlmostEqual( C.point_and_derivatives(0.3, 1)[1], C.derivative()(0.3) ) self.assertAlmostEqual( C.nearest_time(C(0)), 0 ) self.assertAlmostEqual( C( C.nearest_time(C(0.5), interval=Interval(0.2, 0.5)) ), C(0.5) ) self.assertAlmostEqual( C( C.nearest_time(C(0.5), 0.2, 0.5) ), C(0.5) ) for p in C.all_nearest_times( C(0), 0, 1): self.assertEqual(C(p), C(0)) for p in C.all_nearest_times( C(1), interval=Interval(0, 1)): self.assertEqual(C(p), C(1)) for r in C.roots(0, 0): self.assertAlmostEqual(C.value_at(r, 0), 0) self.assertGreaterEqual(C.length(), abs(C(1) - C(0))) self.assertEqual(C.winding(Point()), int(C.winding(Point())) ) self.assertAlmostEqual( C.unit_tangent_at(0.5), Point.unit_vector(C.derivative()(0.5)) ) self.assertTrue(isinstance(C.to_SBasis()[0], SBasis))