File indexing completed on 2025-04-27 04:01:22

0001 import math
0002 from .. import base
0003 from lottie.utils.transform import TransformMatrix, NVector
0004 
0005 
0006 class TestTransform(base.TestCase):
0007     def test_properties_get(self):
0008         m = TransformMatrix()
0009         m._mat = [
0010              0,  1,  2,  3,
0011              4,  5,  6,  7,
0012              8,  9, 10, 11,
0013             12, 13, 14, 15
0014         ]
0015 
0016         self.assertEqual(m.a, 0)
0017         self.assertEqual(m.b, 1)
0018         self.assertEqual(m.c, 4)
0019         self.assertEqual(m.d, 5)
0020         self.assertEqual(m.tx, 12)
0021         self.assertEqual(m.ty, 13)
0022 
0023     def test_properties_set(self):
0024         m = TransformMatrix()
0025         m.a = 1
0026         m.b = 2
0027         m.c = 3
0028         m.d = 4
0029         m.tx = 5
0030         m.ty = 6
0031 
0032         self.assertEqual(m._mat, list(map(float, [
0033             1, 2, 0, 0,
0034             3, 4, 0, 0,
0035             0, 0, 1, 0,
0036             5, 6, 0, 1,
0037         ])))
0038 
0039     def test_init(self):
0040         self.assertEqual(TransformMatrix()._mat, [
0041             1, 0, 0, 0,
0042             0, 1, 0, 0,
0043             0, 0, 1, 0,
0044             0, 0, 0, 1,
0045         ])
0046 
0047     def test_getitem(self):
0048         m = TransformMatrix()
0049         m._mat = [
0050              0,  1,  2,  3,
0051              4,  5,  6,  7,
0052              8,  9, 10, 11,
0053             12, 13, 14, 15
0054         ]
0055 
0056         self.assertEqual(m[0, 0], 0)
0057         self.assertEqual(m[0, 1], 1)
0058         self.assertEqual(m[0, 2], 2)
0059         self.assertEqual(m[0, 3], 3)
0060         self.assertEqual(m[1, 0], 4)
0061         self.assertEqual(m[1, 1], 5)
0062         self.assertEqual(m[1, 2], 6)
0063         self.assertEqual(m[1, 3], 7)
0064         self.assertEqual(m[2, 0], 8)
0065         self.assertEqual(m[2, 1], 9)
0066         self.assertEqual(m[2, 2], 10)
0067         self.assertEqual(m[2, 3], 11)
0068         self.assertEqual(m[3, 0], 12)
0069         self.assertEqual(m[3, 1], 13)
0070         self.assertEqual(m[3, 2], 14)
0071         self.assertEqual(m[3, 3], 15)
0072 
0073     def test_setitem(self):
0074         m = TransformMatrix()
0075 
0076         m[0, 0] = 0
0077         m[0, 1] = 1
0078         m[0, 2] = 2
0079         m[0, 3] = 3
0080         m[1, 0] = 4
0081         m[1, 1] = 5
0082         m[1, 2] = 6
0083         m[1, 3] = 7
0084         m[2, 0] = 8
0085         m[2, 1] = 9
0086         m[2, 2] = 10
0087         m[2, 3] = 11
0088         m[3, 0] = 12
0089         m[3, 1] = 13
0090         m[3, 2] = 14
0091         m[3, 3] = 15
0092 
0093         self.assertEqual(m._mat, [
0094              0,  1,  2,  3,
0095              4,  5,  6,  7,
0096              8,  9, 10, 11,
0097             12, 13, 14, 15
0098         ])
0099 
0100     def test_clone(self):
0101         m = TransformMatrix()
0102         m._mat = [
0103              0,  1,  2,  3,
0104              4,  5,  6,  7,
0105              8,  9, 10, 11,
0106             12, 13, 14, 15
0107         ]
0108 
0109         m1 = m.clone()
0110         self.assertEqual(m1._mat, m._mat)
0111         self.assertIsNot(m1._mat, m._mat)
0112 
0113     def test_scale(self):
0114         m = TransformMatrix()
0115         self.assertIs(m.scale(2), m)
0116         self.assertEqual(m._mat, [
0117             2, 0, 0, 0,
0118             0, 2, 0, 0,
0119             0, 0, 1, 0,
0120             0, 0, 0, 1,
0121         ])
0122         self.assertIs(m.scale(3, 4), m)
0123         self.assertEqual(m._mat, [
0124             6, 0, 0, 0,
0125             0, 8, 0, 0,
0126             0, 0, 1, 0,
0127             0, 0, 0, 1,
0128         ])
0129 
0130     def test_translate(self):
0131         m = TransformMatrix()
0132         self.assertIs(m.translate(2, 3), m)
0133         self.assertEqual(m._mat, [
0134             1, 0, 0, 0,
0135             0, 1, 0, 0,
0136             0, 0, 1, 0,
0137             2, 3, 0, 1,
0138         ])
0139         self.assertEqual(m.tx, 2)
0140         self.assertEqual(m.ty, 3)
0141 
0142     def asssert_matrix_almost_equal(self, m, comps):
0143         for i in range(9):
0144             self.assertAlmostEqual(m._mat[i], comps[i], msg="%s\n%s" % (m, comps))
0145 
0146     def test_skew(self):
0147         m = TransformMatrix()
0148         self.assertIs(m.skew(math.pi / 4, math.pi*(2-1/4)), m)
0149         self.asssert_matrix_almost_equal(m, [
0150             1,-1, 0, 0,
0151             1, 1, 0, 0,
0152             0, 0, 1, 0,
0153             0, 0, 0, 1,
0154         ])
0155         self.assertAlmostEqual(m.c, 1)
0156         self.assertAlmostEqual(m.b, -1)
0157 
0158     def test_row_col(self):
0159         m = TransformMatrix()
0160         m._mat = [
0161              0,  1,  2,  3,
0162              4,  5,  6,  7,
0163              8,  9, 10, 11,
0164             12, 13, 14, 15
0165         ]
0166         self.assertEqual(m.row(0), NVector(0, 1, 2, 3))
0167         self.assertEqual(m.row(1), NVector(4, 5, 6, 7))
0168         self.assertEqual(m.row(2), NVector(8, 9, 10, 11))
0169         self.assertEqual(m.row(3), NVector(12, 13, 14, 15))
0170 
0171         self.assertEqual(m.column(0), NVector(0, 4, 8, 12))
0172         self.assertEqual(m.column(1), NVector(1, 5, 9, 13))
0173         self.assertEqual(m.column(2), NVector(2, 6, 10, 14))
0174         self.assertEqual(m.column(3), NVector(3, 7, 11, 15))
0175 
0176     def test_to_identity(self):
0177         m = TransformMatrix()
0178         m._mat = [
0179              0,  1,  2,  3,
0180              4,  5,  6,  7,
0181              8,  9, 10, 11,
0182             12, 13, 14, 15
0183         ]
0184         m.to_identity()
0185         self.assertEqual(m._mat, [
0186             1, 0, 0, 0,
0187             0, 1, 0, 0,
0188             0, 0, 1, 0,
0189             0, 0, 0, 1,
0190         ])
0191 
0192     def test_apply(self):
0193         m = TransformMatrix()
0194         v = NVector(1, 2)
0195         self.assertEqual(m.apply(v), v)
0196         m.scale(2, 4)
0197         self.assertEqual(m.apply(v), NVector(2, 8))
0198         m.translate(-1, -3)
0199         self.assertEqual(m.apply(v), NVector(1, 5))
0200         m.rotate(-math.pi/2)
0201         self.assert_nvector_equal(m.apply(v), NVector(-5, 1))
0202 
0203     def test_rotation(self):
0204         m = TransformMatrix.rotation(math.pi/2)
0205         self.asssert_matrix_almost_equal(m, [
0206             0, -1, 0, 0,
0207             1, 0, 0, 0,
0208             0, 0, 1, 0,
0209             0, 0, 0, 1,
0210         ])
0211 
0212     def test_mul(self):
0213         m1 = TransformMatrix()
0214         m1._mat = [
0215             2, 3, 4, 0,
0216             5, 6, 7, 0,
0217             8, 9, 10, 0,
0218             0, 0, 0, 1,
0219         ]
0220         m2 = TransformMatrix()
0221         m2._mat = [
0222             .1, .2, .3, 0,
0223             .4, .5, .6, 0,
0224             .7, .8, .9, 0,
0225              0,  0,  0, 1,
0226         ]
0227         self.asssert_matrix_almost_equal(m1 * m2, [
0228              4.2,  5.1,  6.0, 0,
0229              7.8,  9.6, 11.4, 0,
0230             11.4, 14.1, 16.8, 0,
0231                0,    0,    0, 1,
0232         ])
0233 
0234     def test_imul(self):
0235         m1 = TransformMatrix()
0236         m1._mat = [
0237             2, 3, 4, 0,
0238             5, 6, 7, 0,
0239             8, 9, 10, 0,
0240             0, 0, 0, 1,
0241         ]
0242         m2 = TransformMatrix()
0243         m2._mat = [
0244             .1, .2, .3, 0,
0245             .4, .5, .6, 0,
0246             .7, .8, .9, 0,
0247              0,  0,  0, 1,
0248         ]
0249         m1 *= m2
0250         self.asssert_matrix_almost_equal(m1, [
0251              4.2,  5.1,  6.0, 0,
0252              7.8,  9.6, 11.4, 0,
0253             11.4, 14.1, 16.8, 0,
0254                0,    0,    0, 1,
0255         ])
0256 
0257     def test_rotate(self):
0258         m = TransformMatrix()
0259         m.scale(2)
0260         m.rotate(math.pi / 3)
0261         self.asssert_matrix_almost_equal(m, [
0262              2 * math.cos(math.pi/3),  2 * -math.sin(math.pi/3),  0, 0,
0263              2 * math.sin(math.pi/3),  2 * math.cos(math.pi/3), 0, 0,
0264              0, 0, 1, 0,
0265              0, 0, 0, 1,
0266         ])
0267 
0268     def test_extract_transform_id(self):
0269         m = TransformMatrix()
0270         tr = m.extract_transform()
0271         self.assert_nvector_equal(tr["translation"], NVector(0, 0))
0272         self.assert_nvector_equal(tr["scale"], NVector(1, 1))
0273         self.assertAlmostEqual(tr["angle"], 0)
0274         self.assertAlmostEqual(tr["skew_axis"], 0)
0275         self.assertAlmostEqual(tr["skew_angle"], 0)
0276 
0277     def test_extract_transform_trans(self):
0278         m = TransformMatrix()
0279         m.translate(10, 23)
0280         tr = m.extract_transform()
0281         self.assert_nvector_equal(tr["translation"], NVector(10, 23))
0282         self.assert_nvector_equal(tr["scale"], NVector(1, 1))
0283         self.assertAlmostEqual(tr["angle"], 0)
0284         self.assertAlmostEqual(tr["skew_axis"], 0)
0285         self.assertAlmostEqual(tr["skew_angle"], 0)
0286 
0287     def test_extract_transform_scale(self):
0288         m = TransformMatrix()
0289         m.scale(2, 3)
0290         tr = m.extract_transform()
0291         self.assert_nvector_equal(tr["translation"], NVector(0, 0))
0292         self.assert_nvector_equal(tr["scale"], NVector(2, 3))
0293         self.assertAlmostEqual(tr["angle"], 0)
0294         self.assertAlmostEqual(tr["skew_axis"], 0)
0295         self.assertAlmostEqual(tr["skew_angle"], 0)
0296 
0297     def test_extract_transform_rotate(self):
0298         m = TransformMatrix()
0299         m.rotate(math.pi / 6)
0300         tr = m.extract_transform()
0301         self.assert_nvector_equal(tr["translation"], NVector(0, 0))
0302         self.assert_nvector_equal(tr["scale"], NVector(1, 1))
0303         self.assertAlmostEqual(tr["angle"], math.pi / 6)
0304         self.assertAlmostEqual(tr["skew_axis"], 0)
0305         self.assertAlmostEqual(tr["skew_angle"], 0)
0306 
0307     def test_extract_transform_skew_x(self):
0308         m = TransformMatrix()
0309         m.skew(math.pi/3, 0)
0310         tr = m.extract_transform()
0311         self.assert_nvector_equal(tr["translation"], NVector(0, 0))
0312         self.assert_nvector_equal(tr["scale"], NVector(1, 1))
0313         self.assertAlmostEqual(tr["angle"], 0)
0314         self.assertAlmostEqual(tr["skew_axis"], 0)
0315         self.assertAlmostEqual(tr["skew_angle"], math.pi/3)
0316 
0317     def test_extract_transform_complex(self):
0318         m = TransformMatrix()
0319         m.scale(2, 3)
0320         #m.skew(math.pi/3, 0)
0321         m.rotate(math.pi / 6)
0322         m.translate(10, 23)
0323         self.asssert_matrix_almost_equal(m, (
0324             TransformMatrix().scale(2, 3) *
0325             #TransformMatrix().skew(math.pi/3, 0) *
0326             TransformMatrix.rotation(math.pi/6) *
0327             TransformMatrix().translate(10, 23)
0328         )._mat)
0329         tr = m.extract_transform()
0330         self.assert_nvector_equal(tr["translation"], NVector(10, 23))
0331         self.assert_nvector_equal(tr["scale"], NVector(2, 3))
0332         self.assertAlmostEqual(tr["angle"], math.pi / 6)
0333         #self.assertAlmostEqual(tr["skew_axis"], 0)
0334         #self.assertAlmostEqual(tr["skew_angle"], math.pi/3)