affinematrix.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: tests/graphics/affinetransform.cpp
  3. // Purpose: Unit test for transformations implemented for wxAffineMatrix2D
  4. // Author: Catalin Raceanu
  5. // Created: 2011-04-14
  6. // Copyright: (c) 2011 wxWidgets development team
  7. ///////////////////////////////////////////////////////////////////////////////
  8. // ----------------------------------------------------------------------------
  9. // headers
  10. // ----------------------------------------------------------------------------
  11. #include "testprec.h"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #include "wx/graphics.h"
  16. #include "wx/dcmemory.h"
  17. #include "wx/affinematrix2d.h"
  18. #include "wx/math.h"
  19. #include "testimage.h"
  20. // ----------------------------------------------------------------------------
  21. // test class
  22. // ----------------------------------------------------------------------------
  23. class AffineTransformTestCase : public CppUnit::TestCase
  24. {
  25. public:
  26. AffineTransformTestCase()
  27. {
  28. wxImage::AddHandler(new wxJPEGHandler);
  29. }
  30. virtual void setUp();
  31. private:
  32. CPPUNIT_TEST_SUITE( AffineTransformTestCase );
  33. CPPUNIT_TEST( InvertMatrix );
  34. #if wxUSE_DC_TRANSFORM_MATRIX
  35. CPPUNIT_TEST( VMirrorAndTranslate );
  36. CPPUNIT_TEST( Rotate90Clockwise );
  37. #if wxUSE_GRAPHICS_CONTEXT
  38. CPPUNIT_TEST( CompareToGraphicsContext );
  39. #endif // wxUSE_GRAPHICS_CONTEXT
  40. #endif // wxUSE_DC_TRANSFORM_MATRIX
  41. CPPUNIT_TEST_SUITE_END();
  42. void InvertMatrix();
  43. #if wxUSE_DC_TRANSFORM_MATRIX
  44. void VMirrorAndTranslate();
  45. void Rotate90Clockwise();
  46. #if wxUSE_GRAPHICS_CONTEXT
  47. void CompareToGraphicsContext();
  48. #endif // wxUSE_GRAPHICS_CONTEXT
  49. wxImage m_imgOrig;
  50. wxBitmap m_bmpOrig;
  51. #endif // wxUSE_DC_TRANSFORM_MATRIX
  52. DECLARE_NO_COPY_CLASS(AffineTransformTestCase)
  53. };
  54. // register in the unnamed registry so that these tests are run by default
  55. CPPUNIT_TEST_SUITE_REGISTRATION( AffineTransformTestCase );
  56. // also include in its own registry so that these tests can be run alone
  57. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AffineTransformTestCase, "AffineTransformTestCase" );
  58. void AffineTransformTestCase::setUp()
  59. {
  60. #if wxUSE_DC_TRANSFORM_MATRIX
  61. m_imgOrig.LoadFile("horse.jpg");
  62. CPPUNIT_ASSERT( m_imgOrig.IsOk() );
  63. m_bmpOrig = wxBitmap(m_imgOrig);
  64. #endif // wxUSE_DC_TRANSFORM_MATRIX
  65. }
  66. void AffineTransformTestCase::InvertMatrix()
  67. {
  68. wxAffineMatrix2D matrix1;
  69. matrix1.Set(wxMatrix2D(2, 1, 1, 1), wxPoint2DDouble(1, 1));
  70. wxAffineMatrix2D matrix2(matrix1);
  71. matrix2.Invert();
  72. wxMatrix2D m;
  73. wxPoint2DDouble p;
  74. matrix2.Get(&m, &p);
  75. CPPUNIT_ASSERT_EQUAL( 1, (int)m.m_11 );
  76. CPPUNIT_ASSERT_EQUAL( -1, (int)m.m_12 );
  77. CPPUNIT_ASSERT_EQUAL( -1, (int)m.m_21 );
  78. CPPUNIT_ASSERT_EQUAL( 2, (int)m.m_22 );
  79. CPPUNIT_ASSERT_EQUAL( 0, (int)p.m_x );
  80. CPPUNIT_ASSERT_EQUAL( -1, (int)p.m_y );
  81. matrix2.Concat(matrix1);
  82. CPPUNIT_ASSERT( matrix2.IsIdentity() );
  83. }
  84. #if wxUSE_DC_TRANSFORM_MATRIX
  85. void AffineTransformTestCase::VMirrorAndTranslate()
  86. {
  87. wxBitmap bmpUsingMatrix(m_bmpOrig.GetWidth(), m_bmpOrig.GetHeight());
  88. // build the mirrored image using the transformation matrix
  89. {
  90. wxMemoryDC dc(bmpUsingMatrix);
  91. if ( !dc.CanUseTransformMatrix() )
  92. return;
  93. wxAffineMatrix2D matrix;
  94. matrix.Mirror(wxVERTICAL);
  95. matrix.Translate(0, -m_bmpOrig.GetHeight() + 1);
  96. dc.SetTransformMatrix(matrix);
  97. dc.DrawBitmap(m_bmpOrig, 0, 0);
  98. }
  99. CPPUNIT_ASSERT_EQUAL( bmpUsingMatrix.ConvertToImage(),
  100. m_imgOrig.Mirror(false) );
  101. }
  102. void AffineTransformTestCase::Rotate90Clockwise()
  103. {
  104. wxBitmap bmpUsingMatrix(m_bmpOrig.GetHeight(), m_bmpOrig.GetWidth());
  105. // build the rotated image using the transformation matrix
  106. {
  107. wxMemoryDC dc(bmpUsingMatrix);
  108. if ( !dc.CanUseTransformMatrix() )
  109. return;
  110. wxAffineMatrix2D matrix;
  111. matrix.Rotate(0.5 * M_PI);
  112. matrix.Translate(0, -m_bmpOrig.GetHeight());
  113. dc.SetTransformMatrix(matrix);
  114. dc.DrawBitmap(m_bmpOrig, 0, 0);
  115. }
  116. CPPUNIT_ASSERT_EQUAL( bmpUsingMatrix.ConvertToImage(),
  117. m_imgOrig.Rotate90(true) );
  118. }
  119. #if wxUSE_GRAPHICS_CONTEXT
  120. void AffineTransformTestCase::CompareToGraphicsContext()
  121. {
  122. wxPoint2DDouble pointA1(1.0, 3.0), pointA2(60.0, 50.0),
  123. pointG1(1.0, 3.0), pointG2(60.0, 50.0);
  124. // Create affine matrix and transform it
  125. wxAffineMatrix2D matrixA1, matrixA2;
  126. matrixA2.Rotate(M_PI / 3);
  127. matrixA1.Translate(-m_bmpOrig.GetWidth()/2, -m_bmpOrig.GetHeight()/2);
  128. matrixA1.Rotate(-M_PI *2/ 6);
  129. matrixA1.Translate(m_bmpOrig.GetWidth()/2, m_bmpOrig.GetHeight()/2);
  130. matrixA1.Mirror(wxHORIZONTAL);
  131. matrixA1.Concat(matrixA2);
  132. matrixA1.Mirror(wxVERTICAL);
  133. matrixA1.Translate(m_bmpOrig.GetWidth()/2, -m_bmpOrig.GetHeight()/2);
  134. matrixA1.Scale(0.9, 0.9);
  135. matrixA1.Invert();
  136. // Create image using first matrix
  137. wxBitmap bmpUsingMatrixA1(m_bmpOrig.GetHeight(), m_bmpOrig.GetWidth());
  138. // Build the transformed image using the transformation matrix
  139. {
  140. wxMemoryDC dc(bmpUsingMatrixA1);
  141. if ( !dc.CanUseTransformMatrix() )
  142. return;
  143. // Draw the bitmap
  144. dc.SetTransformMatrix(matrixA1);
  145. dc.DrawBitmap(m_bmpOrig, 0, 0);
  146. // Draw a line
  147. matrixA1.TransformPoint(&pointA1.m_x, &pointA1.m_y);
  148. matrixA1.TransformDistance(&pointA2.m_x, &pointA2.m_y);
  149. dc.DrawLine(wxRound(pointA1.m_x), wxRound(pointA1.m_y),
  150. wxRound(pointA1.m_x + pointA2.m_x), wxRound(pointA1.m_x + pointA2.m_y));
  151. }
  152. // Create graphics matrix and transform it
  153. wxMemoryDC mDc;
  154. wxGraphicsContext* gDc = wxGraphicsContext::Create(mDc);
  155. wxGraphicsMatrix matrixG1 = gDc->CreateMatrix();
  156. wxGraphicsMatrix matrixG2 = gDc->CreateMatrix();
  157. matrixG2.Rotate(M_PI / 3);
  158. matrixG1.Translate(-m_bmpOrig.GetWidth()/2, -m_bmpOrig.GetHeight()/2);
  159. matrixG1.Rotate(-M_PI*2 / 6);
  160. matrixG1.Translate(m_bmpOrig.GetWidth()/2, m_bmpOrig.GetHeight()/2);
  161. matrixG1.Scale(-1, 1);
  162. matrixG1.Concat(matrixG2);
  163. matrixG1.Scale(1, -1);
  164. matrixG1.Translate(m_bmpOrig.GetWidth()/2, -m_bmpOrig.GetHeight()/2);
  165. matrixG1.Scale(0.9, 0.9);
  166. matrixG1.Invert();
  167. // Create affine matrix from the graphics matrix
  168. wxMatrix2D mat2D;
  169. wxPoint2DDouble tr;
  170. matrixG1.Get(&mat2D.m_11, &mat2D.m_12, &mat2D.m_21, &mat2D.m_22, &tr.m_x, &tr.m_y);
  171. wxAffineMatrix2D matrixAG;
  172. matrixAG.Set(mat2D, tr);
  173. delete gDc;
  174. // Create image using last matrix
  175. wxBitmap bmpUsingMatrixAG(m_bmpOrig.GetHeight(), m_bmpOrig.GetWidth());
  176. // Build the transformed image using the transformation matrix
  177. {
  178. wxMemoryDC dc(bmpUsingMatrixAG);
  179. if ( !dc.CanUseTransformMatrix() )
  180. return;
  181. // Draw the bitmap
  182. dc.SetTransformMatrix(matrixAG);
  183. dc.DrawBitmap(m_bmpOrig, 0, 0);
  184. // Draw a line
  185. matrixG1.TransformPoint(&pointG1.m_x, &pointG1.m_y);
  186. matrixG1.TransformDistance(&pointG2.m_x, &pointG2.m_y);
  187. dc.DrawLine(wxRound(pointG1.m_x), wxRound(pointG1.m_y),
  188. wxRound(pointG1.m_x + pointG2.m_x), wxRound(pointG1.m_x + pointG2.m_y));
  189. }
  190. CPPUNIT_ASSERT_EQUAL( bmpUsingMatrixA1.ConvertToImage(),
  191. bmpUsingMatrixAG.ConvertToImage() );
  192. // Save the images to check that something _is_ inside the visible area.
  193. //bmpUsingMatrixA1.SaveFile("matrixA1.jpg", wxBITMAP_TYPE_JPEG);
  194. //bmpUsingMatrixAG.SaveFile("matrixAG.jpg", wxBITMAP_TYPE_JPEG);
  195. }
  196. #endif // wxUSE_GRAPHICS_CONTEXT
  197. #endif // wxUSE_DC_TRANSFORM_MATRIX